Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I am having trouble with collision detection part of the game.

I am using touch events to fire the gun as you will see in the video. Note, the android icon is a temporary graphic for the bullets

When ever the user touches (represented by clicks in the video)the bullet appears and kills random sprites.

As you can see it never touches the sprites it kills or kill the sprites it does touch.

My Question is How do I fix it, so that the sprite dies when the bullet hits it?

Collision Code snippet:

//Handles Collision
private void CheckCollisions(){     
    synchronized(mSurfaceHolder){
        for (int i = sprites.size() - 1; i >= 0; i--){
            Sprite sprite = sprites.get(i);
            if(sprite.isCollision(bullet)){
                sprites.remove(sprite);
                mScore++;
                if(sprites.size() == 0){
                    mLevel = mLevel +1;
                    currentLevel++;
                    initLevel();                            
                }
                break;
            }           
        }
    }
}

Sprite Class Code Snippet:

//bounding box left<right and top>bottom
int left ;
int right ;
int top ;
int bottom ;
public boolean isCollision(Beam other) {
    // TODO Auto-generated method stub  
    if(this.left>other.right || other.left<other.right)return false;
    if(this.bottom>other.top || other.bottom<other.top)return false;

    return true;
}

EDIT 1:

Sprite Class:

public class Sprite {

   // direction = 0 up, 1 left, 2 down, 3 right,
   // animation = 3 back, 1 left, 0 front, 2 right
   int[] DIRECTION_TO_ANIMATION_MAP = { 3, 1, 0, 2 };
   private static final int BMP_ROWS = 4;
   private static final int BMP_COLUMNS = 3;
   private static final int MAX_SPEED = 5;
   private HitmanView gameView;
   private Bitmap bmp;
   private int x;
   private int y;
   private int xSpeed;
   private int ySpeed;
   private int currentFrame = 0;
   private int width;
   private int height;

   //bounding box left<right and top>bottom
   int left ;
   int right ;
   int top ;
   int bottom ;

   public Sprite(HitmanView gameView, Bitmap bmp) {
         this.width = bmp.getWidth() / BMP_COLUMNS;
         this.height = bmp.getHeight() / BMP_ROWS;
         this.gameView = gameView;
         this.bmp = bmp;
         Random rnd = new Random();
         x = rnd.nextInt(gameView.getWidth() - width);
         y = rnd.nextInt(gameView.getHeight() - height);
         xSpeed = rnd.nextInt(MAX_SPEED * 2) - MAX_SPEED;
         ySpeed = rnd.nextInt(MAX_SPEED * 2) - MAX_SPEED;
   }
   private void update() {
         if (x >= gameView.getWidth() - width - xSpeed || x + xSpeed <= 0) {
                xSpeed = -xSpeed;
         }
         x = x + xSpeed;
         if (y >= gameView.getHeight() - height - ySpeed || y + ySpeed <= 0) {
                ySpeed = -ySpeed;
         }
         y = y + ySpeed;
         currentFrame = ++currentFrame % BMP_COLUMNS;
   }
   public void onDraw(Canvas canvas) {
         update();
         int srcX = currentFrame * width;
         int srcY = getAnimationRow() * height;
         Rect src = new Rect(srcX, srcY, srcX + width, srcY + height);
         Rect dst = new Rect(x, y, x + width, y + height);
         canvas.drawBitmap(bmp, src, dst, null);
   }
   private int getAnimationRow() {
         double dirDouble = (Math.atan2(xSpeed, ySpeed) / (Math.PI / 2) + 2);
         int direction = (int) Math.round(dirDouble) % BMP_ROWS;
         return DIRECTION_TO_ANIMATION_MAP[direction];
   }
   public boolean isCollision(float x2, float y2){
       return x2 > x && x2 < x + width && y2 > y && y2 < y + height;
   }


    public boolean isCollision(Beam other) {
        // TODO Auto-generated method stub  
        if(this.left>other.right || other.left<other.right)return false;
        if(this.bottom>other.top || other.bottom<other.top)return false;

        return true;
    }   
}

Bullet Class:

public class Bullet {

    int mX;
    int mY;
    private Bitmap mBitmap;

    //bounding box left<right and top>bottom
    int left ;
    int right ;
    int top ;
    int bottom ;

    public Bullet (Bitmap mBitmap){
        this.mBitmap = mBitmap;

    }

    public void draw(Canvas canvas, int mX, int mY) {
        this.mX = mX;
        this.mY = mY;
        canvas.drawBitmap(mBitmap, mX, mY, null);
    }
}
share|improve this question
    
-1 Anything wrong with using your debugger and step through the code? –  Maik Semder Jul 1 '11 at 6:19
2  
Try to draw the bounding rect over sprites and bullets. In general is a good idea to write down a Rectangle class whit its collision tests methods and test those methods in a clean way. –  FxIII Jul 1 '11 at 7:13
    
If D is the difference between the two rectangle centers, they collide if Dx < (R'.w + R".w)/2 and Dy <(R'.h + R".h)/2. –  FxIII Jul 1 '11 at 7:19
    
@Maik That doesn't work. @Fxlll To make sure I understand, make a rectangle class and use the Rect collision methods or my own? –  Manji Jul 1 '11 at 15:40

3 Answers 3

This part of your code does not make logical sense for working collision detection.

if(this.left>other.right || other.left<other.right)return false;
if(this.bottom>other.top || other.bottom<other.top)return false;

change it to

if(this.left > other.right) return false;
if(this.right < other.left) return false;
if(this.top > other.bottom) return false;
if(this.bottom < other.top) return false;

This should work assuming the left, right, top and bottom variables are correct at the time of the collision test.

share|improve this answer
    
No it doesn't, I tried using that method the way that LRFLEW said and it still gave me the same result. –  Manji Jul 1 '11 at 2:58
    
Are your left/right/top/bottom methods returning the correct values? –  Jonathan Hobbs Jul 1 '11 at 3:52
    
I am not sure, I tried leaving the left/right/top/bottom blank and I get collisions you see in the video. When ever I give them values(ex: left = x, right = x + width) nothing happens. –  Manji Jul 1 '11 at 3:58
    
Your sprites aren't rotated by any chance, are they? Because in that case, that simple kind of collision detection will not work and you need something a little more complex. Other than that, AttackingHobo's code is 100% correct and the error is somewhere else (probably your right, left, bottom, top values being wrong) –  TravisG Jul 1 '11 at 11:28
    
@Manji, you should try drawing some debugging images over the sprite, 1 for each side, at the sprites position. –  AttackingHobo Jul 1 '11 at 14:47

Why not just create 2 rectangle objects, one for the player and one for the bomb, then check if they intersect?

Rectangle bullet = new Rectangle(bullet.x, bullet.y, bullet.width, bullet.height);
Rectangle player = new Rectangle(player.x, player.y, player.width, player.height);
if(player.intersects(bullet))
    return true;
share|improve this answer

AttackingHobo had the right idea. you can write the same thing, though, as:

if(this.left>other.right || this.left<other.right)return false;
if(this.bottom>other.top || this.bottom<other.top)return false;

(note the change from other to this)

However, this might cause a lack of collisions. This is saying if the position of the bullet image is EXACTALLY the same as the enemy, it will hit. You probobly want some range (based on the size of the enemy and bullet). Try something like this:

final int distance = 10; //set to the number of pixel distance you want the max to be for the collision to occur
if (Math.abs(this.left-other.left) > distance) return false;
if (Math.abs(this.right-other.right) > distance) return false;
if (Math.abs(this.up-other.up) > distance) return false;
if (Math.abs(this.down-other.down) > distance) return false;

return true;

Try that and see how it works. You may need to play with how big distance is, so I separated it from the rest of the code. I hope this helps.

EDIT: Nevermind. I misread the post and misinterpreted what the variables left down right and up meant. The second block of code will probably confuse thing even more :P.

EDIT2: Use this with variables x and y instead.

final int distance = 10; //set to the number of pixel distance you want the max to be for the collision to occur
if (Math.abs(this.x-other.x) > distance) return false;
if (Math.abs(this.y-other.y) > distance) return false;

return true;
share|improve this answer
    
No it didn't work either, I increased the distance and decreased the distance to see if I would get a better collision and I still end up with the same result. –  Manji Jul 1 '11 at 3:10
    
since all I'm given is the code you gave me, I'd have to say the problem probobly lies with the whole left right ect. thing. Try instead getting the objects position ( x and y ) and using Edit 2 –  LRFLEW Jul 1 '11 at 3:32
    
Still no luck, I will post the code to my sprite class and to the bullet class so you can see whats in them both. –  Manji Jul 1 '11 at 4:00
    
-1 to LRFLEW, the collision check at the top of your answer is wrong. For example, your second condition in the first line is: "this.left < other.right". They still do collide if this.left < other.right && this.right > other.right, though. (plus they need to collide on the y axis, too, of course) –  TravisG Jul 1 '11 at 11:26
    
@LRFLEW -1 That is not the same thing. Yours won't work. Mine will. And I am not sure about java, but some languages will execute faster if you have 1 check per if statement, some will run the same speed if the compiler is good. But even so I prefer shorter lines, easier to visually parse. –  AttackingHobo Jul 1 '11 at 14:49

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.