import ddf.minim.*; /** * Friday Prototype: "Energy Combo"
*
*
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; 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; AudioSample lightAttack; AudioSample heavyAttack; AudioSample readySound; AudioSample hitSound; PVector avatar; void audioInit() { minim = new Minim(this); lightAttack = minim.loadSample("light.wav", 1024); heavyAttack = minim.loadSample("heavy.wav", 1024); hitSound = minim.loadSample("hit.wav", 1024); readySound = minim.loadSample("ready.wav", 1024); } void audioClose() { lightAttack.close(); heavyAttack.close(); readySound.close(); hitSound.close(); minim.stop(); } float energy = 1; boolean exhausted = false; int DOTS = 10; float RECHARGE_RATE = 1.0; float ATTACK_COST = 0.29; float ATTACK_DELAY = 0.4; float delay_timer = 0; float avspeed = 0.7; GameList foes = new GameList(); ParticleList parts = new ParticleList(); void setup() { size(720, 480); frameRate(600); audioInit(); info_font = loadFont("PressStartK-16.vlw"); setTitle(); avatar = new PVector(width/2, height/2); } void setTitle() { title = true; game_over = true; } void newGame() { game_over = false; title = false; score = 0; } void stop() { audioClose(); super.stop(); } void tryAttack() { if(!exhausted) { energy -= ATTACK_COST; if(energy <= 0) { exhausted = true; finishAttack(); } else normalAttack(); } } void hit(float rad, int dmg) { parts.add(new Flash(avatar, rad)); for(int i = 0; i < foes.size(); i++) { Foe f = (Foe) foes.get(i); if(PVector.dist(f.pos, avatar) < rad + f.radius) { PVector away = PVector.sub(f.pos, avatar); away.normalize(); away.mult(5 * dmg); f.pos.add(away); f.harm(dmg); } } } void normalAttack() { lightAttack.trigger(); delay_timer = ATTACK_DELAY; hit(15, 1); } void finishAttack() { heavyAttack.trigger(); delay_timer = ATTACK_DELAY; hit(26, 2); } void physicsStep() { if(!title) { //main game loop delay_timer -= 1.0/PHYSICS_FPS; if(delay_timer <= 0) energy += RECHARGE_RATE/PHYSICS_FPS; if(energy >= 1.0) { energy = 1.0; if(exhausted) readySound.trigger(); exhausted = false; } foes.tick(); parts.tick(); if(keys[UP]) avatar.y -= avspeed; if(keys[DOWN]) avatar.y += avspeed; if(keys[LEFT]) avatar.x -= avspeed; if(keys[RIGHT]) avatar.x += avspeed; top_score = max(score, top_score); } //jukebox stuff info_time --; } void drawingStep() { if(title) { drawTitle(); } else { background(32,64,96); ellipseMode(RADIUS); if(paused) drawPauseOverlay(); fill(120, 230, 230); stroke(100, 255, 200); ellipse(avatar.x, avatar.y, 6, 6); foes.draw(); parts.draw(); String energy_stars = ""; textAlign(LEFT, BOTTOM); for(int i = 0; i < DOTS; i++) { energy_stars += "*"; } if(exhausted) fill(0, 0, 64); else fill(128, 64, 32); noStroke(); text(energy_stars, 8, height-8); energy_stars = ""; for(int i = 0; i < int(DOTS * energy); i++) { energy_stars += "*"; } if(exhausted) fill(128,64,128); else if(delay_timer > 0) fill(255, 192, 0); else fill(255, 255, 128); text(energy_stars, 8, height-8); fill(192); textAlign(LEFT, TOP); text("[Q/W] Recharge rate: "+RECHARGE_RATE+"\n[E/R] Attack cost: "+ATTACK_COST+"\n[T/Y] Attack delay: "+ATTACK_DELAY, 8, 8); } //jukebox stuff drawSongInfo(); } void drawTitle() { background(128, 0, 128); fill(255); textFont(info_font, 32); textAlign(CENTER, CENTER); text("Energy Combo Prototype", width/2, height/2); textFont(info_font, 16); text("x to attack, arrows to move\ns to spawn small foe, b to spawn big foe\npress enter", 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() { 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(!paused && !title) { if(theKey == 'X') tryAttack(); if(theKey == 'S') foes.add(new Foe()); if(theKey == 'B') foes.add(new BigFoe()); if(theKey == 'Q') RECHARGE_RATE -= 0.1; if(theKey == 'W') RECHARGE_RATE += 0.1; if(theKey == 'E') ATTACK_COST -= 0.1; if(theKey == 'R') ATTACK_COST += 0.1; if(theKey == 'T') ATTACK_DELAY -= 0.1; if(theKey == 'Y') ATTACK_DELAY += 0.1; } if(theKey == ENTER && game_over) newGame(); } void up(int theKey) { println(theKey + " up"); }