import ddf.minim.*;
/**
* Game 24: "add special instructions"
*
*
Go play more games at NMcCoy.net!
* 
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[] key_mask = 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;
int phys_frame;
Minim minim;
float PLAYER_RADIUS = 8;
float PLAYER_SPEED = 1;
float PLAYER_SHOT_SPEED = 2;
float ENEMY_SPEED = 0.8;
int ENEMY_SWERVE_TIME = 180;
float SCROLL_RATE = 0.4;
int ENEMIES_PER_DROP = 4;
int ENEMY_SHOOT_RATE = 200;
int TURRET_SHOOT_RATE = 80;
float ENEMY_SHOT_SPEED = 1.0;
int FADE_TIME = 60;
PVector player_pos;
int fade_timer;
int level_goal;
int COLLECT = 0;
int DESTROY = 1;
int level_target;
int goal_progress;
int level;
boolean success = true;
String instructions;
GameList enemy_shots;
GameList player_shots;
GameList targets;
float player_phase;
PFont font;
AudioSample levelSound;
AudioSample getSound;
AudioSample failSound;
AudioSample shootSound;
AudioSample killSound;
AudioPlayer music;
void audioInit()
{
minim = new Minim(this);
levelSound = minim.loadSample("levelup.wav", 1024);
getSound = minim.loadSample("pickup.wav", 1024);
failSound = minim.loadSample("fail.wav", 1024);
shootSound = minim.loadSample("shoot.wav", 1024);
killSound = minim.loadSample("kill.wav", 1024);
music = minim.loadFile("addition.mp3", 2048);
music.loop();
}
void audioClose()
{
levelSound.close();
getSound.close();
failSound.close();
shootSound.close();
killSound.close();
music.close();
minim.stop();
}
void setup()
{
ellipseMode(RADIUS);
rectMode(RADIUS);
size(720, 480);
frameRate(600);
audioInit();
phys_frame = 0;
loadLevel(0);
font = loadFont("PressStartK-16.vlw");
}
int misc_counter;
float ground_wander;
void loadLevel(int lev)
{
misc_counter = 0;
level = lev;
enemy_shots = new GameList();
player_shots = new GameList();
targets = new GameList();
goal_progress = 0;
fade_timer = FADE_TIME;
if(lev == 0)
{
key_mask = new boolean[256];
key_mask['D'] = true;
key_mask['P'] = true;
key_mask['M'] = true;
instructions = "Pause: P\nMute: M\nMove Right: D";
player_pos = new PVector(128, height-64);
level_goal = COLLECT;
level_target = 1;
enemy_shots.add(new Pickup(new PVector(width-128, height-64)));
}
if(lev == 1)
{
key_mask['A'] = true;
instructions = "Pause: P\nMute: M\nMove Right: D\nMove Left: A";
level_goal = COLLECT;
level_target = 5;
player_pos = new PVector(width-128, height-64);
}
if(lev == 2)
{
key_mask['F'] = true;
instructions = "Pause: P\nMute: M\nMove Right: D\nMove Left: A\nFail: F";
level_goal = COLLECT;
level_target = 5;
player_pos = new PVector(width/2, height-64);
for(int i = 0; i < 5; i++)
{
enemy_shots.add(new Pickup(new PVector(width/2, 8), new PVector((random(2)-1)*0.3/(i+1), 0.8+0.3*i)));
}
}
if(lev == 3)
{
key_mask['W'] = true;
instructions = "Pause: P\nMute: M\nMove Right: D\nMove Left: A\nFail: F\nMove Up: W";
level_goal = COLLECT;
level_target = 1;
player_pos = new PVector(width/2, height-8);
enemy_shots.add(new Pickup(new PVector(width/2, 8)));
}
if(lev == 4)
{
key_mask['S'] = true;
instructions = "Pause: P\nMute: M\nMove Right: D\nMove Left: A\nFail: F\nMove Up: W\nMove Down: S";
level_goal = COLLECT;
level_target = 5;
player_pos = new PVector(width/2, 8);
for(int i = 0; i < 5; i++)
enemy_shots.add(new Pickup(new PVector(random(width), random(height-24)+24)));
for(int i = 0; i < 70; i++)
enemy_shots.add(new BadShot(new PVector(random(width), random(height-24)+24)));
}
if(lev == 5)
{
key_mask['L'] = true;
instructions = "Pause: P\nMute: M\nMove Right: D\nMove Left: A\nFail: F\nMove Up: W\nMove Down: S\nShoot Right: L";
level_goal = COLLECT;
level_target = 5;
player_pos = new PVector(64, height/2);
}
if(lev == 6)
{
key_mask['K'] = true;
instructions = "Pause: P\nMute: M\nMove Right: D\nMove Left: A\nFail: F\nMove Up: W\nMove Down: S\nShoot Right: L\nShoot Down: K";
level_goal = COLLECT;
level_target = 5;
player_pos = new PVector(64, height/2);
ground_wander = height;
}
if(lev == 7)
{
key_mask['J'] = true;
instructions = "Pause: P\nMute: M\nMove Right: D\nMove Left: A\nFail: F\nMove Up: W\nMove Down: S\nShoot Right: L\nShoot Down: K\nShoot Left: J";
level_goal = COLLECT;
level_target = 9;
player_pos = new PVector(width/2, 64);
ground_wander = height;
for(int i = 0; i < 3; i++)
{
float xo = width/4 * (i+1);
targets.add(new Enemy(new PVector(xo-32, height-32)));
targets.add(new Enemy(new PVector(xo-16, height-32)));
targets.add(new Enemy(new PVector(xo+16, height-32)));
targets.add(new Enemy(new PVector(xo+32, height-32)));
targets.add(new Enemy(new PVector(xo-32, height-48)));
targets.add(new Enemy(new PVector(xo-16, height-48)));
targets.add(new Enemy(new PVector(xo, height-48)));
targets.add(new Enemy(new PVector(xo+16, height-48)));
targets.add(new Enemy(new PVector(xo+32, height-48)));
targets.add(new Enemy(new PVector(xo-16, height-64)));
targets.add(new Enemy(new PVector(xo, height-64)));
targets.add(new Enemy(new PVector(xo+16, height-64)));
targets.add(new Turret(new PVector(xo, height+4)));
}
}
if(lev == 8)
{
key_mask['I'] = true;
instructions = "Pause: P\nMute: M\nMove Right: D\nMove Left: A\nFail: F\nMove Up: W\nMove Down: S\nShoot Right: L\nShoot Down: K\nShoot Left: J\nShoot Up: I";
level_goal = COLLECT;
level_target = 5;
player_pos = new PVector(width/2, height/2);
}
if(lev == 9)
{
key_mask['V'] = true;
instructions = "Pause: P\nMute: M\nMove Right: D\nMove Left: A\nFail: F\nMove Up: W\nMove Down: S\nShoot Right: L\nShoot Down: K\nShoot Left: J\nShoot Up: I\nVictory: V";
level_goal = COLLECT;
level_target = 1;
player_pos = new PVector(width/2, height/2);
}
if(lev == 10)
{
key_mask['R'] = true;
instructions = "Pause: P\nMute: M\nMove Right: D\nMove Left: A\nFail: F\nMove Up: W\nMove Down: S\nShoot Right: L\nShoot Down: K\nShoot Left: J\nShoot Up: I\nVictory: V\nReplay: R";
level_goal = COLLECT;
level_target = 1;
player_pos = new PVector(width/2, height/2);
}
}
void killPlayer()
{
if(!muted) failSound.trigger();
success = false;
loadLevel(level);
}
void stop()
{
audioClose();
super.stop();
}
void physicsStep()
{
phys_frame++;
player_phase += random(1);
fade_timer--;
enemy_shots.tick();
player_shots.tick();
targets.tick();
if(keys['D']) player_pos.x += PLAYER_SPEED;
if(keys['A']) player_pos.x -= PLAYER_SPEED;
if(keys['W']) player_pos.y -= PLAYER_SPEED;
if(keys['S']) player_pos.y += PLAYER_SPEED;
if(player_pos.x < 0 + PLAYER_RADIUS) player_pos.x = 0 + PLAYER_RADIUS;
if(player_pos.x > width - PLAYER_RADIUS) player_pos.x = width - PLAYER_RADIUS;
if(player_pos.y < 0 + PLAYER_RADIUS) player_pos.y = 0 + PLAYER_RADIUS;
if(player_pos.y > height - PLAYER_RADIUS) player_pos.y = height - PLAYER_RADIUS;
if(level == 1)
{
if(phys_frame%40 == 0)
{
misc_counter++;
if(misc_counter % 8 == 0) enemy_shots.add(new Pickup(new PVector(width*3/4-random(width/2), 0), new PVector(0, 0.7)));
else enemy_shots.add(new BadShot(new PVector(width*3/4-random(width/2), 0), new PVector(0, 0.7)));
}
}
if(level == 2)
{
// if(phys_frame%60 == 0)
// {
// misc_counter++;
// if(misc_counter <= 5) enemy_shots.add(new Pickup(new PVector(width/2 -(random(1)-0.5)*100, 0), new PVector(0, 1.5)));
// //else enemy_shots.add(new BadShot(new PVector(width*3/4-random(width/2), 0), new PVector(0, 0.7)));
// }
}
if(level == 3)
{
if(phys_frame%15 == 0)
{
misc_counter++;
if(misc_counter%2 == 0) enemy_shots.add(new BadShot(new PVector(0, random(height)), new PVector(random(3),0)));
else enemy_shots.add(new BadShot(new PVector(width, random(height)), new PVector(-random(3),0)));
//else enemy_shots.add(new BadShot(new PVector(width*3/4-random(width/2), 0), new PVector(0, 0.7)));
}
}
if(level == 5)
{
if(phys_frame % 120 == 0)
{
targets.add(new MobileEnemy(new PVector(width, random(height))));
}
Iterator ei = targets.iterator();
while(ei.hasNext())
{
GameObject g = (GameObject) ei.next();
g.pos.x -= SCROLL_RATE;
}
ei = enemy_shots.iterator();
while(ei.hasNext())
{
GameObject g = (GameObject) ei.next();
g.pos.x -= SCROLL_RATE;
}
}
if(level == 6)
{
if(phys_frame % 810 == 0)
{
targets.add(new MobileEnemy(new PVector(width, random(height))));
}
if(phys_frame % 30 == 0)
{
ground_wander += random(20) - 10;
if(ground_wander > height) ground_wander = height;
if(ground_wander < height/2) ground_wander = height/2;
enemy_shots.add(new BadShot(new PVector(width, ground_wander)));
}
if(phys_frame % 240 == 0)
{
targets.add(new Enemy(new PVector(width, ground_wander-14)));
}
Iterator ei = targets.iterator();
while(ei.hasNext())
{
GameObject g = (GameObject) ei.next();
g.pos.x -= SCROLL_RATE;
}
ei = enemy_shots.iterator();
while(ei.hasNext())
{
GameObject g = (GameObject) ei.next();
g.pos.x -= SCROLL_RATE;
}
}
if(level == 8)
{
if(phys_frame % 60 == 0)
{
int wall = (int)random(4);
if(wall == 0)
targets.add(new Asteroid(new PVector(0, random(height))));
if(wall == 1)
targets.add(new Asteroid(new PVector(width, random(height))));
if(wall == 2)
targets.add(new Asteroid(new PVector(random(width), 0)));
if(wall == 3)
targets.add(new Asteroid(new PVector(random(width), height)));
}
}
if(level == 9)
{
if(phys_frame % 15 == 0)
{
PVector offset = randomVector(150);
enemy_shots.add(new BadShot(PVector.add(player_pos, offset), PVector.mult(offset, -0.005)));
}
}
if(goal_progress >= level_target && level != 10)
{
if(!muted) levelSound.trigger();
success = true;
loadLevel(level+1);
}
}
void drawingStep()
{
background(235);
textFont(font, 8);
fill(190);
textAlign(LEFT, TOP);
text("add special instructions\n\n"+instructions, 8, 8);
if(level == 10)
{
textAlign(CENTER, CENTER);
text("add special congratulations\n\n(p.s.: you're awesome)", width/2, height/2 - 64);
}
textFont(font, 16);
//if(level_goal == COLLECT) fill(190, 210, 170);
//else fill(210, 190, 170);
textAlign(RIGHT, TOP);
if(level != 10) text(""+goal_progress+"/"+level_target, width-8, 8);
enemy_shots.draw();
player_shots.draw();
targets.draw();
fill(0, 128+64*sin(player_phase*0.1), 255);
noStroke();
rect(player_pos.x, player_pos.y, PLAYER_RADIUS, PLAYER_RADIUS);
if(fade_timer > 0)
{
if(success)
fill(255, 255*fade_timer/FADE_TIME);
else
fill(255, 0, 0, 255*fade_timer/FADE_TIME);
rectMode(CORNER);
noStroke();
strokeWeight(1);
rect(0, 0, width, height);
rectMode(RADIUS);
}
}
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(key_mask[keyCode])
if(!keys[keyCode])
{
keys[keyCode] = true;
down(keyCode);
}
}
void keyReleased()
{
if(key_mask[keyCode])
if(keys[keyCode])
{
keys[keyCode] = false;
up(keyCode);
}
}
void down(int theKey)
{
println(theKey + " down");
if(theKey == 'M')
{
muted = !muted;
if(muted) music.mute(); else music.unmute();
}
if(theKey == 'P' && !title) paused = !paused;
if(theKey == 'F' && !paused) killPlayer();
if(theKey == 'L' && !paused)
{
player_shots.add(new PShot(player_pos, new PVector(PLAYER_SHOT_SPEED, 0)));
if(!muted) shootSound.trigger();
}
if(theKey == 'J' && !paused)
{
player_shots.add(new PShot(player_pos, new PVector(-PLAYER_SHOT_SPEED, 0)));
if(!muted) shootSound.trigger();
}
if(theKey == 'K' && !paused)
{
player_shots.add(new PShot(player_pos, new PVector(0, PLAYER_SHOT_SPEED)));
if(!muted) shootSound.trigger();
}
if(theKey == 'I' && !paused)
{
player_shots.add(new PShot(player_pos, new PVector(0, -PLAYER_SHOT_SPEED)));
if(!muted) shootSound.trigger();
}
if(theKey == 'V' && !paused)
{
goal_progress = level_target;
}
if(theKey == 'R' && !paused)
{
loadLevel(0);
}
}
void up(int theKey)
{
println(theKey + " up");
}