Question

In a Java 2D game, I have a rectangular sprite of a tank. The sprite can rotate in any angle, and travel in the direction of that angle.

This sprite needs to have a bounding box, so I can detect collision to it.

This bounding box needs to:

  1. Follow the sprite around the screen.
  2. Rotate when the sprite rotates.

Obviously it should be invisible, but right now I'm drawing the box on the screen to see if it works. It doesn't.

My problem is this:

When the sprite travels parallel to the x axis or y axis, the box follows correctly and keeps 'wrapping' the sprite precisely.

But when the sprites travles diagonaly, the box doesn't follow the sprite correctly.

Sometimes it moves too much along the x axis and too little along the y axis. Sometimes the opposite. And maybe sometimes too much both or too little on both. Not sure.

Could you look at my code and tell me if you see anything wrong?

(Please note: The bounding box most of the time is actually just two arrays of coordinates, each one containing 4 values. The coordinates are used to form a Polygon when collision is checked, or when the box is drawn to the screen).

Relevant code from the Entity class, the superclass of Tank:

int[] xcoo = new int[4]; // coordinates of 4 vertices of the bounding box.
int[] ycoo = new int[4];

double x,y; // current position of the sprite.
double dx,dy; // how much to move the sprite, and the vertices of the bounding box.
double angle; // current angle of movement and rotation of sprite and bounding-box.

// Returns a Polygon object, that's the bounding box.
public Polygon getPolyBounds(){ return new Polygon(xcoo,ycoo,xcoo.length) ; }

public void move(){

 // Move sprite
    x += dx;
    y += dy;

 // Move vertices of bounding box.
     for(int i=0;i<4;i++){
        xcoo[i] += dx;
        ycoo[i] += dy;
    } 

 // Code to rotate the bounding box according to the angle, will be added later.
 // ....

}

Relevant code from the Board class, the class that runs most of the game. This is from the game-loop.

// keysPressed1 is an array of flags to tell which key is currently pressed.

// if left arrow is pressed
if(keysPressed1[0]==true)
    tank1.setAngle(tank1.getAngle()-3);

// if right arrow is pressed
if(keysPressed1[1]==true)
    tank1.setAngle(tank1.getAngle()+3);

// if up arrow is pressed (sets the direction to move, based on angle).
if(keysPressed1[2]==true){
    tank1.setDX(2 * Math.cos(Math.toRadians(tank1.getAngle())));
    tank1.setDY(2 * Math.sin(Math.toRadians(tank1.getAngle())));

    tank1.move(); // should move both the sprite, and it's bounding box.

}

Thanks a lot for your help. If you need me to explain something about the code so you can help me, please say so.

Was it helpful?

Solution

Your sprite is using doubles and your bounding box is using ints, see these declarations:

  • int[] xcoo = new int[4];

  • double x, y

And the following updates:

(double dx, dy, showing it is a double)

  • x += dx

  • xcoo[i] += dx

In the latter (the bounding box) you are adding an int to a double which causes it to drop it's decimal places as it is being cast to an integer.

Hence why they do not follow the sprite exactly, as an int can never follow a double.

To solve this you need xcoo, ycoo and corresponding methods to work with double instead of int.

Update: So Polygon only takes Integers appereantly, to solve that take a look at the following question: Polygons with Double Coordinates

You should be using Path2D.Double

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top