import ddf.minim.*; /** * Game 46: "Dessert Stressed"
* Drag and release the mouse to fire shots.
*
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; boolean game_over; int score; int top_score; GameList fireballs = new GameList(); GameList shots = new GameList(); ParticleList particles = new ParticleList(); PVector anchor; int fireball_timer; int charge_timer; int SHOT_COOLDOWN = 90; float SHOT_MINDIST = 60; int cooldown_timer; int score_timer; int SCORE_TIME = 30; int BURNT_TIME = 90; int burnt_timer; int phys_clock; void points(int pts) { score += pts; score_timer = max(score_timer, SCORE_TIME); } int difficulty_timer = 0; 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; int fireTime() { return PHYSICS_FPS * 10 / (5 + difficulty_timer / (PHYSICS_FPS * 15)); } AudioSample comboSound; AudioSample popSound; AudioSample shotSound; AudioSample burntSound; void audioInit() { minim = new Minim(this); comboSound = minim.loadSample("combo.wav", 1024); popSound = minim.loadSample("pop.wav", 1024); shotSound = minim.loadSample("shot.wav", 1024); shotSound.setGain(-10); burntSound = minim.loadSample("burnt.wav", 1024); } void audioClose() { comboSound.close(); popSound.close(); shotSound.close(); burntSound.close(); minim.stop(); } void setup() { size(720, 480); frameRate(600); audioInit(); info_font = loadFont("PressStartK-16.vlw"); setTitle(); } void setTitle() { title = true; game_over = true; } void newGame() { fireballs.clear(); cooldown_timer = 0; charge_timer = 0; fireball_timer = 0; difficulty_timer = 0; score_timer = 0; burnt_timer = 0; game_over = false; title = false; score = 0; } void stop() { audioClose(); super.stop(); } void mousePressed() { if(!paused && !title) { anchor = new PVector(mouseX, mouseY); } if(title) newGame(); } void mouseReleased() { if(!paused && !title && anchor != null && cooldown_timer <= 0) { PVector shotangle = new PVector(anchor.x - mouseX, anchor.y - mouseY); shotangle.normalize(); shotangle.mult(10); if(shotangle.mag() > 0 && PVector.dist(new PVector(mouseX, mouseY), anchor) > SHOT_MINDIST) { shots.add(new Coldshot(new PVector(mouseX, mouseY), shotangle)); cooldown_timer = SHOT_COOLDOWN; if(!muted) shotSound.trigger(); } } } void physicsStep() { phys_clock++; if(!title) { //main game loop fireballs.tick(); shots.tick(); particles.tick(); fireball_timer --; if(fireball_timer <= 0) { fireball_timer = fireTime(); fireballs.add(new Fireball()); } if(mousePressed) charge_timer++; else charge_timer = 0; cooldown_timer --; difficulty_timer++; if(score_timer > 0) score_timer--; burnt_timer--; top_score = max(score, top_score); } //jukebox stuff info_time --; } void drawingStep() { if(title) { drawTitle(); } else { background(32, 0, 64); ellipseMode(RADIUS); fill(0, 192, 255, 24); stroke(0, 192, 255, 48); strokeWeight(2); ellipse(width/2, height/2, DESSERT_RADIUS, DESSERT_RADIUS); fill(230, 250, 250); noStroke(); ellipse(width/2, height/2-18, 20, 20); fill(192, 128, 64); triangle(width/2 - 16, height/2 - 8, width/2 + 16, height/2 - 8, width/2, height/2 + 32); particles.draw(); fireballs.draw(); shots.draw(); smooth(); if(mousePressed && anchor != null) { noFill(); stroke(255, 128); if(PVector.dist(new PVector(mouseX, mouseY), anchor) > SHOT_MINDIST) stroke(96, 255, 255); strokeWeight(1); ellipse(anchor.x, anchor.y, 10, 10); PVector lead = new PVector(anchor.x - mouseX, anchor.y - mouseY); lead.normalize(); lead.mult(1000); lead.add(anchor); line(anchor.x, anchor.y, mouseX, mouseY); stroke(255, 32); if(PVector.dist(new PVector(mouseX, mouseY), anchor) > SHOT_MINDIST) stroke(96, 255, 255, 64); line(anchor.x, anchor.y, lead.x, lead.y); } else { noFill(); stroke(255, 128); strokeWeight(1); ellipse(mouseX, mouseY, 12, 12); } noSmooth(); if(burnt_timer > 0) { fill(255, 512*burnt_timer/BURNT_TIME, 255*burnt_timer/BURNT_TIME, 255*burnt_timer/BURNT_TIME); noStroke(); rectMode(CORNERS); rect(0, 0, width, height); } fill(255, 128 + 127* score_timer / SCORE_TIME); textAlign(RIGHT, TOP); textFont(info_font, 16 + 16 * score_timer / SCORE_TIME); text(score, width-8, 8); textFont(info_font, 8); fill(255, 128); text("top: "+top_score, width-8, 24); if(paused) drawPauseOverlay(); } //jukebox stuff drawSongInfo(); } void drawTitle() { background(200, 100, 70); fill(255); textFont(info_font, 32); textAlign(CENTER, CENTER); text("Dessert Stressed", width/2, height/2); textFont(info_font, 16); text("Use your chillshot to defend\nyour ice cream from fireballs.", width/2, height*2/3); } void drawPauseOverlay() { rectMode(CORNER); strokeWeight(1); noStroke(); fill(0, 128); rect(0, 0, width, height); fill(255); textFont(info_font, 16); textAlign(CENTER, CENTER); text("[ PAUSED ]", width/2, height/2); } 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(keyCode < 256) if(!keys[keyCode]) { keys[keyCode] = true; down(keyCode); } } void keyReleased() { if(keyCode < 256) if(keys[keyCode]) { keys[keyCode] = false; up(keyCode); } } void down(int theKey) { println(theKey + " down"); if(theKey == 'M') jbToggleMute(); if(theKey == 'P' && !title) paused = !paused; if(theKey == ENTER && game_over) newGame(); } void up(int theKey) { println(theKey + " up"); }