xxxxxxxxxx
673
//FINAL PROJECT
let w = 1440;
let h = 780;
let m = 140;
let video;
let poseNet;
let poses = [];
let noseX = 0;
let noseY = 0;
let idealTemp;
let ingDrop;
let displayIng;
let ingNames = ["banana", "macapuno", "crushed\n ice", "red\n jelly", "choco\n stick", "green\n jelly", "nata\n de coco", "ube\n ice cream"];
let gameStartTime;
let ings = [];
//basic settings
let gameSpeed = 5;
let startstage = false;
let val1 = 0; //stage 1 potentiometer
let val2 = 0; //stage 3 digital switch
let gameState = -1; //-1
let soundtrack, soundtrack2, blendCrop, boilinb, fanfare, gameOver;
function preload() {
//audio
soundtrack = loadSound('sound/acoustic-short.mp3');
soundtrack2 = loadSound('sound/acoustic3.mp3');
blendCrop = loadSound('sound/blend-crop.mp3');
boiling = loadSound('sound/boiling.mp3');
fanfare = loadSound('sound/fanfare.mp3');
gameOver = loadSound('sound/gameOver.mp3');
squish = loadSound('sound/plop.mp3');
}
function setup() {
//canvas
createCanvas(w, h);
//sprites
halo = loadImage('assets/halostart-1.PNG');
startbtn = loadImage('assets/start.png');
//tutorial slides
stage1 = loadImage('assets/stage1.png');
stage2 = loadImage('assets/stage2.PNG');
stage3 = loadImage('assets/stage2-new.png');
serialStage = loadImage('assets/serial.PNG');
endstage = loadImage('assets/end.png');
//ui slides
fail = loadImage('assets/fail.png');
time = loadImage('assets/time.png');
success = loadImage('assets/success.png');
//1: sago
pot = loadImage('assets/pot.png');
low = loadImage('assets/low.PNG');
med = loadImage('assets/med.PNG');
high = loadImage('assets/high.PNG');
hot = loadImage('assets/toohot.PNG');
cold = loadImage('assets/toocold.PNG');
//falling ingredients
glass = loadImage('assets/glass.png');
ban1 = loadImage('ingredients/ban1.png');
coco1 = loadImage('ingredients/coco1.png');
ice1 = loadImage('ingredients/ice1.png');
redg1 = loadImage('ingredients/redg1.png');
stick1 = loadImage('ingredients/stick1.png');
greeng1 = loadImage('ingredients/greeng1.png');
nata1 = loadImage('ingredients/nata1.png');
ube1 = loadImage('ingredients/ube1.png');
ban2 = loadImage('ingredients/ban2.png');
coco2 = loadImage('ingredients/coco2.png');
ice2 = loadImage('ingredients/ice2.png');
redg2 = loadImage('ingredients/redg2.png');
stick2 = loadImage('ingredients/stick2.png');
greeng2 = loadImage('ingredients/greeng2.png');
nata2 = loadImage('ingredients/nata2.png');
ube2 = loadImage('ingredients/ube2.png');
//fonts
titleFont = loadFont('p22.otf');
//backgrounds
halobg = loadImage('assets/halobg2.PNG');
kitchen = loadImage('assets/kitchen.png');
//stage 3
blender1 = loadImage('assets/blender.PNG');
//video
video = createCapture(VIDEO);
video.size(width, height);
// Create a new poseNet method with a single detection
poseNet = ml5.poseNet(video, modelReady);
// Hide the video element, and just show the canvas
video.hide();
//displaylist
displayIng = [ban2, coco2, ice2, redg2, stick2, greeng2, nata2, ube2];
//random temp
idealTemp = round(random(100, 200));
}
//creates an ant object
class ing {
constructor(img, size, speed) {
this.x = random(60, width-360); //x position
this.y = 0; //y position
this.size = size;
this.img = img;
this.speed = speed;
this.dead = false;
this.timeDied = 100000;
}
display() {
image(this.img, this.x, this.y, this.size, this.size)
}
move() {
//if thing in same spot as glass
if (w-noseX>this.x && w-noseX<this.x+this.size && noseY-100>this.y && noseY-100<this.y+this.size) {
console.log("DIED");
this.speed = 0; //stop moving
this.dead=true; //mark dead
squish.play(); // audio
} else {
this.y += this.speed;
}
}
}
function draw() {
if (gameState==-1) setSerial();
//start screen
else if (gameState==0) startScreen();
//game stages
else if (gameState==1) sago(); //sago cooking
else if (gameState==2) catchstuff(); //catch ice and fruit
else if (gameState==3) blender(); //blend
//other stages
else if (gameState==4) end(); //finish
}
//pre set up page
function setSerial() {
background(serialStage);
if (mouseIsPressed && mouseX>w/2 && mouseY>h/4 && mouseY<h-200) {
setUpSerial();
gameState = 0; //go to startscreen
}
}
//HELPER FUNCTIONS
//restarts games and resets ant list, score time, lives
function restartGame() {
now = millis();
gameStartTime = now;
}
// returns time in millis since game started
function millisInGame() {
// Subtract when the game started from current time
return millis() - gameStartTime;
}
//body text
function bodyText(body, size, x, y) {
textAlign(CENTER);
textFont(titleFont);
textSize(size);
text(body, x, y)
}
//GAME STATES
let bob = 1;
let haloy = 0;
//start screen
function startScreen() {
if (!soundtrack.isPlaying()) soundtrack.play(); //play music if not already
background(halobg);
//bobbing animation
if (frameCount % 80==0) { bob=(bob*-1); }
haloy += bob*0.08;
image(halo, 0, haloy, w, h);
if (mouseIsPressed && mouseX>200 && mouseX<600 && mouseY>200 && mouseY<600) {
soundtrack.pause();
gameState = 1; //go to game
}
}
let outcome = "none";
let tutorial = true;
function tutstage(param) {
if (startstage == false && tutorial==true) {
if (!soundtrack2.isPlaying()) soundtrack2.play();
//tutorial slide
image(param, 0, 0, w, h);
image(startbtn, w*0.2, h*0.2, w*0.8, h*0.8);
if (mouseIsPressed && mouseX>w-200 && mouseY>h-200) {
restartGame();
soundtrack2.stop();
startstage = true;
tutorial = false;
}
}
}
//stage 1: sago - potentiometer
function sago() {
tutstage(stage1);
if (startstage) {
background(kitchen, 200);
//timer bg
fill('#ffeecc');
ellipse(50, 50, 60);
//timer
fill(0);
textAlign(LEFT);
let timer = round(millisInGame()/1000);
bodyText(timer, 30, 50, 60);
//image of pot
if (frameCount % 60==0) { bob=(bob*-1); }
haloy += bob*0.1;
image(pot, 0, haloy, w, h);
image(low, 0, 0, w, h);
//to change stovelight colors
if (val1<85) {
image(low, 0, 0, w, h);
} else if (val1<85*2) {
image(med, 0, 0, w, h);
} else {
image(high, 0, 0, w, h);
}
textSize(20);
let tempText = "Temperature: "+val1;
text(tempText, w/2, h-50);
//heat bar
fill(255);
noStroke();
//bar
rect(m, h-m, w-m*2, 50);
fill("#ffeecc");
rect(m, h-m, (w-m*2)/3, 50);
fill("#ffb84d");
rect(m+(w-m*2)/3, h-m, (w-m*2)/3, 50);
fill("#ff471a");
rect(m+(w-m*2)/3*2, h-m, (w-m*2)/3, 50);
//cursor
fill("#003380");
rect(m+val1*4.5, h-m-10, 16, 70, 30);
//to respond to temp
if (val1<idealTemp) {
image(cold, 0, 0, w, h);
} else if (val1>idealTemp) {
image(hot, 0, 0, w, h);
} else if (val1==idealTemp) {
//success
if (startstage) fanfare.play();
outcome = "win";
startstage = false;
}
if (timer>=15) {
//failure
if (startstage) gameOver.play();
outcome="lose";
startstage = false;
}
}
if (outcome=="lose") {
//failure, try again
image(time, 0, 0, w, h);
if (mouseIsPressed && mouseX>w/2 && mouseY>h/4 && mouseY<h-200) {
gameState=1;
outcome = "none";
tutorial=true;
}
}
if (outcome=="win") {
image(success, 0, 0, w, h);
if (mouseIsPressed && mouseX>w/2 && mouseY>h/4 && mouseY<h-200) {
gameState=2;
outcome = "none";
tutorial=true;
}
}
}
function readSerial(data) {
if (data != null) {
// make sure there is actually a message
// split the message
//console.log("data "+data)
let fromArduino = split(trim(data), ",");
// if the right length, then proceed
if (fromArduino.length == 2) {
// only store values here
// do everything with those values in the main draw
val1 = fromArduino[0];
val2 = fromArduino[1];
//console.log("val1 " + val1);
//console.log("val2 " + val2);
}
}
}
//POSENET STUFF
function modelReady() {
poseNet.on('pose', gotPose);
// This sets up an event that fills the global variable "poses"
}
function gotPose(results) {
poses = results;
// with an array every time new poses are detected
if (! poses || poses.length < 1) return;
//leave this function if the results don't look right
//console.log(poses[0].pose.nose.x);
noseX = poses[0].pose.rightWrist.x;
noseY = poses[0].pose.rightWrist.y;
}
//stage 2: catch -
function catchstuff() {
tutstage(stage2);
//list
ingDrop = [ban2, coco2, ice2, redg2, stick2, greeng2, nata2, ube2];
if (startstage) {
background("#fcefd0");
//display ingredient names
for (let i=ingNames.length-1; i>=0; i--) {
textSize(12);
text(ingNames[i], w-70, 60 + i*90)
}
push();
translate(video.width, 0);
scale(-1, 1);
image(video, 250, 0, width-250, height);
//display ingredients
for (let i=displayIng.length-1; i>=0; i--) {
image(displayIng[i], 110, 16 + i*90, 100, 100);
}
image(glass, noseX, noseY-160, 160, 210);
if (frameCount % 30==0) { //new fruit drop
ings.push(new ing(random(ingDrop), 150, gameSpeed));
}
pop();
//timer bg
fill('#ffeecc');
ellipse(50, 50, 60);
//timer
fill(0);
textAlign(LEFT);
let timer = round(millisInGame()/1000);
bodyText(timer, 30, 50, 60);
for (let i=ings.length-1; i>0; i--) {
//move and display as normal
ings[i].move();
ings[i].display();
//splice and subtract life if out of bounds
if (ings[i].y>=height) {
ings.splice(i, 1);
}
//splice if dead
if (ings[i].dead==true) {
let b = displayIng.indexOf(ings[i].img);
//console.log("spliced image", b);
if (b!=-1) displayIng.splice(b, 1);
if (b!=-1) ingNames.splice(b, 1);
ings.splice(i, 1);
}
} //end of for loop
//SUCCESS
if (displayIng.length==0) {
if (startstage) fanfare.play();
outcome="win";
startstage = false;
}
//FAILURE
if (timer>=50) {
if (startstage) gameOver.play();
outcome="lose";
startstage = false;
}
} //end of if start stage
if (outcome=="win") {
//success
image(success, 0, 0, w, h);
if (mouseIsPressed && mouseX>w/2 && mouseY>h/4 && mouseY<h-200) {
gameState=3;
outcome = "none";
tutorial=true;
}
}
//failure
if (outcome=="lose") {
//failure, try again
image(time, 0, 0, w, h);
if (mouseIsPressed && mouseX>w/2 && mouseY>h/4 && mouseY<h-200) {
//reset displayIng
displayIng = [ban2, coco2, ice2, redg2, stick2, greeng2, nata2, ube2];
ings = [];
gameState=2;
outcome = "none";
tutorial=true;
}
}
}
let blendAmt = 0;
let blendExplode = 0;
let blendx = 0;
let opac = 0;
let blendAmtOpac = 0;
let gameStop = false;
let restarto = false;
let bb = false;
//stage 3: blender - digital switch and servo
function blender() {
tutstage(stage3);
if (startstage) {
soundtrack2.pause();
background(kitchen, 200);
//timer bg
fill('#ffeecc');
ellipse(50, 50, 60);
//timer
fill(0);
textAlign(LEFT);
let timer = round(millisInGame()/1000);
bodyText(timer, 30, 50, 60);
//image of blender
if (frameCount % 4==0) { bob=bob*(-1); }
blendx += bob*0.1*blendExplode*0.8;
image(blender1, blendx, 0, w, h);
//text reminder
textSize(20);
let tempText;
let b = m+blendAmt;
if (b<(w-2*m)/3) {
tempText = "Press to blend! You've got a long way to go!";
} else if (b<(w-2*m)/1.5){
tempText = "You're getting there!";
} else if (b<(w-2*m)-100){
tempText = "You're almost there!";
} else {
tempText = "Done!";
}
//IF BUTTON PRESSED
//increase values of amount blended and explode level
if (val2==1) {
if (!blendCrop.isPlaying()) blendCrop.play();
blendAmt+=5; //increase amount blended
blendExplode += 5; //increase explode level
} else if (val2==0) {
blendCrop.pause();
if (blendExplode>0) blendExplode -= 4; //decrease explode level
}
opac = map(blendExplode, 0, w-m*4, 100, 255);
//val2
//top bar: explode amount
fill(255);
noStroke();
fill("#ffeecc");
rect(m*2, m/2, w-m*4, 50);
fill(color(255, 80, 80, opac));
rect(m*2, m/2, blendExplode, 50);
blendAmtOpac = map(blendAmt, 0, w-m*2, 100, 255);
//bottom bar: blend amount
fill(255);
noStroke();
fill("#ffeecc");
rect(m, h-m, w-m*2, 50);
fill(color(94,173,237,blendAmtOpac));
rect(m, h-m, blendAmt, 50);
fill(0);
//helper text at top
if (blendExplode>250) {
text("Don't let this explosion bar reach the end!!", w/2, 100);
}
//helper text at bottom
text(tempText, w/2, h-110);
//if you blend enough: SUCCESS
if (blendAmt >= w-m*2) {
if (startstage) fanfare.play();
outcome="win";
startstage=false;
}
//if the blender explodes: LOSE
if (blendExplode >= w-m*4) {
if (startstage) gameOver.play();
outcome="lose";
startstage=false;
}
if (timer>=30) {
if (startstage) gameOver.play();
outcome="time";
startstage=false;
}
}
if (outcome=="win") {
if (blendCrop.isPlaying()) blendCrop.pause();
soundtrack2.pause();
//success slide
image(success, 0, 0, w, h);
if (mouseIsPressed && mouseX>w/2 && mouseY>h/4 && mouseY<h-200) {
gameState=4;
outcome="none";
}
}
//failure
if (outcome=="time") {
if (blendCrop.isPlaying()) blendCrop.pause();
soundtrack2.pause();
image(time, 0, 0, w, h);
if (mouseIsPressed && mouseX>w/2 && mouseY>h/4 && mouseY<h-200) {
restartGame();
blendAmt = 0;
blendExplode = 0;
gameState=3;
tutorial = true;
outcome="none";
}
}
if (outcome=="lose") {
soundtrack2.pause();
image(fail, 0, 0, w, h);
if (mouseIsPressed && mouseX>w/2 && mouseY>h/4 && mouseY<h-200) {
restartGame();
blendAmt = 0;
blendExplode = 0;
gameState=3
tutorial = true;
outcome="none";
}
}
}
//stage 4: finish screen
function end() {
if (!soundtrack.isPlaying()) soundtrack.play();
background(endstage);
if (mouseIsPressed && mouseX>200 && mouseX<600 && mouseY>200 && mouseY<600) {
soundtrack.pause();
idealTemp = round(random(100, 200));
gameState = 0; //go to game
}
}