import ddf.minim.*; /** * Game 27: "now sir, a war is never even. sir, a war is won"
* Move the green dot above the red dots.
*
Go play more games at NMcCoy.net!
* Creative Commons License
This work by Nathan McCoy is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License. */ boolean[] keys = new boolean[256]; boolean title; boolean paused; boolean muted; int drawing_ms_last; int physics_ms_last; int CORE_FPS = 540; int DRAWING_FPS = 60; int PHYSICS_FPS = 180; int DRAW_MS = 1000 / DRAWING_FPS; int PHYS_MS = 1000 / PHYSICS_FPS; Minim minim; float WHEEL_RADIUS = 70; float GRAVITY = 0.1; PVector pivot; float inertia; float torque; float omega; PFont font; Dot greendot; boolean game_done; int score; int topscore; int penalty; ArrayList all_dots; ArrayList grabbed_dots; AudioPlayer bgm; void audioInit() { minim = new Minim(this); bgm = minim.loadFile("uneven.mp3", 2048); bgm.loop(); } void audioClose() { bgm.close(); minim.stop(); } void setup() { size(550, 550); frameRate(600); audioInit(); font = loadFont("PressStartK-32.vlw"); newGame(); } void newGame() { all_dots = new ArrayList(); int NUM_DOTS = 20; for(int i = 0; i < NUM_DOTS; i++) all_dots.add(new Dot(random(width), i*height/NUM_DOTS, random(3)+5, color(255, 0, 0))); greendot = new Dot(width/2, height-20, 5, color(0, 255, 0)); all_dots.add(greendot); grabbed_dots = new ArrayList(); game_done = false; score = 0; penalty = 0; } void stop() { audioClose(); super.stop(); } void mousePressed() { if(game_done) newGame(); else { pivot = new PVector(mouseX, mouseY); grabbed_dots.clear(); inertia = 0; omega = 0; Iterator adi = all_dots.iterator(); while(adi.hasNext()) { Dot d = (Dot)adi.next(); if(inRadius(pivot, d.pos, WHEEL_RADIUS) && d.pos.y <= greendot.pos.y) { grabbed_dots.add(d); float r = d.pos.dist(pivot); inertia += r*r*d.mass; } } } } void mouseReleased() { grabbed_dots.clear(); } void physicsStep() { if(!grabbed_dots.isEmpty() && !game_done) { penalty++; torque = 0; for(int i = 0; i < grabbed_dots.size(); i++) { Dot d = (Dot) grabbed_dots.get(i); torque += (d.pos.x - pivot.x)*d.mass*GRAVITY; } omega += torque/inertia; for(int i = 0; i < grabbed_dots.size(); i++) { Dot d = (Dot) grabbed_dots.get(i); d.pos.sub(pivot); //translate so we can do math relative to origin float nx = d.pos.x*cos(omega)-d.pos.y*sin(omega); float ny = d.pos.x*sin(omega)+d.pos.y*cos(omega); d.pos.x = nx; d.pos.y = ny; d.pos.add(pivot); //and move it back. } } score = 0; boolean allbelow = true; for(int i = 0; i < all_dots.size(); i++) { Dot d = (Dot) all_dots.get(i); if(d.pos.y > greendot.pos.y) score += (int)(height - d.pos.y); else if(d != greendot) allbelow = false; } score -= penalty; if(allbelow) game_done = true; //score += (int)(height - greendot.pos.y); topscore = max(score, topscore); } void drawingStep() { background(32,64, 96); strokeWeight(1); noFill(); ellipseMode(RADIUS); stroke(0, 128, 0); line(0, greendot.pos.y, width, greendot.pos.y); stroke(128); if(!grabbed_dots.isEmpty()) { stroke(255); ellipse(pivot.x, pivot.y, WHEEL_RADIUS, WHEEL_RADIUS); ellipse(pivot.x, pivot.y, 2, 2); for(int i = 0; i < grabbed_dots.size(); i++) { Dot d = (Dot) grabbed_dots.get(i); line(pivot.x, pivot.y, d.pos.x, d.pos.y); } fill(0, 128, 255); textFont(font, 8); textAlign(CENTER, BOTTOM); text("-"+penalty, pivot.x, pivot.y - 3); } else { ellipse(mouseX, mouseY, WHEEL_RADIUS, WHEEL_RADIUS); fill(128); textFont(font, 8); textAlign(CENTER, BOTTOM); text("-"+penalty, mouseX, mouseY - 3); } for(int i = 0; i < all_dots.size(); i++) { Dot d = (Dot) all_dots.get(i); fill(d.col); noStroke(); if(d.pos.y > greendot.pos.y) { fill(255, 192, 0); textFont(font, 8); textAlign(CENTER, BOTTOM); text("+"+(int)(height-d.pos.y), d.pos.x, d.pos.y - 6); fill(160, 0, 0); } ellipse(d.pos.x, d.pos.y, d.mass, d.mass); } textFont(font); fill(255, 128); if(game_done) fill(255, 234, 128); textAlign(LEFT, TOP); text(""+score, 8, 8); textFont(font, 16); textAlign(RIGHT, TOP); text("top: "+topscore, width-8, 8); } void draw() { cursor(CROSS); while(physics_ms_last + PHYS_MS < millis()) { if(!paused) { physicsStep(); } physics_ms_last += PHYS_MS; } if(drawing_ms_last + DRAW_MS < millis()) { drawingStep(); drawing_ms_last = millis(); } } void keyPressed() { if(!keys[keyCode]) { keys[keyCode] = true; down(keyCode); } } void keyReleased() { if(keys[keyCode]) { keys[keyCode] = false; up(keyCode); } } void down(int theKey) { println(theKey + " down"); if(theKey == 'M') { muted = !muted; if(muted) bgm.mute(); else bgm.unmute(); } //if(theKey == 'P' && !title) paused = !paused; } void up(int theKey) { println(theKey + " up"); }