import ddf.minim.*;
/**
* Intermission: "Motes"
* Drag mouse to play with.
*
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;
PVector pm;
ArrayList motes;
PVector MIDDLE;
boolean inRadius(PVector a, PVector b, float rad)
{
return rad*rad > (a.x - b.x)*(a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}
class Mote
{
PVector pos;
PVector vel;
int h;
float speed;
Mote()
{
speed = 2;
pos = new PVector(random(width), random(height));
vel = new PVector(random(2)-1, random(2)-1);
vel.normalize();
vel.mult(speed);
h = (int)random(255);
}
void tick()
{
pos.add(vel);
/*
if(pos.x < 0) { pos.x = 0; vel.x = -vel.x;}
if(pos.x > width) { pos.x = width; vel.x = -vel.x;}
if(pos.y < 0) { pos.y = 0; vel.y = -vel.y;}
if(pos.y > height) { pos.y = height; vel.y = -vel.y;}
*/
float maxrad = width * 0.5;
if(PVector.dist(pos, MIDDLE) > maxrad)
{
PVector out = PVector.sub(pos, MIDDLE);
out.normalize();
pos = PVector.add(MIDDLE, PVector.mult(out, maxrad));
vel.sub(PVector.mult(proj(vel, out), 2));
}
h+=1;
h = h % 256;
}
}
void setup()
{
size(500, 500);
frameRate(600);
minim = new Minim(this);
motes = new ArrayList();
for(int i = 0; i < 200; i++)
{
motes.add(new Mote());
}
background(0);
pm = new PVector(mouseX, mouseY);
MIDDLE = new PVector(width/2, height/2);
}
void stop()
{
minim.stop();
super.stop();
}
void physicsStep()
{
for(int i = 0; i < motes.size(); i++)
{
Mote m =(Mote) motes.get(i);
for(int j = i+1; j < motes.size(); j++)
{
Mote n = (Mote)motes.get(j);
if(inRadius(m.pos, n.pos, 30))
{
PVector newv = PVector.add(m.vel, n.vel);
PVector mton = PVector.sub(n.pos, m.pos);
mton.normalize();
mton.mult(0.1);
newv.mult(0.25);
m.vel.add(newv);
n.vel.add(newv);
m.vel.sub(mton);
n.vel.add(mton);
m.vel.normalize();
n.vel.normalize();
m.speed = n.speed = (m.speed + n.speed)/2;
m.vel.mult(m.speed);
n.vel.mult(n.speed);
}
}
}
for(int i = 0; i < motes.size(); i++)
{
Mote m =(Mote) motes.get(i);
m.speed *= 0.997;
m.speed += 0.001;
PVector mvec = new PVector(mouseX, mouseY);
if(mousePressed && inRadius(m.pos, mvec, 100)) {
m.vel.x += (mouseX -pm.x) / (PVector.dist(m.pos, mvec) + 1);
m.vel.y += (mouseY -pm.y) / (PVector.dist(m.pos, mvec) + 1);
m.speed = m.vel.mag();
//PVector tomouse = PVector.sub(mvec, m.pos);
//tomouse.normalize();
//tomouse.mult(0.001);
//m.vel.add(tomouse);
//m.speed += 0.05;/// = m.vel.mag();
}
m.vel.normalize();
m.vel.mult(m.speed);
m.tick();
}
pm.x = mouseX;
pm.y = mouseY;
}
void drawingStep()
{
// background(0);
fill(0, 8);
rect(0, 0, width, height);
for(int i = 0; i < motes.size(); i++)
{
Mote m = (Mote)motes.get(i);
colorMode(HSB);
fill(m.h, 128, 255);
noStroke();
ellipse(m.pos.x, m.pos.y, m.speed*3 +1, m.speed*3 +3);
}
}
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");
}
void up(int theKey)
{
println(theKey + " up");
}