# Loosing lives really fast when Collision happens

**URL:** https://discourse.processing.org/t/loosing-lives-really-fast-when-collision-happens/8627
**Category:** Coding Questions
**Created:** [February 22, 2019, 11:37am UTC](https://discourse.processing.org/t/loosing-lives-really-fast-when-collision-happens/8627 "2019-02-22T11:37:05Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![vinipineschi](https://avatars.discourse-cdn.com/v4/letter/v/b2d939/32.png) [@vinipineschi](https://discourse.processing.org/u/vinipineschi)
#### Post date: [February 22, 2019, 11:37am UTC](https://discourse.processing.org/t/loosing-lives-really-fast-when-collision-happens/8627/1 "2019-02-22T11:37:05Z")

</div>

Hi,  
I was trying to create a simple collision code for my Asteroid game. Basically I managed to create the collision between the objects (Spaceship and Asteroid), however when I created this if condition bellow:

if (xpos + asteroidWidth + vx \> shiptrek.location.x &&  
xpos + vx \< shiptrek.location.x + shipWidth &&  
ypos + asteroidHeight \> shiptrek.location.y &&  
ypos \< shiptrek.location.y + shipHeight) {

```
 live = live - 1;
 }

```

}

What is happening is that I am loosing -10 lives, I guess it is because of the timing of collision exposure. How could I set this to make the game code understand that every time collision happens the user just loose 1 live?

---

<div class="post-metadata">

### Author: ![hotfooted](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hotfooted/32/3670_2.png) [@hotfooted](https://discourse.processing.org/u/hotfooted)
#### Post date: [February 22, 2019, 11:39am UTC](https://discourse.processing.org/t/loosing-lives-really-fast-when-collision-happens/8627/2 "2019-02-22T11:39:41Z")

</div>

if you aren’t removing the asteroid it probably just catching the collision multiple times? it’s hard to say without seeing the code.

---

<div class="post-metadata">

### Author: ![vinipineschi](https://avatars.discourse-cdn.com/v4/letter/v/b2d939/32.png) [@vinipineschi](https://discourse.processing.org/u/vinipineschi)
#### Post date: [February 22, 2019, 11:54am UTC](https://discourse.processing.org/t/loosing-lives-really-fast-when-collision-happens/8627/3 "2019-02-22T11:54:43Z")

</div>

```auto
[quote="hotfooted, post:2, topic:8627, full:true"]
if you aren't removing the asteroid it probably just catching the collision multiple times? it's hard to say without seeing the code.
[/quote]

```

Hi friend,

Hmm, I don´t want to remove the asteroid, basically the idea is: Having a spaceship inside the frame that have to fly around the frame without shocking with the asteroid. If the user could keep flying between shocking in 30s he moves on to the next level.

I will try to put the code here but will be a little bit large:

```auto

//THIS IS MY FRAME MODE.

//Loading font
PFont font;

//game levels
int mode; //1: intro, 2: level01, 3:level02, 4: level3, 5:gameover

//asteriodes movements
int xpos, ypos, vx, vy;

//Game features
int score;
int live;

//spaceship elements
PImage ship;
PImage ship2;
int shipsize = 100;
spaceship shiptrek;

//movement of the ship
boolean up = false;
boolean down = false;
boolean left = false;
boolean right = false;
//gif generator
PImage[] gif;
int currentPic = 0;

//Timer for the levels.
long timer = 0;
long TIMEOUT = 30000;
int time = 0;

//Asteroids
PImage asteroid;

//mouse hover for intro button:
float rectX;
float rectY;
float rectWidth;
float rectHeight;

//collision:

boolean collision = false;
float asteroidWidth = 100;
float asteroidHeight = 100;
float shipWidth = 50;
float shipHeight = 70;

void setup() {
 timer = millis();
 size(600,600);
 frameRate(40);
 mode = 1;
 xpos = 100;
 ypos = 300;
 vx = 2;
 vy = 5;
 asteroid = loadImage("asteroid.png");
 ship = loadImage("ship2.png");
 gif = new PImage[21];
 int index = 0;
 while (index < 21) {
   gif[index] = loadImage("starsfinal_" + index + ".jpg"); 
   index = index + 1;
 }
 
 //ship.resize(50,90);
 shiptrek = new spaceship();
 imageMode(CENTER);
 
 //mouse hover intro:
  rectX = 168;
  rectY = 280;
  rectWidth = 270;
  rectHeight = 128;
 

}

void draw() {
  if (mode == 1) {
    intro();
    
  } else if(mode == 2) {
    level01();
    
  } else if(mode == 3) {
    level02();
    
  } else if(mode == 4) {
    level03();
    
   } else if(mode == 5){
     gameOver();
     
   } else {
 background(25, 25, 25);
   
   }
  
}

//THIS IS THE SPACESHIP

class spaceship {
  //1. Instance variables
  int lives;
  PVector location;
  PVector velocity;
  PVector direction;
  PVector stop;
  
  //2. Constructor - same name as the class. No void (return type)
  spaceship() {
    lives = 3;
    location = new PVector(300, 300);
    direction = new PVector(0, -0.05);
    velocity = new PVector(0, 0.2);
    stop = new PVector(0,0);
     
  }
  
  //3. Behaviour functions
  
  void show() {
    pushMatrix();
    translate(location.x, location.y);
    rotate(direction.heading());
    rotate(1.55);
    fill(255, 0, 255, 100);
    rect(0, 0, shipWidth, shipHeight);
    image(ship, 0, 0);
    popMatrix(); 
    
  }
  
  void act() {
    
    //velocity.rotate( radians(50) );
    
    location.add(velocity);
    
    if (left) direction.rotate( radians(-5) );
    if (right) direction.rotate( radians(5) );
    if (up) velocity.add(direction);
    if (down) velocity.add(stop);
    
  
    if (location.x > width || location.x < 0) {
      mode = 5;
    }
    
    if (location.y > height + 20 || location.y < -20) {
      mode = 5;
    }
    
   
  }
  
  
}

//THIS IS THE LEVEL ONE

void level01() {
  time = time + 1;
  
  if (time > 1150) mode = 3;
  imageMode(CORNER);
  background(0, 0, 0);
  image(gif[currentPic], 0, 0, 600, 600);
  currentPic++;
  if (currentPic >= 20) {
    currentPic = 0;
  }
  shiptrek.show();
  shiptrek.act();
  
   if (live == 0) {
    mode = 5;
  }
 
  font = loadFont("AmstoniaSans-34.vlw");
  textFont(font);
  //textSize(34);
  fill(255);
  //text("SCORE: " + score, 20, 40);
  text("LIVES: " + live, 20, 80);
  //noStroke();
  //ellipse(xpos, ypos, 50, 50);
  //imageMode(CENTER);
  image(asteroid, xpos, ypos);
  fill(255, 0, 0, 125);
  rect(xpos, ypos, asteroidWidth, asteroidHeight);
  
  xpos = xpos + vx;
  ypos = ypos + vy;
  
  if (ypos < -10 || ypos > height -80) {
    
    vy = vy * -1;
    
  }
  
  if (xpos < 0 || xpos > width-90) {
    
    vx = vx * -1;
    
  }
  
 
 //Defining the collision X
  if (xpos + asteroidWidth + vx > shiptrek.location.x && 
      xpos + vx < shiptrek.location.x + shipWidth && 
      ypos + asteroidHeight > shiptrek.location.y && 
      ypos < shiptrek.location.y + shipHeight) {
   
     if (time > 1) {   
     live = live - 1;
     }
  }
 
   //Defining the collision Y
  if (xpos + asteroidWidth + vx > shiptrek.location.x && 
      xpos < shiptrek.location.x + shipWidth && 
      ypos + asteroidHeight + vy > shiptrek.location.y && 
      ypos + vy < shiptrek.location.y + shipHeight) {
   
     live = live - 1;
     }
  }
  
 
  //Timer
  
   // draw the clock's rectangle
  fill(25, 25, 37, 127);
  stroke(168, 153, 108);
  rect(20,height-40,width-40,20);
  // calculate current time
  long currentTime = millis() - timer;  

  // choose the color, red for < 5s
  //gris
  //fill(197,211,211, 120);
  //Azul
  fill(27,72,113, 140);
  if(TIMEOUT - currentTime < 5000)
    fill(0,255,0);
  // width of the countdown
  float w = map(currentTime,0,TIMEOUT,0,width-40);
  // draw if not the end of time
  if(TIMEOUT - currentTime > 0)
    rect(20,height-40,width-40-w,20);
    
  
}

  
  void keyPressed() {
  if (keyCode == 'W') {
    up = true;
  }
  if (key == 's') {
    down = true;
  }
  if (key == 'a') {
    left = true;
  }
  if (key == 'd') {
    right = true;
  }
  }
  
  void keyReleased() {
  if (keyCode == 'W') { 
    up = false;
  }
  if (key == 's') {
    down = false;
  }
  if (key == 'a') {
    left = false;
  }
  if (key == 'd') {
    right = false;
  }
   }

//THIS IS MOUSE INTERACTION

void mouseReleased() {
  
  if (mode == 1) {
    time = 0;
    image(bgintro2, 0, 0);
    mode = 2;
    
    } else if (mode == 2){
      
        
      }
    
    } else if (mode == 3){
      
    
    } else if (mode == 4){
    
    } else if (mode == 5){
     setup();
     mode = 1;
     
    } else {
      println("mode is broken" + mode);
      
    }
}

//THIS IS INTROMODE

PImage bgintro;
PImage bgintro2;

void intro() {
  imageMode(CORNER);
 bgintro = loadImage ("button_off.jpg");
 bgintro2 = loadImage ("button_on.jpg");
 
 image(bgintro, 0, 0);
 live = 5;
 score = 0;
 
//mouse hover function 
  if (mouseX > rectX && mouseX < rectX + rectWidth && mouseY > rectY && mouseY < rectY + rectHeight) {
    noFill();
    noStroke();
    image(bgintro2, 0, 0);
  } 
  else {
    noFill();
    noStroke();
    image(bgintro, 0, 0);
  }
  
  rect(rectX, rectY, rectWidth, rectHeight);
 
}

//THIS IS GAMEOVER

PImage gameover;

void gameOver() {
  imageMode(CORNER);
  gameover = loadImage ("gameover.jpg");
  
 
 image(gameover, 0, 0);
  
}

```

---

<div class="post-metadata">

### Author: ![hotfooted](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hotfooted/32/3670_2.png) [@hotfooted](https://discourse.processing.org/u/hotfooted)
#### Post date: [February 22, 2019, 12:20pm UTC](https://discourse.processing.org/t/loosing-lives-really-fast-when-collision-happens/8627/4 "2019-02-22T12:20:39Z")

</div>

i sort of get what you’re doing. i see you only have a single asteroid which makes it alot easier basically you can add a variable “colliding” and set it to true when you are colliding with the asteroid and only do collision testing when colliding is false. so basically

replace

```auto
  if (xpos + asteroidWidth + vx > shiptrek.location.x && 
    xpos + vx < shiptrek.location.x + shipWidth && 
    ypos + asteroidHeight > shiptrek.location.y && 
    ypos < shiptrek.location.y + shipHeight) {

    if (time > 1) {   
      live = live - 1;
    }
  }

  //Defining the collision Y
  if (xpos + asteroidWidth + vx > shiptrek.location.x && 
    xpos < shiptrek.location.x + shipWidth && 
    ypos + asteroidHeight + vy > shiptrek.location.y && 
    ypos + vy < shiptrek.location.y + shipHeight) {

    live = live - 1;
  }

```

with something like

```auto
    if (xpos + asteroidWidth + vx > shiptrek.location.x && 
        xpos < shiptrek.location.x + shipWidth && 
        ypos + asteroidHeight + vy > shiptrek.location.y && 
        ypos + vy < shiptrek.location.y + shipHeight) {
      
        if(!ship.isCollding) 
           live = live - 1;
        ship.isColliding = true;
    }
    else {
      ship.isColliding = false;
    }

```

and just add a variable isColliding to the ship

```auto
boolean isColliding = false;

```

---

<div class="post-metadata">

### Author: ![vinipineschi](https://avatars.discourse-cdn.com/v4/letter/v/b2d939/32.png) [@vinipineschi](https://discourse.processing.org/u/vinipineschi)
#### Post date: [February 22, 2019, 7:11pm UTC](https://discourse.processing.org/t/loosing-lives-really-fast-when-collision-happens/8627/5 "2019-02-22T19:11:41Z")

</div>

> [@hotfooted](#):
>
> boolean isColliding = false;

Hi,

Sorry my delay, it works perfectly. Thanks so much for the help.  
Just to documented, I had to change only 2 things in your code, the first one is really simple,  
In that line: if(!ship.isCollding)  
we were missing an I in ¨ship.Collding¨.

And the last one, I replaced all the ship.XXX to shiptrek.XXX that was the name of the new class.  
Bellow is the final code for the level 01:

```auto

void level01() {
  time = time + 1;
  
  if (time > 1150) mode = 3;
  background(0, 0, 0);
  
  
  //GIF
  imageMode(CORNER);
  image(gif[currentPic], 0, 0, 600, 600);
  currentPic++;
  if (currentPic >= 20) {
    currentPic = 0;
  }
  
  
  /*
  //ANIMATED STARS BACKGROUD CLASS
  background(0);
  translate(width/2, height/2);
  for (int i = 0; i < stars.length; i++) {
    stars[i] = update();
    stars[i] = show();
  }
  */
  
  shiptrek.show();
  shiptrek.act();
  
   if (live == 0) {
    mode = 5;
  }
 
  font = loadFont("AmstoniaSans-34.vlw");
  textFont(font);
  //textSize(34);
  fill(255);
  //text("SCORE: " + score, 20, 40);
  text("LIVES: " + live, 20, 80);
  //noStroke();
  //ellipse(xpos, ypos, 50, 50);
  //imageMode(CENTER);
  image(asteroid, xpos, ypos);
  fill(255, 0, 0, 125);
  rect(xpos, ypos, asteroidWidth, asteroidHeight);
  
  xpos = xpos + vx;
  ypos = ypos + vy;
  
  if (ypos < -10 || ypos > height -80) {
    
    vy = vy * -1;
    
  }
  
  if (xpos < 0 || xpos > width-90) {
    
    vx = vx * -1;
    
  }
  
 
 if (xpos + asteroidWidth + vx > shiptrek.location.x && 
        xpos < shiptrek.location.x + shipWidth && 
        ypos + asteroidHeight + vy > shiptrek.location.y && 
        ypos + vy < shiptrek.location.y + shipHeight) {
      
        if(!shiptrek.isColliding) 
           live = live - 1;
        shiptrek.isColliding = true;
    }
    else {
      shiptrek.isColliding = false;
    }
  
  

  
  //Timer
  
   // draw the clock's rectangle
  fill(25, 25, 37, 127);
  stroke(168, 153, 108);
  rect(20,height-40,width-40,20);
  // calculate current time
  long currentTime = millis() - timer;  

  // choose the color, red for < 5s
  //gris
  //fill(197,211,211, 120);
  //Azul
  fill(27,72,113, 140);
  if(TIMEOUT - currentTime < 5000)
    fill(0,255,0);
  // width of the countdown
  float w = map(currentTime,0,TIMEOUT,0,width-40);
  // draw if not the end of time
  if(TIMEOUT - currentTime > 0)
    rect(20,height-40,width-40-w,20);
    
  
}

  
  void keyPressed() {
  if (keyCode == 'W') {
    up = true;
  }
  if (key == 's') {
    down = true;
  }
  if (key == 'a') {
    left = true;
  }
  if (key == 'd') {
    right = true;
  }
  }
  
  void keyReleased() {
  if (keyCode == 'W') { 
    up = false;
  }
  if (key == 's') {
    down = false;
  }
  if (key == 'a') {
    left = false;
  }
  if (key == 'd') {
    right = false;
  }
   }

```

Once again, thank you so much!  
Cheers

---

<div class="post-metadata">

### Author: ![scudly](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/scudly/32/5597_2.png) [@scudly](https://discourse.processing.org/u/scudly)
#### Post date: [February 22, 2019, 7:17pm UTC](https://discourse.processing.org/t/loosing-lives-really-fast-when-collision-happens/8627/6 "2019-02-22T19:17:16Z")

</div>

Other possibilities: if your objects are bouncing off of each other, only count a collision if they overlap AND they are moving towards each other. If they are moving apart, your simulator is “resolving” the collision, so it doesn’t count.

Another possibility is to recognize that you are testing the collision once per frame, e.g. 60 times per second. Scale your damage amount small enough or health large enough so that counting it every frame is reasonable. Leave it up to the player to fly back out of the collision.

Take a look at my p5.js code to see how I resolve the collisions. I scale the damage based on how hard the players’ ships hit other objects. [https://codepen.io/scudly/pen/ZLeejK](https://codepen.io/scudly/pen/ZLeejK) doBounce() at line 278 tests for the collisions and returns the impact force.

---

<div class="post-metadata">

### Author: ![vinipineschi](https://avatars.discourse-cdn.com/v4/letter/v/b2d939/32.png) [@vinipineschi](https://discourse.processing.org/u/vinipineschi)
#### Post date: [February 22, 2019, 9:46pm UTC](https://discourse.processing.org/t/loosing-lives-really-fast-when-collision-happens/8627/7 "2019-02-22T21:46:07Z")

</div>

Good idea as well. Nice game by the way.  
I saw that you created a deathFrame = 300, but I don´t get it how this works. Probably because I am really new learning Processing and I am not not familiar with some p5. components.

I know that I could control the frameRate in processing but this also influence in the general speed of the game. Do you have any example of processing elements based in frame control?

Thanks for answering by the way

---

<div class="post-metadata">

### Author: ![scudly](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/scudly/32/5597_2.png) [@scudly](https://discourse.processing.org/u/scudly)
#### Post date: [February 22, 2019, 11:59pm UTC](https://discourse.processing.org/t/loosing-lives-really-fast-when-collision-happens/8627/8 "2019-02-22T23:59:22Z")

</div>

When a player ship runs out of energy and dies, deathFrame is set to 300 and counts down to zero. During that time, the ship is shown as a fading circle “explosion” and ignores any collisions. Since the frameRate is 60, that gives five seconds dead before the ship re-spawns. deathFrame is just an integer counter, but I also treat it in a few places as a flag to tell me if the ship is still alive.

For a game, you’ll want to leave the frameRate at its default 60 fps to keep motion as smooth as possible. But don’t get stuck thinking that numbers have to be integers. Let your health values be floats and when colliding, subtract 1.0/60 from the health each frame to lose 1 point per second, for example. Start them with 5 or 10 health and see how long they can survive your asteroid field. Maybe at higher levels they start with a lower health in addition to more or faster asteroids.

---

<div class="post-metadata">

### Author: ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)
#### Post date: [February 23, 2019, 7:20pm UTC](https://discourse.processing.org/t/loosing-lives-really-fast-when-collision-happens/8627/9 "2019-02-23T19:20:36Z")

</div>

> [@hotfooted](#):
>
> only do collision testing when colliding is false.

> [@scudly](#):
>
> only count a collision if they overlap AND they are moving towards each other.

These both work, although they both create double-hits in certain situations if the ship or asteroid direction changes.

A common method of dealing with this in classic video games is for “being damaged” to be a state with a duration – say, 1 second – and that while the ship is being damaged it may be knocked back multiple times, but is invincible to further damage. Often the avatar flashes etc. during this period. When that timer ends, the avatar may be damaged again.
