/* built with Studio Sketchpad:
* https://sketchpad.cc
*
* observe the evolution of this sketch:
* https://studio.sketchpad.cc/sp/pad/view/ro.C9xqONTO0b5/rev.2500
*
* authors:
* Mitch Davis
* license (unless otherwise specified):
* creative commons attribution-share alike 3.0 license.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
// Pressing Control-R will render this sketch.
int i = 0;
Planet[] planets = new Planet[1];
Ship ship = new Ship(400,300);
Planet[] stars = new Planet[200];
boolean instructions = true;
int simulate = 300;
boolean[] keys = new boolean[255];
void setup() { // this is run once.
// set the background color
background(0);
// canvas size (Variable aren't evaluated. Integers only, please.)
size(800, 600);
// smooth edges
smooth();
// limit the number of frames per second
frameRate(30);
for (int i = 0; i < planets.length(); i++) {
planets[i] = new Planet(-1);
}
for (int i = 0; i < stars.length(); i++) {
stars[i] = new Planet(1);
}
// set the width of the line.
strokeWeight(3);
}
void draw() { // this is run repeatedly.
background(0);
if(keys[DOWN]) { ship.yVelocity+=.05; }
if(keys[UP]) { ship.yVelocity-=.05; }
if(keys[LEFT]) { ship.xVelocity-=.05; }
if(keys[RIGHT]) { ship.xVelocity+=.05; }
for (int i = 0; i < stars.length(); i++) {
//println("TEST");
stars[i].draw();
}
for (int i = 0; i < planets.length(); i++) {
//println("TEST");
planets[i].draw();
}
//println("HEY");
if (ship.moving) {
ship.update();
ship.draw();
} else {
ship.simulate(simulate);
}
if (instructions) {
textSize(30);
text("Use Arrow Keys to change trajectory", 15, 60);
text("Press ENTER to play/pause", 15, 100);
textSize(15);
text("After you've got the hang of that, try these", 15, 140);
text("Use 1-9 to change planets", 15, 160);
text("Press Z to reverse direction (Go backward)", 15, 180);
text("Press +/- to change prediction length", 15, 180);
//text("Press i/o to zoom in/out", 15, 200);
}
}
public void keyPressed() {
if(keyCode == ENTER) {
ship.moving = ! ship.moving;
instructions = false;
}
if (key >= '1' && key <= '9') {
planets = new Planet[key - '0'];
setup();
}
if (key == 'z') {
ship.xVelocity = -ship.xVelocity;
ship.yVelocity = -ship.yVelocity;
}
if (key == '+' || key == '=') {
simulate ++;
}
if (key == '-') {
simulate --;
}
keys[keyCode] = true;
}
public void keyReleased() {
keys[keyCode] = false;
}
public class Planet {
int radius;
int x, y;
int r,g,b = 0;
float mass;
public Planet(int size) {
//Create a random position, and then make
//sure it doesn't collide with anything.
r = random(255);
g = random(255);
b = random(255);
if (size < 0) {
radius = random(20,100);
} else {
radius = size;
r = g = b = 255;
}
x = random(radius, width-radius);
y = random(radius, height-radius);
mass = (radius * radius);
}
void draw() {
fill(r,g,b,255);
stroke(r/2,g/2,b/2,255);
ellipse(x,y,radius,radius);
}
void applyGravity(Ship ship) {
int deltaX = x-ship.x;
int deltaY = y-ship.y;
float distance = Math.sqrt((deltaX*deltaX) + (deltaY*deltaY));
float pull = mass / distance;
pull /= distance;
float unitX = deltaX / distance;
float unitY = deltaY / distance;
ship.xVelocity += (pull * unitX);
ship.yVelocity += (pull * unitY);
//Apply this pull in the direction of the planet
}
}
public class Ship {
float x,y;
float xVelocity, yVelocity;
boolean moving = false;
public Ship(int x, int y) {
this.x = x;
this.y = y;
yVelocity = 5;
xVelocity = 5;
}
public void update() {
//Check each planet
for (int i = 0; i < planets.length(); i++) {
planets[i].applyGravity(this);
}
x += xVelocity;
y += yVelocity;
}
public void draw() {
fill(255,255,255,255);
stroke(150,150,150,255);
ellipse(x,y,10,10);
}
public void simulate(int times) {
//Show velocity
//Save everything
int oldX = x;
int oldY = y;
float oldXVel = xVelocity;
fkiat oldYVel = yVelocity;
for (int i = 0; i < times; i++) {
update();
draw();
}
//Restore everything
x = oldX;
y = oldY;
xVelocity = oldXVel;
yVelocity = oldYVel;
stroke(255,0,0,255);
int x2 = x + (xVelocity*10);
int y2 = y + (yVelocity*10);
line(x,y,x + (xVelocity*10), y + (yVelocity*10));
}
}