xxxxxxxxxx
407
//===========================================THE ELEMENTS==============================================
//This uses Teachable Machine Image Classifier and PoseNET to make you command the elements at will.
//Simply press the buttons to change which element you wish to command
//Elemet Powers:
//Fire: If you hold out your arms to your right, you can shoot out flame blasts
//Water: If you move your hands towards the screen, the water particles splash everywhere
//Earth: If you crunch your fists, the earth particles increase in size, if you release, they shrink
//Air: If you raise your arms up, the canvas fills with smoke.
//------------------------------------------------------------------------------------
//Global Variables:
let poseNet;
let imagePoseModel;
let myImageResults;
let myVideo;
let poseNetResults;
let gate = true;
let fireGate = true;
const particlesArr = [];
const imagePoseModelURL = 'https://teachablemachine.withgoogle.com/models/orAFuxZcb/'
//Booleans:
let fireMode = true;
let waterMode = false;
let earthMode = false;
let airMode = false;
let fireMove = false;
let waterMove = false;
let earthMove1 = false;
let earthMove2 = false;
let airMove = false;
//--------------------------Image Classifier From Teachable Machine-------------------------------------
function preload() {
imagePoseModel = ml5.imageClassifier(imagePoseModelURL + 'model.json', gotImageModel);
soundFormats('mp3');
Fire_Sound = loadSound("Sounds/Fire Sound Effect.mp3");
Water_Sound = loadSound("Sounds/Water Sound Effect.mp3");
Earth_Sound = loadSound("Sounds/Earth Sound Effect.mp3");
Air_Sound = loadSound("Sounds/Air Sound Effect.mp3");
Fire_Blast = loadSound("Sounds/Fire Blast.mp3");
}
//Setup function to start video, start poseNet Model and Image Classifier
function setup() {
myVideo = createCapture(VIDEO);
myVideo.hide();
flippedVideo = ml5.flipImage(myVideo);
classifyMyVideo();
poseNet = ml5.poseNet(myVideo, gotPoseNETModel);
Fire_Sound.play();
Fire_Sound.loop();
Fire_Sound.setVolume(0.2);
createCanvas(640, 480);
}
function gotImageModel() {
console.log('ImageTMModel', imagePoseModel);
}
function classifyMyVideo() {
imagePoseModel.classify(myVideo, gotImageResults);
}
function gotImageResults(error, results) {
if (error) {
console.error(error);
}
if (results) {
myImageResults = results;
classifyMyVideo();
}
}
//------------------------------Pose NET Model Initiaiation----------------------------------------
function gotPoseNETModel() {
poseNet.on('pose', gotPoseResults);
}
function gotPoseResults(results) {
if(results) {
poseNetResults = results;
//If there is a pose result, then do the following
if(poseNetResults[0]) {
// console.log(poseNetResults);
leftHand = poseNetResults[0].pose.leftWrist;
rightHand = poseNetResults[0].pose.rightWrist;
//Depending on the mode push the particles into the array from different initial conditions
if(fireMode) {
particlesArr.push(new Particle(leftHand.x, leftHand.y-50));
particlesArr.push(new Particle(rightHand.x, rightHand.y-50));
}
else if(waterMode) {
particlesArr.push(new Particle(leftHand.x, leftHand.y-100));
particlesArr.push(new Particle(rightHand.x, rightHand.y-100));
}
else if(earthMode) {
particlesArr.push(new Particle(random(leftHand.x-15, leftHand.x+15), leftHand.y-100));
particlesArr.push(new Particle(random(rightHand.x-15, rightHand.x+15), rightHand.y-100));
}
else if(airMode) {
particlesArr.push(new Particle(random(leftHand.x-15, leftHand.x+15), leftHand.y-100));
particlesArr.push(new Particle(random(rightHand.x-15, rightHand.x+15), rightHand.y-100));
}
}
}
}
//Draw Function
function draw() {
//Draws the user on the camera
image(myVideo, 0, 0, width, height);
//If the Image Results from Teachable Machine come through then do the following
if(myImageResults) {
const label = myImageResults[0].label;
//Classifies what the labels are and depending on them, activates the move booleans
if(label == "Fire Move" && fireMode) {
fireMove = true;
waterMove = false;
earthMove1 = false;
earthMove2 = false;
airMove = false;
if(fireGate) {
Fire_Blast.play();
Fire_Blast.loop();
Fire_Blast.setVolume(0.2);
fireGate = false;
}
}
if(label == "Water Move" && waterMode) {
fireMove = false;
waterMove = true;
earthMove1 = false;
earthMove2 = false;
airMove = false;
Fire_Blast.stop();
fireGate = true;
}
if(label == "Earth Move Clinch" && earthMode) {
fireMove = false;
waterMove = false;
earthMove1 = true;
earthMove2 = false;
airMove = false;
Fire_Blast.stop();
fireGate = true;
}
if(label == "Earth Move Relax" && earthMode) {
fireMove = false;
waterMove = false;
earthMove1 = false;
earthMove2 = true;
airMove = false;
Fire_Blast.stop();
fireGate = true;
}
if(label == "Air Move" && airMode) {
fireMove = false;
waterMove = false;
earthMove1 = false;
earthMove2 = false;
airMove = true;
Fire_Blast.stop();
fireGate = true;
}
if(label == "Nothing") {
fireMove = false;
waterMove = false;
earthMove1 = false;
earthMove2 = false;
airMove = false;
Fire_Blast.stop();
fireGate = true;
}
}
//Draws the particles onto the canvas
for (let i = particlesArr.length-1; i >= 0; i--) {
particlesArr[i].update();
particlesArr[i].show();
if (particlesArr[i].finished()) {
particlesArr.splice(i, 1);
}
}
//Drawing the buttons on the canvas.
button("Fire", "#FF5733", 0, 440, 160, 40, 4);
button("Water", "#0096FF", 160, 440, 160, 40, 4);
button("Earth", "#4F7942", 320, 440, 160, 40, 4);
button("Air", "#D3D3D3", 480, 440, 160, 40, 4);
}
//This is a class which controls particles
class Particle {
//Constructor to initialize the particle based on initial variables
constructor(handX, handY){
this.x = handX;
this.y = handY;
this.alpha = 255;
this.size = random(35,40);
this.assignVelocity();
if(earthMode) {
this.earthSize();
}
}
//This is a function only for the Earth Mode which determines it's size
earthSize() {
if(earthMove1) {
while(this.size < 100) {
this.size+=1;
}
}
else if(earthMove2) {
while(this.size > 15) {
this.size-=1;
}
}
}
//This assigns the velocity on the particle depending on what it is
assignVelocity() {
if(fireMode) {
if(fireMove) {
this.vx = random(20, 30);
this.vy = random(-2, 2);
}
else {
this.vx = random(-4, 4);
this.vy = random(-6, -1);
}
}
else if(waterMode) {
if(waterMove) {
this.vx = random(-20, 20);
this.vy = random(-20, 20);
}
else {
this.vx = random(-4, 4);
this.vy = random(1, 6);
}
}
else if(earthMode) {
this.vx = random(-0.1, 0.1);
this.vy = random(-1, 1);
}
else if(airMode) {
this.vx = random(-4, 4);
this.vy = random(-0.5, 0.5);
}
}
//Then the alpha value is below 0, then we return a true (to remove particle from array)
finished() {
return this.alpha < 0;
}
//This function updates the velocities and alpha value of the particles
update() {
if(airMode && airMove) {this.alpha -= 0.5; }
else {this.alpha -= 5; }
this.x += this.vx;
this.y += this.vy;
}
//This function draws the particles
show() {
noStroke();
//Assigns the colors depending on the mode it's on
if(fireMode) {fill(227, random(100,160), 68, this.alpha); }
else if(waterMode) {fill(0, random(120, 180), 255, this.alpha); }
else if(earthMode) {fill(102, 50, 0, this.alpha); }
else if(airMode) {fill(random(200, 255), random(200,255), random(200, 255), this.alpha); }
ellipse(this.x, this.y, this.size);
}
}
//This is a simple function to create a button.
function button(title, button_color, x, y, w, h, rounding) {
if(mouseX > x && mouseX < x+w && mouseY > y && mouseY < y+h) {
//Set the hovering over button color;
if(title == "Fire") {button_color = "#fb6767"}
else if(title == "Water") {button_color = "#6495ED"}
else if(title == "Earth") {button_color = "#5F8575"}
else if(title == "Air") {button_color = "#E5E4E2"}
//If the mouse is pressed,
if(mouseIsPressed && gate) {
if(title == "Fire") {
Fire_Sound.stop();
Water_Sound.stop();
Earth_Sound.stop();
Air_Sound.stop();
fireMode = true;
waterMode = false;
earthMode = false;
airMode = false;
Fire_Sound.play();
Fire_Sound.loop();
Fire_Sound.setVolume(0.2);
gate = false;
}
else if(title == "Water") {
Fire_Sound.stop();
Water_Sound.stop();
Earth_Sound.stop();
Air_Sound.stop();
fireMode = false;
waterMode = true;
earthMode = false;
airMode = false;
Water_Sound.play();
Water_Sound.loop();
Water_Sound.setVolume(0.2);
gate = false;
}
else if(title == "Earth") {
Fire_Sound.stop();
Water_Sound.stop();
Earth_Sound.stop();
Air_Sound.stop();
fireMode = false;
waterMode = false;
earthMode = true;
airMode = false;
Earth_Sound.play();
Earth_Sound.loop();
Earth_Sound.setVolume(0.2);
gate = false;
}
else if(title == "Air") {
Fire_Sound.stop();
Water_Sound.stop();
Earth_Sound.stop();
Air_Sound.stop();
fireMode = false;
waterMode = false;
earthMode = false;
airMode = true;
Air_Sound.play();
Air_Sound.loop();
Air_Sound.setVolume(0.2);
gate = false;
}
}
else {
gate = true;
}
}
//Drawing the button:
strokeWeight(1);
fill(button_color);
rect(x, y, w, h, rounding);
//Button text:
fill(255);
textFont("Kefa", 30);
textAlign(CENTER);
text(title, (x+(x+w))/2, ((y+(y+h))+15)/2);
}