Java collision detection and player movement: tips

Posted by Loris on Game Development See other posts from Game Development or by Loris
Published on 2014-06-24T08:05:00Z Indexed on 2014/08/25 4:33 UTC
Read the original article Hit count: 407

Filed under:
|

I have read a short guide for game develompent (java, without external libraries). I'm facing with collision detection and player (and bullets) movements.

Now i put the code. Most of it is taken from the guide (should i link this guide?). I'm just trying to expand and complete it.

This is the class that take care of updates movements and firing mechanism (and collision detection):

public class ArenaController {

    private Arena arena;

    /** selected cell for movement */
    private float targetX, targetY;

    /** true if droid is moving */
    private boolean moving = false;

    /** true if droid is shooting to enemy */
    private boolean shooting = false;

    private DroidController droidController;

    public ArenaController(Arena arena) {
        this.arena = arena;
        this.droidController = new DroidController(arena);
    }

    public void update(float delta) {

        Droid droid = arena.getDroid();

        //droid movements
        if (moving) {
            droidController.moveDroid(delta, targetX, targetY);
        //check if arrived
        if (droid.getX() == targetX && droid.getY() == targetY)
                moving = false;
        }

        //firing mechanism
        if(shooting) {

        //stop shot if there aren't bullets
        if(arena.getBullets().isEmpty()) {
            shooting = false;
        }

        for(int i = 0; i < arena.getBullets().size(); i++) {

            //current bullet
            Bullet bullet = arena.getBullets().get(i);

            System.out.println(bullet.getBounds());

            //angle calculation
                double angle = Math.atan2(bullet.getEnemyY() - bullet.getY(), bullet.getEnemyX() - bullet.getX());

            //increments x and y
            bullet.setX((float) (bullet.getX() + (Math.cos(angle) * bullet.getSpeed() * delta)));           
            bullet.setY((float) (bullet.getY() + (Math.sin(angle) * bullet.getSpeed() * delta)));

            //collision with obstacles
            for(int j = 0; j < arena.getObstacles().size(); j++) {
            Obstacle obs = arena.getObstacles().get(j);
            if(bullet.getBounds().intersects(obs.getBounds())) {
                System.out.println("Collision detect!");
                arena.removeBullet(bullet);
                }
            }

            //collisions with enemies
            for(int j = 0; j < arena.getEnemies().size(); j++) {
            Enemy ene = arena.getEnemies().get(j);
            if(bullet.getBounds().intersects(ene.getBounds())) {
                System.out.println("Collision detect!");
                arena.removeBullet(bullet);
            }
            }
        }
        }
    }

    public boolean onClick(int x, int y) {
    //click on empty cell
    if(arena.getGrid()[(int)(y / Arena.TILE)][(int)(x / Arena.TILE)] == null) {
        //coordinates
        targetX = x / Arena.TILE;
        targetY = y / Arena.TILE;
        //enables movement
        moving = true;
        return true;
    }
    //click on enemy: fire
    if(arena.getGrid()[(int)(y / Arena.TILE)][(int)(x / Arena.TILE)] instanceof Enemy) {
        //coordinates
        float enemyX = x / Arena.TILE;
        float enemyY = y / Arena.TILE;
        //new bullet
        Bullet bullet = new Bullet();
        //start coordinates
        bullet.setX(arena.getDroid().getX());
        bullet.setY(arena.getDroid().getY());
        //end coordinates (enemie)
        bullet.setEnemyX(enemyX);
        bullet.setEnemyY(enemyY);
        //adds bullet to arena
        arena.addBullet(bullet);
        //enables shooting
        shooting = true;
        return true;
    }

    return false;
}

As you can see for collision detection i'm trying to use Rectangle object. Droid example:

import java.awt.geom.Rectangle2D;

public class Droid {

    private float x;
    private float y;
    private float speed = 20f;
    private float rotation = 0f;
    private float damage = 2f;
    public static final int DIAMETER = 32;
    private Rectangle2D rectangle;

    public Droid() {
        rectangle = new Rectangle2D.Float(x, y, DIAMETER, DIAMETER);
    }

    public float getX() {
            return x;
    }

    public void setX(float x) {
        this.x = x;
        //rectangle update
        rectangle.setRect(x, y, DIAMETER, DIAMETER);
    }

    public float getY() {
        return y;
    }

    public void setY(float y) {
        this.y = y;
        //rectangle update
        rectangle.setRect(x, y, DIAMETER, DIAMETER);
    }

    public float getSpeed() {
        return speed;
    }

    public void setSpeed(float speed) {
        this.speed = speed;
    }

    public float getRotation() {
        return rotation;
    }

    public void setRotation(float rotation) {
        this.rotation = rotation;
    }

    public float getDamage() {
        return damage;
    }

    public void setDamage(float damage) {
        this.damage = damage;
    }

    public Rectangle2D getRectangle() {
        return rectangle;
    }
}

For now, if i start the application and i try to shot to an enemy, is immediately detected a collision and the bullet is removed!

Can you help me with this? If the bullet hit an enemy or an obstacle in his way, it must disappear.

Ps: i know that the movements of the bullets should be managed in another class. This code is temporary.

update

I realized what happens, but not why. With those for loops (which checks collisions) the movements of the bullets are instantaneous instead of gradual.

In addition to this, if i add the collision detection to the Droid, the method intersects returns true ALWAYS while the droid is moving!

public void moveDroid(float delta, float x, float y) {
    Droid droid = arena.getDroid();

    int bearing = 1;
    if (droid.getX() > x) {
        bearing = -1;
    }
    if (droid.getX() != x) {
        droid.setX(droid.getX() + bearing * droid.getSpeed() * delta);
        //obstacles collision detection
        for(Obstacle obs : arena.getObstacles()) {
            if(obs.getRectangle().intersects(droid.getRectangle())) {
                System.out.println("Collision detected");
                                    //ALWAYS HERE
            }
        }
        //controlla se è arrivato
        if ((droid.getX() < x && bearing == -1)
                || (droid.getX() > x && bearing == 1))
            droid.setX(x);
    }

    bearing = 1;
    if (droid.getY() > y) {
        bearing = -1;
    }
    if (droid.getY() != y) {
        droid.setY(droid.getY() + bearing * droid.getSpeed() * delta);
        if ((droid.getY() < y && bearing == -1)
                || (droid.getY() > y && bearing == 1))
            droid.setY(y);
    }
}

© Game Development or respective owner

Related posts about java

Related posts about collision-detection