For my final project, I create a particle game in which the player attempts to avoid an increasing amount of particles which follow the cursor. The circular cursor is controlled by the mouse and is the direction in which all the particles move individually towards. A timer tracks the number of red particles on the screen and acts as a scoreboard which halts when the cursor makes contact with a particle. This game is based off one of my favorite iPhone apps which I discuss in my project priors and precursors.
The main source code comes from the Flock Particle Mutual Interactions example from our class notes. Overall, I was able to execute my original proposal. There were some features that I found worked better than others which was the main difference between my proposal and my final project.
//Kyle Lee
//Section C
//kdlee@andrew.cmu.edu
//Final Project
function particleUpdate() {
if (this.bFixed == false) {
this.vx *= this.damping;
this.vy *= this.damping;
this.px += this.vx;
this.py += this.vy;
}
if (this.px + particleDiameter/2 > width ||
this.px - particleDiameter/2 < 0){
this.vx = -this.vx;
}
if (this.py + particleDiameter/2 > height ||
this.py - particleDiameter/2 < 0){
this.vy = -this.vy;
}
}
var particleDiameter = 8;
function particleDraw() {
fill("#FA4E44");//red
ellipse(this.px, this.py, particleDiameter, particleDiameter);
}
// add a force to the particle using F = mA
function particleAddForce(fx, fy) {
var ax = fx / this.mass;
var ay = fy / this.mass;
this.vx += ax;
this.vy += ay;
}
// make a new particle
function makeParticle(x, y, dx, dy) {
var p = {px: x, py: y, vx: dx, vy: dy,
mass: 1.0, damping: 0.9,
bFixed: false,
addForce: particleAddForce,
update: particleUpdate,
draw: particleDraw
}
return p;
}
var seekFactor = 0.0010;
function seek(p) {
var desiredX = mouseX - p.px;
var desiredY = mouseY - p.py;
p.addForce(desiredX * seekFactor, desiredY * seekFactor);
}
//attempt to implement a restart without reloading page.
//Unable to empty array and restart time
// function keyPressed() {
// loop();
// background();
// time = 0;
// myParticles.push(time);
// }
var myParticles = [];
var nParticles = 1000;
var follow = true;
var cursorD = 30;
var x = 200;
var y = 200;
var diffx = 0;
var diffy = 0;
function setup() {
createCanvas(400, 400);
for (var i = 0; i < nParticles; i++) {
var rx = random(width);
var ry = random(height);
var p = makeParticle(rx, ry, 0, 0);
p.bElasticBoundaries = false;
p.damping = 0.99;
myParticles[i] = p;
}
frameRate(25);
noStroke();
}
function draw() {
background(250);
var time = ceil(frameCount/10);
var xConstrain = constrain(x, cursorD/2, width - cursorD/2);//mouse boundary
var yConstrain = constrain(y, cursorD/2, height - cursorD/2);//mouse boundary
for (var i = 0; i < time; i++) {
var ithParticle = myParticles[i];
ithParticle.fx = 0;
ithParticle.fy = 0;
if (follow) seek(ithParticle);
}
fill("#FA9998");
textAlign(CENTER);
textStyle(BOLD);
textSize(36);
text(time, width/2, 100);//displays time/score
fill("#2A3447");
ellipseMode(CENTER);
diffx = mouseX - x;
diffy = mouseY - y;
x = x + 0.2*diffx;
y = y + 0.2*diffy;
ellipse(xConstrain, yConstrain, cursorD, cursorD);//draws cursor/player
for (var i = 0; i < time; i++) {
var p = myParticles[i]
var length = dist(xConstrain, yConstrain, p.px, p.py);
p.update(); // update all locations
p.draw(); // draw all particles
if (length < cursorD/2){//stops game
textStyle(BOLD);
textSize(48);
fill("#FA4E44");
text("Game Over", width/2, height/2);
textStyle(NORMAL);
textSize(14);
fill(0);
text("reload to restart", width/2, height/2 + 20);
noLoop();
}
}
}