Collision Detection between two images in Java

前端 未结 9 1929
情歌与酒
情歌与酒 2020-11-27 06:53

I have two characters displayed in a game I am writing, the player and the enemy. defined as such:

public void player(Graphics g) {
    g.drawImage(plimg, x,         


        
相关标签:
9条回答
  • 2020-11-27 07:45

    First, use the bounding boxes as described by Jonathan Holland to find if you may have a collision.

    From the (multi-color) sprites, create black and white versions. You probably already have these if your sprites are transparent (i.e. there are places which are inside the bounding box but you can still see the background). These are "masks".

    Use Image.getRGB() on the mask to get at the pixels. For each pixel which isn't transparent, set a bit in an integer array (playerArray and enemyArray below). The size of the array is height if width <= 32 pixels, (width+31)/32*height otherwise. The code below is for width <= 32.

    If you have a collision of the bounding boxes, do this:

    // Find the first line where the two sprites might overlap
    int linePlayer, lineEnemy;
    if (player.y <= enemy.y) {
        linePlayer = enemy.y - player.y;
        lineEnemy = 0;
    } else {
        linePlayer = 0;
        lineEnemy = player.y - enemy.y;
    }
    int line = Math.max(linePlayer, lineEnemy);
    
    // Get the shift between the two
    x = player.x - enemy.x;
    int maxLines = Math.max(player.height, enemy.height);
    for ( line < maxLines; line ++) {
        // if width > 32, then you need a second loop here
        long playerMask = playerArray[linePlayer];
        long enemyMask = enemyArray[lineEnemy];
        // Reproduce the shift between the two sprites
        if (x < 0) playerMask << (-x);
        else enemyMask << x;
        // If the two masks have common bits, binary AND will return != 0
        if ((playerMask & enemyMask) != 0) {
            // Contact!
        }
    
    }
    

    Links: JGame, Framework for Small Java Games

    0 讨论(0)
  • 2020-11-27 07:48

    is there a problem with:

    Rectangle box1 = new Rectangle(100,100,100,100);
    Rectangle box2 = new Rectangle(200,200,100,100);
    
    // what this means is if any pixel in box2 enters (hits) box1
    if (box1.contains(box2)) 
    {
         // collision occurred
    }
    
    // your code for moving the boxes 
    


    this can also be applied to circles:

    Ellipse2D.Double ball1 = new Ellipse2D.Double(100,100,200,200);
    Ellipse2D.Double ball2 = new Ellipse2D.Double(400,100,200,200);
    
    // what this means is if any pixel on the circumference in ball2 touches (hits)
    // ball1
        if (ball1.contains(ball2)) 
        {
             // collision occurred
        }
    
        // your code for moving the balls
    



    to check whether youve hit the edge of a screen you could use the following:

    Rectangle screenBounds = jpanel.getBounds();
    Ellipse2D.Double ball = new Ellipse2D.Double(100,100,200,200);  // diameter 200
    Rectangle ballBounds = ball.getBounds();
    
    if (!screenBounds.contains(ballBounds))
    {
    // the ball touched the edge of the screen
    }
    
    0 讨论(0)
  • 2020-11-27 07:50

    Use a rectangle to surround each player and enemy, the height and width of the rectangles should correspond to the object you're surrounding, imagine it being in a box only big enough to fit it.

    Now, you move these rectangles the same as you do the objects, so they have a 'bounding box'

    I'm not sure if Java has this, but it might have a method on the rectangle object called .intersects() so you'd do if(rectangle1.intersectS(rectangle2) to check to see if an object has collided with another.

    Otherwise you can get the x and y co-ordinates of the boxes and using the height/width of them detect whether they've intersected yourself.

    Anyway, you can use that to either do an event on intersection (make one explode, or whatever) or prevent the movement from being drawn. (revert to previous co-ordinates)

    edit: here we go

    boolean

    intersects(Rectangle r) Determines whether or not this Rectangle and the specified Rectangle intersect.

    So I would do (and don't paste this code, it most likely won't work, not done java for a long time and I didn't do graphics when I did use it.)

    Rectangle rect1 = new Rectangle(player.x, player.y, player.width, player.height);
    
    Rectangle rect2 = new Rectangle(enemy.x, enemy.y, enemy.width, enemy.height);
    
    //detects when the two rectangles hit
    if(rect1.intersects(rect2))
    {
    
    System.out.println("game over, g");
    }
    

    obviously you'd need to fit that in somewhere.

    0 讨论(0)
提交回复
热议问题