Concept for moving in a direction for ship in game asteroids

I want to recreate asteroids game but don’t know how to program ship moving in the direction of it’s aim.

Hi Arsenii, Probably the best way to understand your issue is to post your code.

1 Like

I want my ship to move in the direction that it aims but all my variants do not work at all.Thank you in advance.

spaceShip ship;
boolean left = false;
boolean right = false;
boolean forward = false;
float maxSpeed =  0.25;
float accelL = -0.45;
float accelR = 0.45;
float accelF = -0.05;
float inercia;
void setup() {
  size(1200, 700);
  ship = new spaceShip();
}



void draw() {
  background(0);
  ship.render();
  ship.edges();
}

void keyPressed() {
  if (keyCode == RIGHT) {
    ship.turn(accelR);
  }
  if (keyCode == LEFT) {
    ship.turn(accelL);
  }
  if (keyCode == UP) {
    for (float i = 0.1; i < maxSpeed; i+=0.05) {
      accelF -= i; 
      ship.forward(accelF);
    }
    forward = true;
    accelF =-0.05;
  }
}
class spaceShip {
  PVector pos = new PVector (width/2, height/2);
  float r = 10;
  float heading = 0;
  spaceShip() {
  }

   void render() {
    translate(pos.x, pos.y);
    noFill();
    stroke(255);
    rotate(heading);
    triangle(-r, r, r, r, 0, -r);
  }
  void turn(float angle) {
    heading += angle;
  }
  void forward(float yspeed) {
    float radians = (float)Math.PI * heading / 180;
    pos.y += Math.sin(radians) * yspeed;
    pos.y  -= Math.cos(radians) *yspeed;
  }
  void edges() {
    if (pos.x > width)
      pos.x = 0;
    if (pos.x < 0)
      pos.x = width;
    if (pos.y > height)
      pos.y = 0;
    if (pos.y < 0)
      pos.y = height;
  }
}
2 Likes

I’m a novice myself, but I notice your forward() method is only translating the y coordinate. If you want the ship to move with the heading, i.e. ‘move in the direction of its aim’, you’ll need to do something with the x coordinate.

  void forward(float yspeed) {
    float myRadians = (float)Math.PI * heading / 180;
    pos.y += Math.sin(myRadians) * yspeed;
    pos.y -= Math.cos(myRadians) *yspeed;
  }

I hope someone else can be of more help.

EDIT - In the code above, I changed your variable name radians to myRadians because radians is a built-in function in Processing. https://processing.org/reference/radians_.html

1 Like

@timAllan, you are correct. Set the following line

pos.y -= Math.cos(myRadians) *yspeed;

to

pos.x += Math.cos(myRadians) *yspeed;

Also, @Arsenii, it appears that you are using both radians and degrees in your sketch.
The values accelR and accelL are quite small for degrees.

Your overall logic is sound but your ship will have to spin a lot to orient to the correct direction and that would make the pilot dizzy. :wink:

4 Likes

I am working on a similar problem. I am trying to make an asteroid type game where the ship shoots in the direction of the mouse. I do this by making the ship instance add bullet instances to an array list. In the bullet constructor I have a direction parameter. However, my calculations for the direction are incorrect. Here is my aimDirection() method:

float aimDirection(){
    float opposite = mouseX-x;
    float adjacent = mouseY-y;
    return atan( opposite/adjacent ) ; // tan(theta)=opposite/adjacent
  }

I then set the bullet vectors with this code:

hspeed = speed * cos( direction );
vspeed = speed * sin( direction );

void move(){
    x += hspeed;
    y += vspeed;
    display();
  }

The result is the bullet does not move in the correct direction. Can anyone find my mistake?

As adjacent approaches zero then opposite/adjacent approaches infinity and the sketch will crash. Also tan(a) == tan(a+180) so the angle returned might be 180° in the wrong direction. The solution is to use the atan2(deltaY, deltaX) function like this -

return atan2( adjacent , opposite) ;

It will return an angle in the range > -π and < +π radians ( > -180° and < +180°)

2 Likes

atan2( y, x ) returns -PI to PI. But, in any case, you can feed that angle back into sin() and cos() and it will be correct.

The angle returned has 0 to the right (towards +x) and increases from there in the +y direction which, for Processing, is down. If you have your ship oriented so that it points up and your shots are going off to the right instead, then you could either subtract PI/2 from the angle returned from atan2() or you could swap the order of the inputs and flip a sign: atan2( x, -y ) so that the angle has 0 along the up axis.

An alternative to using angles at all would be to treat your (mouseX-x, mouseY-y) as a vector, normalize it by dividing each term by its length, and multiplying that by the speed directly to get your velocity.

   float velx = mouseX - x;
   float vely = mouseY - y;
   float s = speed / sqrt( velx*velx + vely*vely );
   velx *= s;
   vely *= s;

   // in `move()`:
   x += velx;
   y += vely;
3 Likes

True I will correct my post. Your other points are well taken though I recommend that users treat the positive X direction as 0° for all objects because it saves having to make corrections in the code.

1 Like

@scudly @quark
Thanks guys! That fixed it. I am adding Asteroids to my high school Programming class and I’m pretty excited about it. Getting these controls right was a big step!