Search code examples
javapath-finding

Java - Diagonal Movement


I'm making a version of SpaceInvaders and I would like my Shoots to have a diagonal movement. I tried to google it, but I can figure out how to do it.

I've got the class Entity:

public abstract class Entity extends Parent{
    protected double x;
    protected double y;
    protected double dx;
    protected double dy;
    private Rectangle me = new Rectangle();
    private Rectangle him = new Rectangle();

        Image ref;
        StackPane root;


        ImageView content;
    public Entity(Image ref,int x,int y, StackPane root)  {
                this.ref=ref;
                this.root=root;
        this.x = x;
        this.y = y;


                content = new ImageView();
                content.setSmooth(true);
                content.setImage(ref);

                content.setScaleX(Game.scalar); 
                content.setScaleY(Game.scalar); 


                content.setTranslateX(this.x);
                content.setTranslateY(this.y);
                content.setRotate(0);

                Game.root.getChildren().add(content);



    }

    public void move(long delta) {
        this.x += (delta * this.dx) / 1000;
        this.y += (delta * this.dy) / 1000;

         content.setTranslateX(this.x);
         content.setTranslateY(this.y);


    }

Now, how could I set a diagonal movement? I printed the game with the Shoot Entity.

Thaks. Alien Shoot


Solution

  • You should use trigonometry, in particular sin and cos. The standard java class Math has those methods.

    For example, we could think that a bullet traveling from the bottom to the top is going at an angle of 90 degrees (0 is from left to right, 180 is from right to left and 270 is from top to bottom):

    double angle = 90.0;
    double angleInRadians = Math.toRadians(angle);  // convert from degrees to radians
    x += Math.cos(angleInRadians);  // cos of 90 is 0, so no horizontal movement
    y += Math.sin(angleInRadians);  // sin of 90 is 1, full vertical movement
    

    To go diagonal just use a different angle, for example with 60 degree the bullet will travel both horizontally and vertically:

    double angle = 60.0;
    double angleInRadians = Math.toRadians(angle);  // convert from degrees to radians
    x += Math.cos(angleInRadians);  // cos of 60 is 0.58.., so a bit of horizontal movement
    y += Math.sin(angleInRadians);  // sin of 60 is 0.80.., a decent amount of vertical movement
    

    Why sine and cosine? A visual representation.

    The image below show what we want to achieve, basically find the delta x and delta y to add to our origin position in order to reach the destination position, which are not perpendicular to each other.

    The situation representation

    Now let's take a look at what sine and cosine represent:

    sine and cosine representation

    (Source: Wikipedia.)

    We can notice the similarities: the points O and P are respectively our origin and destination, while sin θ and cos θ corresponds to delta y and delta x.

    Applying these concepts to our situation we end up with:

    sine and cosine applied

    Sine and cosine require an angle, which will define the movement direction of our object.

    They will return a value between -1 and 1, so we will need to multiply it with a coefficient if we want to change the object movement "speed".