简体   繁体   中英

How can I fix my crash method/collision detection between my player and other objects?

Currently, I'm making a 2d java game that includes a tank at the top of the screen shooting the oncoming cars from below, I have made a crash method and collision detection which determines to stop the game when the tank crashes or enters the radius of the cars. However, sometimes it works early, sometimes late and other times it doesn't. My question is how can I fix it so that when the tank enters the radius of the car it stops the game with simple code that excludes vectors.

Below are my classes and code. I'm using Java in Processing.

PImage bg;                 //loads bakground
PFont f;                   //loads font

Car[] cars = new Car[3];
//Bullet[] bullets = new Bullet[100];

int x = 0;
int y = 0; 
int game = 0; 
int running = 0;
int over = 1;
int score = 0;
int move = 20;
int cX, cY;
//int carRadius = 20;

Tank tank;

void setup()
{
  size(500,1000);
  textSize(40);
  bg = loadImage("bg.jpeg");             //loads background
  bg.resize(width,height);               //the background will fill the height and width of the screen size
  tank = new Tank(tankX, tankY, 3, 2);      //X pos, Y pos, speedY
  for (int i=0; i<cars.length; i++)
  {
    int cX = (int)random(width-100);      //car xpos
    int cY = (int)random(900);            //car ypos
    int speedY = 3;                       //car speedY
    cars[i] = new Car(cX, cY, speedY);
  }
      
  cars[0] = new Car((int)random(5, width-100), (int)random(5, height), 2); //X pos, Y pos, speedY
  cars[1] = new Car((int)random(5, width-100), (int)random(5, height), 2); //X pos, Y pos, speedY
  cars[2] = new Car((int)random(5, width-100), (int)random(5, height), 2); //X pos, Y pos, speedY
  
  f = createFont("Arial", 36, true);
}

void draw()
{
  if (game == running)
  {
    drawBackground();       //background
    for (Car c : cars) {
      c.draw();
      c.move();
    }
    tank.draw();            //tank
    drawScore();            //draw score

    //if (bullet.crash(cars[0]) == true) {
    //  cars.remove(c);
    //  score++;
    //}
      
    if (game == over)
    {
      tank.speedX = 0;
      tank.speedY = 0;
      move = 0;
      gameOver();
    }
    
    //if tank crashes into cars
    if(tank.crash(cars[0]))
    {
      game = over;
      gameOver();
    }
    if(tank.crash(cars[1]))
    {
      game = over;
      gameOver();
    }
    if(tank.crash(cars[2]))
    {
      game = over;
      gameOver();
    }
    /*

    if(bullet.shoot(cars[0]))
    {
      cars[0].remove(c);
      score++;
    }
    if(bullet.shoot(cars[1]))
    {
      cars[1].remove(c);
      score++;
    }
    if(bullet.shoot(cars[2]))
    {
      cars[2].remove(c);
      score++;
    }
    */
  }
}

void keyReleased() {
  tankXD = 0;
  tankYD = 0;
}

void keyPressed() //controls for the tank using the arrow keys
{
  if(keyCode == LEFT) { 
    tankXD =- 10;
  }
  if(keyCode == RIGHT) {
    tankXD = 10; 
  }
  if(keyCode == DOWN) { 
    tankYD = 10; 
  }
  if(keyCode == UP) { 
    tankYD =- 10; 
  }
  if(keyCode == ' ') {
    bulletSPD = 30;
    //bullets.add(new Bullet(tank.x+30, tank.y+140, 3));
}
}

//void carFill()
// {
//   fill(255,0,0);
// }
 
void drawBackground()
{
  image(bg, y, 0);
}

void drawScore() {
  fill(255);
  textFont(f);
  text("Score: " + String.valueOf(score), 200, 50);
}

void gameOver() {
  clear();
  textFont(f);
  text("Game Over! ", 150, 400);
}
class Car 
{
  //members
   int cX, cY;
   int speedY = 2;
   int speedX = 0;
   int animationCounter = 0;
   int carRadius = 30;
   PImage image1,image2,image3;
   
   //constructor
   Car(int cX, int cY, int speedY)
   {
     this.cX = cX;
     this.cY = cY;
     this.speedY = speedY;
     image1 = loadImage("c1.png");
     image2 = loadImage("c2.png");
     image3 = loadImage("c3.png");
   }
   
   void update() {
     draw();
     move();
   }
   
   void move()
     {
    this.cY = this.cY - speedY; //move upwards
    
    if(this.cY < 0 - image1.height)
    this.cY = height + image1.height;
       
    if(this.cY > height + image1.height +30)
    this.cY = -image1.height;
  }
  
   void draw()
   {
     if (animationCounter >=0  &  animationCounter <=8) 
   { image(image1,this.cX,this.cY); }
   else if (animationCounter >8  &  animationCounter <=16) 
 { image(image2,this.cX,this.cY); }
 else
 { image(image3,this.cX,this.cY); }
 
 animationCounter = animationCounter + 1;
 if(animationCounter>20)
 animationCounter = 0; 
 }

}
int tankX = 215;           //tank xpos
int tankY = 60;            //tank ypos
int tankXD = 0;            //tank x dir
int tankYD =  0;           //tank y dir
int bulletX = tankX;       //bullet xpos
int bulletY = tankY;       //bullet ypos
int bulletW = 8;       //bullet xpos
int bulletH = 20;       //bullet ypos
int bulletSPD = 0;         //bullet speed
int bulletRadius = 4;
float bulletDistance = 5;
PImage image1;

class Tank
{
  //members
  int tankX;
  int tankY;
  int speedX;
  int speedY;
  
  //constructor
  Tank (int tankX, int tankY, int speedX, int speedY)
  {
    this.tankX = tankX;
    this.tankY = tankY;
    this.speedX = speedX;
    this.speedY = speedY;
    image1 = loadImage("tank.png");
  }
  
  void draw() {
    image(image1,tankX, tankY);
    
    tankX+=tankXD;
    tankY+=tankYD;
    bulletX=tankX;
    bulletY+=bulletSPD;
    if(bulletY>800) {
      bulletX=tankX;
      bulletY=tankY;
      bulletSPD=0;
    }
    //draw bullet
    fill(255,0,0);
    stroke(255,0,0);
    rect(bulletX+30, bulletY+140, bulletW, bulletH);

  }

//tank crash method
boolean crash(Car other)
{
  return (abs(this.tankY-other.cY) <20) && abs(this.tankX-other.cX) <10;
}

/*
boolean shoot (Bullet b, Car c) {
  float d = dist(bulletX, bulletY, cX, cY);
  if ((d < 5) == true) {
    // we have a collision
    return true;
  } else {
    return false;
  }
}
*/
/*
boolean shoot(Car c) {
  float d = dist(bulletX, bulletY, cX, cY);
  if (d < 5) {
    // we have a collision
    return true;
  } else {
    return false;
  }
}
*/

}

So I believe you want to fix the collision. If you have two circles and you want to see if they collide, you need to see if the radii collide. You can do this by seeing if the distance between the centers is greater than or less than the total of the two radii. Like this:

//returns whether or not two circles collide
//x1, y1, and r1 are for circle 1
boolean colliding(int x1, int y1, int x2, int y2, int r1, int r2) {
     return sqrt(pow(x1-x2, 2) + pow(y1-y2, 2)); <= r1 + r2
}

If you wish to use rectangular hitboxes instead, check this link . I hope this helped, have a good day.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM