Skip to content

Instantly share code, notes, and snippets.

@nathanielarking
Created May 17, 2020 05:55
Show Gist options
  • Save nathanielarking/f04e41387799499a09679587d9bfc483 to your computer and use it in GitHub Desktop.
Save nathanielarking/f04e41387799499a09679587d9bfc483 to your computer and use it in GitHub Desktop.
Simply gravity simulation
class Entity{
boolean spawned = false;
boolean freeze = false;
PVector pos, vel, acc;
float mass, size;
int[] colour = new int[3];
Entity(){
pos = new PVector();
vel = new PVector();
acc = new PVector(0, 0);
mass = random(0.5, 6);
size = mass * 20;
for(int i = 0; i < 3; i++){
colour[i] = int(random(50, 255));
}
}
void randomize(){
for(int i = 0; i < 3; i++){
colour[i] = int(random(50, 255));
}
}
void setMass(int m){
mass = m;
size = mass * 20;
}
void updateEntity(){
vel.add(acc);
pos.add(vel);
acc.mult(0);
}
void collideEntity(int mode){
if(mode == 0){
if(pos.x > (width - size/2)){
pos.x = (width - size/2);
vel.x *= -1;
}else if(pos.x < (0 + size/2)){
pos.x = (0 + size/2);
vel.x *= -1;
}
if(pos.y > (height - size/2)){
pos.y = (height - size/2);
vel.y *= -1;
}else if(pos.y < (0 + size/2)){
pos.y = (0 + size/2);
vel.y *= -1;
}
}else if (mode == 1){
if(pos.x < 0) pos.x = width;
if(pos.x > width) pos.x = 0;
if(pos.y < 0) pos.y = height;
if(pos.y > height) pos.y = 0;
}else{
if(pos.x < 0) spawned = false;
if(pos.x > width) spawned = false;
if(pos.y < 0) spawned = false;
if(pos.y > height) spawned = false;
}
}
void displayEntity(){
stroke(255);
strokeWeight(2);
fill(colour[0], colour[1], colour[2]);
if(spawned) ellipse(pos.x, pos.y, size, size);
}
PVector attract(Entity a){
if((spawned) && (!freeze) && (a.spawned) && (!a.freeze)){
PVector force = PVector.sub(pos, a.pos);
float d = force.mag();
d = constrain(d, 1, 25);
float str = (mass * a.mass * -G)/(d*d);
force.normalize();
force.mult(str);
force.y *= -1;
return force;
}else{
PVector force = new PVector(0, 0);
return force;
}
}
void applyForce(PVector force){
if(!freeze){
PVector f = PVector.div(force,mass);
f.y *= -1;
acc.add(f);
}
}
}
//Press stores whether or not the mouse is being held
boolean press = false;
//Vectors to store mouse coordinates
PVector click = new PVector();
PVector mouse = new PVector(mouseX, mouseY);
//Count stores which entity is next to be spawned our of our array of entities
int count = 0;
Entity[] objects = new Entity[100];
float G = 10;
int mass = 3;
void setup(){
size(1280, 720);
frameRate(45);
background(255);
strokeWeight(1);
stroke(0);
fill(100);
for(int i = 0; i < objects.length; i++) objects[i] = new Entity();
}
void draw(){
background(0);
String mstring = str(mass);
stroke(255);
fill(255);
text(mstring, 15, height - 15);
drawReset();
checkPress();
updateEntities(objects);
}
void drawReset(){
stroke(255);
fill(255);
rect(width - 60, height - 30, 60, 30);
stroke(0);
fill(0);
text("RESET", width - 50, height - 10);
if(mousePressed && (((mouseX > width - 60) && (mouseX < width)) && ((mouseY > height - 30) && (mouseY < height)))){
for(Entity o : objects){
o.spawned = false;
count = 0;
}
}
}
void mouseWheel(MouseEvent event) {
float m = event.getCount();
mass -= m;
if(mass < 1) mass = 1;
if(mass > 10) mass = 10;
}
void checkPress(){
if(mousePressed){
//This says: if the mouse is being pressed for the first time after being releasd
if(!press){
//Update our click vector to the spot where the mouse is clicked
click.x = mouseX;
click.y = mouseY;
//Set the position of one of the objects to our cursor, reset the velocity & accelleration, randomize the shape and colour, and then enable displaying of the entity. Also freeze the entity so gravity doesn't affect it yet
objects[count].pos = click.get();
objects[count].vel.mult(0);
objects[count].acc.mult(0);
objects[count].freeze = true;
objects[count].randomize();
objects[count].setMass(mass);
objects[count].spawned = true;
//This informs the next draw loop that the mouse is now being held down
press = true;
//This says: if the mouse is currently being held
}else{
//Update our mouse vector to current cursor position
mouse.x = mouseX;
mouse.y = mouseY;
//Define a new vector that is the line from our original click spot to our current mouse position
PVector traj = mouse.sub(click);
//Draw a line from our original click position along our trajectory vector to our current mouse position, weighted based on the traj length
stroke(255);
strokeWeight(traj.mag() * 0.01);
line(click.x, click.y, (click.x + traj.x), (click.y + traj.y));
objects[count].setMass(mass);
}
//This says: if the mouse is not pressed but on the previous frame it was
}else if(press){
//Update mouse vector
mouse.x = mouseX;
mouse.y = mouseY;
//Update traj vector
PVector traj = mouse.sub(click);
//Set velocity of entity based on the traj vector, reversing it and tying it to mass. Then unfreeze
objects[count].vel = traj.get();
objects[count].vel.mult(-0.1 / objects[count].mass);
objects[count].freeze = false;
//This resets our press variable for the next time the mouse is pressed, incrementing the object counter and wrapping it to 0 to keep within the bounds of our array
press = false;
count++;
if(count == objects.length) count = 0;
}
}
void updateEntities(Entity[] objects){
for(int i = 0; i < objects.length; i++){
//Apply attraction
for(int a = 0; a < objects.length; a++){
if(a != i){
objects[i].applyForce(objects[i].attract(objects[a]));
}
}
//Update objects
objects[i].displayEntity();
objects[i].collideEntity(3a);
objects[i].updateEntity();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment