Last active
December 23, 2015 11:49
-
-
Save macklinu/6630759 to your computer and use it in GitHub Desktop.
Asteroids snippet
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class Asteroid { | |
| PVector location; | |
| PVector velocity; | |
| PVector acceleration; | |
| float mass; | |
| String tweet; | |
| float x, y, w, h; | |
| boolean hit; | |
| boolean dead; | |
| float hitTime, textTime; | |
| // standard constructor | |
| Asteroid(float x, float y, float w, String tweet) { | |
| this.x = x; | |
| this.y = y; | |
| this.w = map(w, 0, 140, 10, 140); | |
| mass = map(w, 0, 140, 280, 800); | |
| this.tweet = tweet; | |
| location = new PVector(x, y); | |
| velocity = new PVector(0, 0); | |
| acceleration = new PVector(0, 0); | |
| hit = dead = false; | |
| textTime = 6000; | |
| } | |
| // used to make a copy of a to-be-destroyed asteroid | |
| Asteroid(Asteroid a) { | |
| this.x = a.x; | |
| this.y = a.y; | |
| this.w = map(a.w, 0, 140, 10, 140); | |
| mass = map(a.w, 0, 140, 280, 800); | |
| this.tweet = a.tweet; | |
| location = new PVector(a.x, a.y); | |
| velocity = new PVector(0, 0); | |
| acceleration = new PVector(0, 0); | |
| hit = dead = false; | |
| textTime = 6000; | |
| } | |
| void applyForce(PVector force) { | |
| PVector f = PVector.div(force, mass); | |
| acceleration.add(f); | |
| } | |
| void update() { | |
| velocity.add(acceleration); | |
| location.add(velocity); | |
| acceleration.mult(-0.01); | |
| } | |
| void display() { | |
| if (hit) { | |
| // want to implement a time system to display tweets in the asteroid field instead of a textbox | |
| dead = true; | |
| } | |
| else { | |
| stroke(255); | |
| noFill(); | |
| ellipse(location.x, location.y, w, w); | |
| } | |
| } | |
| void hit(boolean b) { | |
| hit = b; | |
| hitTime = millis(); | |
| } | |
| ///////////// | |
| // getters // | |
| ///////////// | |
| PVector repel(Asteroid a) { | |
| PVector force = PVector.sub(location, a.location); // Calculate direction of force | |
| float distance = force.mag(); // Distance between objects | |
| distance = constrain(distance, 1.0, 10000.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects | |
| force.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction | |
| float strength = (g * mass * a.mass) / (distance * distance); // Calculate gravitional force magnitude | |
| force.mult(-1*strength); // Get force vector --> magnitude * direction | |
| return force; | |
| } | |
| boolean isHit() { | |
| return hit; | |
| } | |
| boolean isDead() { | |
| return dead; | |
| } | |
| String getTweet() { | |
| return tweet; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // draw() == main() loop in Processing | |
| // removing some code | |
| // original here: https://github.com/macklinu/senior-thesis-data-viz/blob/master/macklinu_senior_thesis/all_code/asteroids/asteroids.pde | |
| ArrayList<Asteroid> asteroids; | |
| ArrayList<Asteroid> tempAsteroids; | |
| Gun gun; | |
| void draw() { | |
| // determine if SNES controller or keyboard is game controller | |
| // draw the screen | |
| // draw elements on screen (gun, asteroids, bullets, etc.) | |
| // iterate through on screen asteroids | |
| ListIterator<Asteroid> it = asteroids.listIterator(); // all on-screen asteroids | |
| List<Bullet> activeBullets = gun.getBullets(); // current on-screen bullets | |
| List<Asteroid> deadAsteroids = new ArrayList<Asteroid>(); // temp dead asteroid pool | |
| List<Bullet> deadBullets = new ArrayList<Bullet>(); // temp dead bullet pool | |
| while (it.hasNext()) { // while there are asteroids | |
| Asteroid a = it.next(); // a = the asteroid we're looking at | |
| // check each bullet for collisions | |
| for (Bullet b : activeBullets) { | |
| checkCollision(a, b); | |
| if (b.isOffScreen()) deadBullets.add(b); // if the bullet leaves the screen | |
| if (a.isHit()) { // if the asteroid is hit | |
| deadBullets.add(b); | |
| allTweets += a.getTweet() + "\n\n"; // add tweet to tweet text box on the right side of the screen | |
| tweetArea.setText(allTweets).scroll(1); // scroll down the list as new tweets are populated | |
| } | |
| } | |
| if (a.isDead()) deadAsteroids.add(a); | |
| // apply gravitational force to the asteroids and gun | |
| PVector aForce = a.repel(a); | |
| a.applyForce(aForce); | |
| PVector force = gun.attract(a); | |
| a.applyForce(force); | |
| a.update(); // update the asteroid | |
| a.display(); // draw the asteroid | |
| } // end of while loop | |
| if (deadAsteroids.size() > 0) asteroids.removeAll(deadAsteroids); | |
| if (deadBullets.size() > 0) activeBullets.removeAll(deadBullets); | |
| // this is actually where the on-screen asteroids are created | |
| // this method prevents concurrent modification/iteration | |
| if (tempAsteroids.size() > 0) { | |
| for (int i = 0; i < tempAsteroids.size(); i++) { | |
| Asteroid temp = tempAsteroids.get(i); // get the temp asteroid | |
| asteroids.add(new Asteroid(temp)); // create a new asteroid with the temporary asteroid's exact same properties | |
| tempAsteroids = new ArrayList<Asteroid>(); // clear the tempAsteroids pool since we've added them to the main asteroid pool | |
| } | |
| } | |
| } | |
| void checkCollision(Asteroid a, Bullet b) { | |
| if (dist(a.location.x, a.location.y, b.location.x, b.location.y) < a.w/2) { // works with an ellipse | |
| a.hit(true); // asteroid was hit | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class Bullet { | |
| PVector location; | |
| PVector velocity; | |
| float r; | |
| float speed; | |
| float dx, dy; | |
| Bullet(float lx, float ly, float angle) { | |
| speed = 5; | |
| // calculating angle of firing | |
| if (angle >= 0 && angle <= 90) { | |
| dx = map(angle, 0, 90, 0, 1); | |
| dy = map(angle, 0, 90, -1, 0); | |
| } | |
| else if (angle >= 90 && angle <= 180) { | |
| dx = map(angle, 90, 180, 1, 0); | |
| dy = map(angle, 90, 180, 0, 1); | |
| } | |
| else if (angle >= 180 && angle <= 270) { | |
| dx = map(angle, 180, 270, 0, -1); | |
| dy = map(angle, 180, 270, 1, 0); | |
| } | |
| else if (angle >= 270 && angle <= 360) { | |
| dx = map(angle, 270, 360, -1, 0); | |
| dy = map(angle, 270, 360, 0, -1); | |
| } | |
| location = new PVector(lx, ly); | |
| velocity = new PVector(dx * speed, dy * speed); | |
| r = 3; | |
| } | |
| void update() { | |
| location.add(velocity); | |
| } | |
| void display() { | |
| // Display circle at x location | |
| stroke(255); | |
| noFill(); | |
| ellipse(location.x, location.y, r*2, r*2); | |
| } | |
| boolean isOffScreen() { | |
| if (location.x+r < 0 || location.x+r > width | |
| || location.y+r < 0 || location.y+r > height) return true; | |
| else return false; | |
| } | |
| } | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class Gun { | |
| ArrayList<Bullet> bullets = new ArrayList<Bullet>(); | |
| PVector location; // current position on screen | |
| float x, y, w, h; | |
| float angle, a; | |
| float r; | |
| float mass; | |
| float amt; | |
| Gun(float x, float y) { | |
| this.x = x; | |
| this.y = y; | |
| location = new PVector(x, y); | |
| mass = 10; | |
| w = 10; | |
| h = 15; | |
| angle = 0; | |
| a = 0; | |
| amt = 1; | |
| } | |
| void rot(float a) { | |
| this.a += a; | |
| if (this.a > 360) this.a %= 360.; | |
| if (this.a < 0) this.a += 360.; | |
| } | |
| void moveX(float mx) { | |
| location.x += mx; | |
| } | |
| void moveY(float my) { | |
| location.y += my; | |
| } | |
| PVector attract(Asteroid a) { | |
| PVector force = PVector.sub(location, a.location); // Calculate direction of force | |
| float d = force.mag(); // Distance between objects | |
| d = constrain(d, 5.0, 25.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects | |
| force.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction) | |
| float strength = (g * mass * a.mass) / (d * d); // Calculate gravitional force magnitude | |
| force.mult(strength); // Get force vector --> magnitude * direction | |
| return force; | |
| } | |
| void update() { | |
| // update gun angle and all bullets | |
| r = radians(a)+radians(angle); | |
| for (Bullet b: bullets) { | |
| b.update(); | |
| } | |
| } | |
| void display() { | |
| noFill(); | |
| stroke(255); | |
| pushMatrix(); | |
| translate(location.x, location.y); | |
| rotate(r); | |
| triangle(0, -h/2, w/2, h/2, -w/2, h/2); | |
| popMatrix(); | |
| for (Bullet b: bullets) { | |
| b.display(); | |
| } | |
| } | |
| void fire() { | |
| bullets.add(new Bullet((location.x + (sin(r)*h/2)), (location.y + (cos(r)*-h/2)), (abs(a) % 360.))); | |
| } | |
| ArrayList<Bullet> getBullets() { | |
| return bullets; | |
| } | |
| PVector getLocation() { | |
| return location; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment