SimObject so; Vector2D ob; float obx, oby; void setup() { size(500,500); background(0); smooth(); noStroke(); fill(255); obx=oby=0.0; Vector2D ob= new Vector2D(0.0, 0.0); Vector2D a= new Vector2D(0.0, 0.0); Vector2D v= new Vector2D(10, 0.0);// 0,0 before Vector2D l= new Vector2D(250, 10); so = new SimObject(l, v, a, 1.5, .85); } void draw() { background(0); obx=mouseX; oby=mouseY; fill(0,255,0); ellipse(obx, oby, 40,40); fill(255); Vector2D gravity = new Vector2D(0, 0.2); so.addForce(gravity); so.addSurfaceFric(); so.simulate(); } //VECTOR CLASS class Vector2D { private float x; private float y; Vector2D(float x_, float y_) {x = x_; y = y_;} Vector2D(int x_, int y_) {x = x_; y = y_;} Vector2D() {x = 0.0f;y = 0.0f;} float getX() {return x;} float getY() {return y;} void setX(float x_) {x = x_;} void setY(float y_) {y = y_;} void setXY(float x_, float y_) {x = x_;y = y_;} void setVector(Vector2D v) {x = v.getX();y = v.getY();} float magnitude() {return (float)Math.sqrt( x * x + y * y);} Vector2D add(Vector2D v) {return new Vector2D(x + v.getX(), y + v.getY());} Vector2D subtract(Vector2D v) {return new Vector2D(x - v.getX(), y - v.getY());} Vector2D multiply(float n) {return new Vector2D(x * n, y * n);} Vector2D divide(float n) {return new Vector2D(x / n, y / n);} void normalize() {x = x / magnitude(); y = y / magnitude();} void limit(float max) {if (magnitude() > max) { normalize(); x *= max; y *= max; }} float heading() { float angle = (float)Math.atan2(y * -1.0f, x); return -1.0f * angle; } Vector2D add(Vector2D v1, Vector2D v2) {return new Vector2D(v1.getX() + v2.getX(), v1.getY() + v2.getY());} Vector2D subtract(Vector2D v1, Vector2D v2) {return new Vector2D(v1.getX() - v2.getX(), v1.getY() - v2.getY());} Vector2D divide(Vector2D v1, float n) {return new Vector2D(v1.getX() / n, v1.getY() / n);} Vector2D multiply(Vector2D v1, float n) {return new Vector2D(v1.getX() * n , v1.getY() * n);} float distance(Vector2D v1, Vector2D v2) {float dx = v1.getX() - v2.getX(); float dy = v1.getY() - v2.getY(); return (float)Math.sqrt(dx * dx + dy * dy);} } //SIMULATED OBJECT CLASS class SimObject { Vector2D loc; Vector2D vel; Vector2D accel; float mass; float max_velocity; float bounciness; float objectSize; SimObject(Vector2D loc_, Vector2D vel_, Vector2D accel_, float mass_, float bounciness_) { // Save the properties we've been constructed with loc = loc_; vel = vel_; accel = accel_; mass = mass_; // set some basic defaults for our other properties max_velocity = 20.0f; bounciness = bounciness_; objectSize = 20.0f; } Vector2D getLocation() { return loc; } void setLocation(Vector2D v) { loc = v; } Vector2D getVelocity() { return vel; } void setVelocity(Vector2D v) { vel = v; } Vector2D getAcceleration() { return accel; } void setAcceleration(Vector2D v) { accel = v; } float getMass() { return mass; } void setMass(float m_) { mass = m_; } void addForce(Vector2D v) { // scale the force by our mass v = v.divide(mass); // add the force to our acceleration accel = accel.add(v); } void addSurfaceFric() { float surfacecoeff; surfacecoeff=.025; if ( (loc.getY() == height - objectSize / 2) ) { accel.setX(-1* surfacecoeff * vel.getX()); } } void simulate() { // Simulate a step in time for our object update(); contain(); display(); } void update() { // update our values for velocity and // location to reflect our movement // add acceleration to velocity vel = vel.add(accel); // limit our velocity to a maximum speed vel.limit(max_velocity); // move our object according to our velocity loc = loc.add(vel); // reset the accerlation forces to zero in // preperation for the next step in time accel.setXY(0.0f, 0.0f); } void contain() { // We want to contain our object to the confines // of the screen, so here we check to make // sure we're within the screen bounds. If we're // at the edge of the screen, we "bounce" back // Contain vertical movement if ( (loc.getY() > height - objectSize / 2) || (loc.getY() < objectSize / 2) ) { // flip our velocity vel.setY(bounciness * -1.0f * vel.getY()); // move our position if (loc.getY() > (height / 2) ) { loc.setY(height - objectSize / 2); } else { loc.setY(objectSize / 2); } } // Contain horizontal movement if ( (loc.getX() > width - objectSize / 2) || (loc.getX() < objectSize / 2) ) { vel.setX(bounciness * -1.0f * vel.getX()); //MIRROR THE Y DATA HERE (MY ADDITION) // move our position if (loc.getX() > (width / 2) ) { loc.setX(width - objectSize / 2); } else { loc.setX(objectSize / 2); } } //THIS CODE ALSO USES THE OBSTACLE float distbc; distbc=sqrt(sq(obx - loc.getX() )+ sq(oby - loc.getY() )); if ( distbc < 30 ) { //Shoot off velocity vel.setX(-1.0f * vel.getX()); vel.setY(-1.0f * vel.getY()); //Change position to edge of obstacle loc.setX( loc.getX()+(loc.getX()-obx)*((30-distbc)/20) ); loc.setY( loc.getY()+(loc.getY()-oby)*((30-distbc)/20) ); } //END OF CODE USING OBSTACLE } void display() { // display our object on screen rectMode(CENTER); //noStroke(); //fill(32, 64, 128, 200); ellipse(loc.getX(), loc.getY(), objectSize, objectSize); } }