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 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);
    }
}
share|improve this question
    
Don't create a new instance of Rectangle every time you call getBounds(). The garbage collector may temporarily freeze your game when it's trying to reclaim memory. Consider having a Rectangle field in your model and return that instead. –  user16547 Jun 24 at 20:43
    
Thanks for the suggestion, but i have the same issue... –  Loris Jun 25 at 7:46
add comment

1 Answer 1

Here is how to use Rectangle's to dedect collision:

(Sorry for the bad explanation)

public static boolean checkCollision(int x, int y, int sx, int sy, int x2, int y2, int sx2, int sy2){
//x and y = Coords of 1st object.
//sx and sy = Sizes of the object in the given axises.
//All the variables with "2" are for the second object.

//If you don't calculate "sx" of the object, "sx" can be found by subtracting
//the first x value of the object from the second (x2-x) (x2 is not the one stated above)

    Rectangle r1 = new Rectangle(int x, int sx, int y, int sy);
    Rectangle r2 = new Rectangle(int x2, int sx2, int y2, int sy2);

    return r1.intersects(r2);
}
share|improve this answer
    
The issue still persist. As soon as i shoot an enemy, the bullet disappear. The collision is immediately found and i don't know why. –  Loris Jun 25 at 7:54
    
Maybe the x,y values of the bullets are wrong? Try debugging your program. –  Sierox Jun 25 at 19:13
    
I changed the code several times and i always get the same behaviour. I drawn the rectangles to see if they are created correctly and so it seems. I tried to add collision detection to the movements of the droid (intersection between rectangles, droid and obstacles) and the method intersects ALWAYS returns true while the droid is moving! –  Loris Jun 25 at 19:45
    
You should find a problem like this by yourself, you shouldn't say, here is my code, fix it for me. Like I said debug your program. –  Sierox Jun 30 at 13:24
add comment

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.