简体   繁体   中英

Collision Detection in java?

I am currently making a collision detection in java, I have a two objects coming from a different class which is a bird and a worm. The worm moves in a random direction while the bird move only when I want him to move because I'm the one who's controlling him by using key arrow buttons. Now, if the two objects collide I want only the worm to be vanish and the bird will remain there. Could somebody help me how to do that? Thanks in advance for sharing your ideas.

This codes is coming from my World class.

public void render()
{
    setupStrategy();

    x0_pixel = 0;
    y0_pixel = 0;

    x1_pixel = getWidth();
    y1_pixel = getHeight();

    x1_world = x1_pixel / meter;
    y1_world = y1_pixel / meter;

    Graphics2D g2d = (Graphics2D) strategy.getDrawGraphics();

    g2d.setBackground(Color.lightGray);
    g2d.clearRect(0, 0, x1_pixel, y1_pixel);

    g2d.setColor(Color.BLACK);

    for (double x = 0; x < x1_world; x++)
    {
        for (double y = 0; y < y1_world; y++)
        {
            int xx = convertToPixelX(x);
            int yy = convertToPixelY(y);

            g2d.drawOval(xx, yy, 2, 2);
        }
    }      

    for (Worm worm : worms)
    {
        for (Sprite bird : birds)
        {
            if (!collides())
            {
                bird.render(g2d);
                worm.render(g2d);
            }
        }
    }

    g2d.dispose();
    strategy.show();
    Toolkit.getDefaultToolkit().
    sync();
}




public void start() throws InterruptedException
{
    long prevLoopStart = System.nanoTime();

    Avg avg = new Avg();

    while (true)
    {

        final long loopStart = System.nanoTime();
        final long dt = loopStart - prevLoopStart;

        for (Worm worm : worms)
        {
            worm.move(dt);
        }

        for (Bird bird : birds)
        {
            bird.move(dt);
        }

        render();
        Collides();

        frame.onFpsUpdated(1.0 / dt * SECOND, avg.add(loopStart));

        final long elapsed_ns = System.nanoTime() - loopStart;

        long expected_elapsed_ms = 1000 / 60;
        long elapsed_ms = (long) (elapsed_ns / (1000.0 * 1000.0));
        long sleep_ms = expected_elapsed_ms - elapsed_ms;

        if (sleep_ms > 0)
        {
            Thread.sleep(sleep_ms  /* ms */);
        }

        prevLoopStart = loopStart;
    }
}





private boolean Collides()
{
    ArrayList<Sprite> toDisappear = new ArrayList<Sprite>();
    for (int i = 0; i < worms.size(); i++)
    {
        Sprite r1 = worms.get(i);
        for (int j = i + 1; j < birds.size(); j++)
        {
            Sprite r2 = birds.get(j);
            if (r1 == r2)
            {
                continue;
            }
            Rectangle me = r1.getBounds();
            Rectangle him = r2.getBounds();
            if (me.intersects(him))
            {
                collision = true;
                toDisappear.add(r1);
                toDisappear.add(r2);

            }
            toDisappear.remove(r1);
            todisappear.remove(r2);
        }
    }

    return collision;
}  

This book provides a lot of INFO regarding "Collision Detection" ( Read Chapter 2 and 3 ) and other topics related to Game programming in Java.

http://fivedots.coe.psu.ac.th/~ad/jg/

you have a nested for-loop which checks for collisions between birds and worms. if there is a collision neither of them are drawn. Your code also incorrectly draws birds and worms multiple times.

for (Worm worm : worms){
    for (Sprite bird : birds){
        if (!collides()){
            bird.render(g2d);
            worm.render(g2d);
        }
    }
 }

The correct way to go is to remove the worm from the list when there is a collision:

for (Iterator<Worm> wit = worms.getIterator(); wit.hasNext(); ){
    Worm worm = wit.next();
    for (Sprite bird : birds){
        if (worm.collidesWith(bird)){
            wit.remove();
            break;
        }
    }
 }

for (Worm worm : worms){
    worm.render(g2d);
}

for (Sprite bird : birds){
    bird.render(g2d);
}

Now I assume that you will implement a boolean collidesWith(Bird other) method in class worm so that you can compare that specific worm with the bird you got as an argument. Alternatively make a function as such:

boolean collidesWormBird(Sprite worm, Sprite bird){
    Rectangle me = worm.getBounds();
    Rectangle him = bird.getBounds();
    return me.intersects(him);
}

There are open source frameworks that already do that. If you are doing it for learning purposes then just check their code.

One is Genuts and it SpriteCollisionManager .

The resource that @Upul mention is also of great value.

Regards.

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