import ddf.minim.*;
boolean cheat = true;
/**
* Game LD20: "It's dangerous to go alone! Take this!"
* Enter = Start, Z = Jump/Airdash, X = Attack/Charge Attack
*
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 title;
boolean paused;
boolean muted;
boolean game_over;
boolean onward;
boolean victory;
int score;
int fake_score;
int FAKE_SCORE_SPEED=10;
int top_score;
int time;
int GAME_TIME = 600;
int phys_frame;
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 WEAPON_BONUS = 1000;
float GROUND_LEVEL = 340;
float GLOBAL_GRAVITY = 0.08;
float GLOBAL_JUMP_GRAVITY = 0.06;
float GLOBAL_DASH_GRAVITY = 0.02;
float GLOBAL_JUMP_SPEED = 3; //velocity to rise or fall at when jumping
float GLOBAL_X_SPEED = 2; //ideal horizontal speed when moving
float GLOBAL_AIR_CONTROL = 0.14; //x-accel to x_wish*s_speed in the air
float GLOBAL_GROUND_CONTROL = 0.17; //x-accel to x_wish*s_speed on the ground
float GLOBAL_DASH_KICK = 5.5;
float GLOBAL_DASH_DRAG = 0.03;
float GLOBAL_DASH_BUMP = -0.7;
float GLOBAL_AIR_JUMP = 2;
int GLOBAL_JUMP_TIME = 25; //maximum frames spendable in rising jump state
int GLOBAL_DASH_TIME = 50; //length of a dash, including cooldown
int DASH_LINGER = -10;
int GLOBAL_STUN = 120;
int COMBO_TIME = 20;
int continuer=0;
AudioSample hop_sound;
AudioSample hop2_sound;
AudioSample dash_sound;
AudioSample land_sound;
AudioSample stick_sound;
AudioSample charge_sound;
AudioSample super_sound;
AudioSample get_sound;
AudioSample hit_sound;
AudioSample die_sound;
AudioSample knife_sound;
AudioSample coin_sound;
AudioSample club_sound;
AudioSample heart_sound;
AudioSample ghost_sound;
AudioSample love_sound;
void audioInit()
{
int buffer = 1024;
minim = new Minim(this);
hop_sound = minim.loadSample("hop.wav", buffer);
hop_sound.setGain(-7);
hop2_sound = minim.loadSample("hop2.wav", buffer);
hop2_sound.setGain(-7);
dash_sound = minim.loadSample("dash.wav", buffer);
dash_sound.setGain(-5);
land_sound = minim.loadSample("land.wav", buffer);
land_sound.setGain(-15);
stick_sound = minim.loadSample("stick.wav", buffer);
stick_sound.setGain(-3);
knife_sound = minim.loadSample("knife.wav", buffer);
knife_sound.setGain(-3);
charge_sound = minim.loadSample("charge.wav", buffer);
charge_sound.setGain(-7);
super_sound = minim.loadSample("super.wav", buffer);
super_sound.setGain(-12);
get_sound = minim.loadSample("ringywhoosh.wav", buffer);
get_sound.setGain(-7);
hit_sound = minim.loadSample("hit.wav", buffer);
hit_sound.setGain(-5);
die_sound = minim.loadSample("die3.wav", buffer);
die_sound.setGain(-5);
coin_sound = minim.loadSample("coin.wav", buffer);
club_sound = minim.loadSample("club.wav", buffer);
heart_sound = minim.loadSample("heart.wav", buffer);
heart_sound.setGain(-5);
ghost_sound = minim.loadSample("ghost.wav", buffer);
love_sound = minim.loadSample("love.wav", buffer);
love_sound.setGain(-10);
}
void audioClose()
{
hop_sound.close();
hop2_sound.close();
dash_sound.close();
land_sound.close();
stick_sound.close();
charge_sound.close();
super_sound.close();
get_sound.close();
hit_sound.close();
die_sound.close();
knife_sound.close();
coin_sound.close();
club_sound.close();
heart_sound.close();
ghost_sound.close();
love_sound.close();
minim.stop();
}
Critter pc;
GameList creatures;
GameList loot;
GameList scenery;
ParticleList particles;
int level;
void setup()
{
size(720, 480);
frameRate(600);
audioInit();
info_font = loadFont("PressStartK-16.vlw");
setTitle();
}
void setTitle()
{
title = true;
game_over = true;
}
void newGame()
{
newGame(0);
}
boolean continued;
void newGame(int lev)
{
game_over = false;
title = false;
score = 0;
fake_score = 0;
level = lev;
pc = new Kobold(new PVector(width/4, height/2));
creatures = new GameList();
loot = new GameList();
scenery = new GameList();
particles = new ParticleList();
continued = false;
loadScreen(lev);
if(lev > 0)
{
pc.weapon=new Stick();
continued = true;
}
}
void stop()
{
audioClose();
super.stop();
}
void physicsStep()
{
if(!title)
{
if(fake_score < score) fake_score += FAKE_SCORE_SPEED;
if(fake_score > score) fake_score = score;
//main game loop
pc.x_wish=0;
if(keys[LEFT])pc.x_wish -= 1;
if(keys[RIGHT])pc.x_wish += 1;
pc.jump_button = keys['Z'];
pc.attack_button = keys['X'];
creatures.tick();
particles.tick();
loot.tick();
scenery.tick();
if(onward) {level++;
loadScreen(level);}
phys_frame++;
if(time > 0)
{
if(phys_frame%PHYSICS_FPS == 0 && pc.hp > 0 && !victory) time--;
}
if(pc.removal_flag) game_over = true;
top_score = max(score, top_score);
}
//jukebox stuff
info_time --;
}
void drawingStep()
{
if(title)
{
drawTitle();
}
else
{
background(0,140,192);
scenery.draw();
strokeWeight(2);
//fill(114,200, 101);
fill(80,180, 60);
//stroke(166,255,136);
stroke(140,220, 100);
rectMode(CORNERS);
rect(-5, GROUND_LEVEL, width+5, height+5);
creatures.draw();
loot.draw();
particles.draw();
if(creatures.size() == 1 && pc.hp > 0) drawAnnoyer();
drawHUD();
if(paused) drawPauseOverlay();
if(game_over)
{
rectMode(CORNER);
strokeWeight(1);
noStroke();
fill(128, 0, 0, 64);
rect(0, 0, width, height);
fill(255);
textFont(info_font, 16);
textAlign(CENTER, CENTER);
text("GAME OVER", width/2, height/2);
textFont(info_font, 8);
fill(pc.fill_color);
text("Press enter to try again? <3", width/2, height*3/5);
}
}
//jukebox stuff
drawSongInfo();
}
void achievement(String name, int bonus)
{
particles.add(new DramaticAnnouncement(PV(width/2, height/2), name+": +"+bonus));
score += bonus;
}
void drawAnnoyer()
{
int pulsar = phys_frame%81;
pulsar *= 3;
fill(255, 400-pulsar, 180-pulsar);
textFont(info_font, 32);
textAlign(RIGHT, CENTER);
text("GO>", width-8, height/2-16);
textFont(info_font, 16);
text("ALONE ", width-8, height/2+8);
}
void drawHUD()
{
textFont(info_font, 16);
textAlign(LEFT, TOP);
fill(255);
text("KOBOLD x", 8, 8);
text("Has "+pc.weapon.name+"!", 8, 26);
fill(255, 160, 192);
if(!pc.removal_flag) text("<3", 153, 8);
fill(255);
textAlign(RIGHT, TOP);
text("SCORE", width-8, 8);
text(""+fake_score, width-8, 26);
textAlign(CENTER, TOP);
if(time > -1)
{
text("TIME", width/2, 8);
text(""+time, width/2, 26);
}
if(level > 0)
{
textAlign(LEFT, BOTTOM);
if(level > 16)
text("Area "+(16-level), 32, height-32);
else text("Area "+level, 32, height-32);
}
if(victory)
{
textAlign(CENTER, CENTER);
text("CONGRATULATIONS!\nTime Bonus: "+time+" x 25\nFinal Score: "+fake_score, width/2, height/3);
}
}
void drawTitle()
{
background(80,180, 60);
fill(255);
textFont(info_font, 32);
textAlign(CENTER, CENTER);
text("Kobold Goes Alone", width/2, height/2);
textFont(info_font, 16);
text("a Dragondot adventure\nby Nathan McCoy", width/2, height*2/3);
if(top_score > 0)
text("TOP SCORE: "+top_score+"\npress ENTER for new game or C to continue", width/2, height*3/4);
}
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 && !game_over) paused = !paused;
if(theKey == ENTER && title) newGame();
if(theKey == 'C' && title) newGame(continuer);
else if(theKey == ENTER && game_over) setTitle();
if(theKey == '=' && cheat) onward=true;
if(theKey == '-' && cheat)
{
for(Object o:creatures)
{
if(o != pc)
{
Critter c= (Critter)o;
c.hp = 0;
}
}
}
}
void up(int theKey)
{
println(theKey + " up");
}