My Space Ship's Velocity is going whack

Running this code is fine at first, but after a bit the velocity and gravity start moving to opposite extremes, but since they’re opposite they average out to the ship’s velocity. Eventually the ship starts acting weird because it’s velocity is like 1200 but it’s being pulled with the same force by the planet it is next to. How do I stop this from happening?

Space s = new Space();
Planet p = new Planet();
PShape shippy;
PVector ship = new PVector(200, 200);
float shipMass = 10;
PVector gravity = new PVector(0, 0);
PVector vel = new PVector(0, 0);
PVector drag = new PVector(.01, .01);

void setup() {
shapeMode(CENTER);
size(2500, 1600);
fill(0);
textSize(30);
shippy = createShape();
shippy.beginShape();
shippy.fill(150);
shippy.noStroke();
shippy.vertex(-20, -10);
shippy.vertex(-20, 10);
shippy.vertex(20, 10);
shippy.vertex(27, 0);
shippy.vertex(20, -10);
shippy.endShape(CLOSE);
}

void draw() {
scale(1);
background(255, 255, 255, 50);
shapeMode(CENTER);

s.thrust(.2);
s.turn();
p.planet(600, 600, 200, -100);
//p.planet(width/2, height/2, 50, 100);
}

class Planet {
void planet(float planetX, float planetY, float size, float initV) {
float pa = planetX - ship.x;
float pb = planetY - ship.y;
float pr = sqrt(papa+pbpb);

 float g = (100*size*shipMass)/(pr*pr);
 PVector planet = new PVector(pa, pb);
 PVector pSign = new PVector(1, 1);
 circle(planetX, planetY, size);
 
 if (planet.x < 0) {pSign.x = -1; drag.x = .01;} else {pSign.x = 1; drag.x = -.01;}
 if (planet.y < 0) {pSign.y = -1; drag.y = .01;} else {pSign.y = 1; drag.y = -.01;}
 
 PVector pAcc = new PVector(g*pSign.x*abs(pa/pr), g*pSign.y*abs(pb/pr));
 
 gravity.add(pAcc);
 constrain(vel.x, -20, 20);
 constrain(vel.y, -20, 20);
 if(sqrt((ship.x-planetX)*(ship.x-planetX)+(ship.y-planetX)*(ship.y-planetY))<size - (size/5)) {vel = vel.mult(0);}
 gravity.add(drag);
 ship.add(gravity);
 
 text("Pull of the planet on X and Y:   "+ceil(gravity.x*100)+",    "+ceil(gravity.y*100), 100, 200);
 text("pAcc of the planet on X and Y:   "+ceil(pAcc.x*100)+",    "+ceil(pAcc.y*100), 100, 250);

}

void attract() {

}
}

class Space {
PVector acc;

void turn() {
float ax = mouseX-ship.x;
float ay = mouseY-ship.y;
PVector a = new PVector(ax, ay);
float angle = atan2((a.y), (a.x));
pushMatrix();
translate(ship.x, ship.y);
rotate(angle);
translate(-ship.x, -ship.y);
shape(shippy, ship.x, ship.y);
popMatrix();
}

void thrust(float power) {
float a = mouseX - ship.x;
float b = mouseY - ship.y;
float r = sqrt(aa+bb);

PVector mouse = new PVector(a, b);
PVector sign = new PVector(1, 1);

if (mouse.x < 0) {sign.x = -1; drag.x = .01;} else {sign.x = 1; drag.x = -.01;}
if (mouse.y < 0) {sign.y = -1; drag.y = .01;} else {sign.y = 1; drag.y = -.01;}

acc = new PVector(power, power);
acc.x = acc.x * sign.x*abs(a/r)*(r/100);
acc.y = acc.y * sign.y*abs(b/r)*(r/100);
vel.add(acc);
vel.add(drag);
constrain(vel.x, -20, 20);
constrain(vel.y, -20, 20);
ship.add(vel);
text("Velocity on X and Y: "+ceil(vel.x*100)+", "+ceil(vel.y*100), 100, 100);
text("Acceleration on X and Y: "+ceil(acc.x*100)+", "+ceil(acc.y*100), 100, 150);

}
}

Your code seems to be doing the same things in too many places. Generally, a simulation animation should operate in two phases: a physics update and a drawing. The physics update should not do any drawing.

In the physics update, you first want to gather together all the forces acting on your objects, in this case that would be your ship. It looks like you’re applying two forces to your ship: the planet and the mouse. Instead of doing the full physics update in those functions, only have them add to the ship’s acceleration vector. Then, only once, apply the accumulated acceleration to the velocity. Instead of using signs and if statements to aim the drag, just multiply the velocity by 0.99. Then add the velocity to the position and finally draw everything.

You might like to look at the ship.move function in https://codepen.io/scudly/pen/ZLeejK

1 Like