import ddf.minim.*;
/**
* Game 26: "Drawn Inward"
* avoid bluedots; touch bombdots
* arrows or wasd to move
* [attribution: guitar sample by casualdave]
*
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;
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;
PFont font;
boolean gameover;
AudioSample hitSound;
AudioSample bombSound;
AudioSample pointSound;
AudioPlayer bgm;
void audioInit()
{
minim = new Minim(this);
hitSound = minim.loadSample("hurt.wav", 1024);
bombSound = minim.loadSample("bomb.wav", 1024);
pointSound = minim.loadSample("point.wav", 1024);
bgm = minim.loadFile("vortex.mp3", 2048);
bgm.loop();
}
void audioClose()
{
minim.stop();
hitSound.close();
bombSound.close();
pointSound.close();
bgm.close();
}
PVector player_pos;
PVector player_vel;
float PLAYER_RADIUS = 16;
float PULL_DENOM_ADD = 300;
float PULL_MULT = 200;
float WORLD_DRAG = 0.96;
float BOMB_DRAG = 0.99;
float GRAVITY_MULT = 0.03;
float JIGGLE = 0.0;
GameList bg_points;
GameList gravity_stuff;
ParticleList particles;
float BG_SPRING_STR = 0.001;
float BG_DAMP_MULT = 0.99;
float BG_ATTRACT_MULT = 0.1;
PVector shock_pos;
float SHOCK_MAX = 1000;
float shock_radius = SHOCK_MAX;
float SHOCK_GROWTH = 5;
float SHOCK_DESTROY_RADIUS = 150;
int damage_timer;
int combo;
int score;
int topscore;
int p_frame;
float TARGET_RATE_BASE = 3;
float TARGET_RATE_INCREASE = 1 / 300;
void initGame()
{
bg_points = new GameList();
gravity_stuff = new GameList();
particles = new ParticleList();
for(int i = 0; i < 3000; i++)
bg_points.add(new BGDot());
player_pos = new PVector(width/2, height/2);
player_vel = new PVector(0, 0);
shock_pos = new PVector(width/2, height/2);
p_frame = 0;
damage_timer = 0;
score = 0;
combo = 0;
gameover = false;
title = false;
}
void setup()
{
size(600, 600, P2D);
frameRate(600);
audioInit();
font = loadFont("PressStartK-32.vlw");
initGame();
gameover = true;
title = true;
}
void stop()
{
audioClose();
super.stop();
}
void physicsStep()
{
topscore = max(topscore, score);
p_frame ++;
particles.tick();
if(damage_timer > 0 && p_frame % 4 == 0) damage_timer --;
//player_pos.x = mouseX;
//player_pos.y = mouseY;
float PV = 2.0;
PVector steer = new PVector(0, 0);
if(keys[LEFT] || keys['A']) steer.x -= PV;
if(keys[RIGHT] || keys['D']) steer.x += PV;
if(keys[UP] || keys['W']) steer.y -= PV;
if(keys[DOWN] || keys['S']) steer.y += PV;
steer.normalize();
steer.mult(PV);
if(!gameover) player_pos.add(steer);
bg_points.tick();
gravity_stuff.tick();
if(shock_radius < SHOCK_MAX) shock_radius += SHOCK_GROWTH;
if(!gameover)
{
float target_rate = TARGET_RATE_BASE + score * TARGET_RATE_INCREASE;
int rate_frames = (int)(PHYSICS_FPS / target_rate);
if(p_frame % rate_frames == 0)
{
gravity_stuff.add(new Target());
}
if(p_frame % (PHYSICS_FPS * 3) == 0)
gravity_stuff.add(new Bomb());
}
}
void drawingStep()
{
background(damage_timer, 0, 48);
if(shock_radius < SHOCK_DESTROY_RADIUS)
{
stroke(255, 255, 255);
fill(255, 128, 0, 255*(1 - (shock_radius / SHOCK_DESTROY_RADIUS)));
ellipse(shock_pos.x, shock_pos.y, shock_radius, shock_radius);
}
bg_points.draw();
gravity_stuff.draw();
fill(0);
noStroke();
stroke(random(192), random(192), 192);
ellipseMode(RADIUS);
if(!gameover) ellipse(player_pos.x, player_pos.y, PLAYER_RADIUS, PLAYER_RADIUS);
particles.draw();
fill(255, 96);
textAlign(LEFT, BOTTOM);
textFont(font, 8);
if(muted) text("mute", 8, height-8);
textAlign(LEFT, TOP);
textFont(font);
if(!gameover)
{
text(""+score, 8, 8);
if(topscore != score)
{
textFont(font, 8);
text("top: "+topscore, 8, 40);
}
}
else
{
fill(255);
textAlign(CENTER, CENTER);
textFont(font, 16);
if(title)text("DRAWN INWARD\n[press space]", width/2, height/2);
else text("GAME OVER\nscore: "+score+"\n[space to play again]", 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(!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;
if(theKey == ' ' && gameover) initGame();
}
void up(int theKey)
{
println(theKey + " up");
}