0
votes

I am in the course of creating a prototype for a Tower Defense game. Right now, I am hacking in some arrows (like bullets from the towers later on) that should point towards the center of monsters running around. I manage to set the rotation accordingly in the first logic call, but I don't know how to change the code to prevent the following from happening: http://recordit.co/jBdXtGGeN8

In short: The arrow rotates the whole time, even though it should spawn rotated and then only rotate for small values to adjust to the moving monster.

Constructor for the Arrow:

    public Shot(Vector2 position, EntityV2 target) {
        this.sprite = SpriteStore.get().getSprite("resources/sprites/arrowShot.png");   
        this.position = position;
        this.targetEntity = target;
        this.rotation = Math.atan2(targetEntity.getBounds().getCenterY()
            - position.getY(), targetEntity.getBounds()
            .getCenterX() - position.getX());
        this.rotation += Math.PI / 2.0;
        this.angle = Math.toDegrees(rotation);
        this.movementVector = new Vector2();
        bounds = new Rectangle((int) position.getX(), (int) position.getY(), sprite.getWidth(), sprite.getHeight());
    }

Logic update call:

    public void move(float delta) {
        position.add((movementVector.getX() * delta) / 1000, (movementVector.getY() * delta) / 1000);

        if(targetEntity.getBounds().contains(position.getX(), position.getY())) {
            isDone = true;
        }
        bounds.setLocation((int) position.getX(), (int) position.getY());


        rotation = Math.atan2(targetEntity.getBounds().getCenterY()
                - position.getY(), targetEntity.getBounds()
                .getCenterX() - position.getX());
        rotation += Math.PI / 2.0;
        angle = Math.toDegrees(rotation);

        calculateMovementVector(targetEntity.getCenter());      
    }

Render call:

public void draw(Graphics2D g) {
    int x = (int) position.getX() + sprite.getWidth()/2;
    int y = (int) position.getY() + sprite.getHeight()/2;
    g.rotate(angle, x, y);
    sprite.draw(g, (int) position.getX(), (int) position.getY());
    g.rotate(-angle, x, y);
}

The way I calculate the movement Vector(gets applied to the position):

private void calculateMovementVector(Vector2 to) {
    float dX = to.getX() - (float) bounds.getCenterX();
    float dY = to.getY() - (float) bounds.getCenterY();
    float distance = (float) Math.sqrt(dX * dX + dY * dY);
    float sX = speed * dX / distance;
    float sY = speed * dY / distance;
    movementVector.set(sX, sY);
}
1

1 Answers

0
votes

I'm assuming your Graphics2D object is an instance of java.awt.Graphics2D. That said, I think I know your problem:

You're using degrees when the documentation for rotate() specifies that you should be passing in a value in radians. As a measurement in degrees is on a very different scale than one in radians, you're going to find that a small change in degrees results in a very large (possible more than a full circle) change in radians. Try commenting out the degrees conversion, and use rotation instead of angle for the call to g.rotate()