xxxxxxxxxx
140
let faceMesh;
let video;
let predictions = [];
let humuses = [];
let humusCount = 5;
let mouthOpen = []
let mouth_was_open = false;
let yaySound, winSound;
let gameOver = false;
let count = 0;
let diameter = 20;
function preload() {
yaySound = loadSound('https://cdn.freesound.org/previews/273/273747_3375950-lq.mp3'); // Working "yay" sound URL
winSound = loadSound('https://cdn.freesound.org/previews/518/518305_2402876-lq.mp3');
}
function setup() {
createCanvas(640, 480);
video = createCapture(VIDEO, {flipped: true});
video.size(width, height);
video.hide();
// Initialize FaceMesh model
faceMesh = ml5.facemesh(video, modelReady);
for (let i = 0; i < humusCount; i++) {
humuses.push({ x: random(width), y: -random(500), caught: false });
}
gridOutput = function(){} // see: https://github.com/processing/p5.js/issues/7259#issuecomment-2518331223
}
function modelReady() {
console.log('Model Ready!');
faceMesh.on('predict', results => {
predictions = results;
checkMouthOpen();
});
}
function draw() {
image(video, 0, 0, width, height);
if (gameOver) {
fill(210, 180, 140);
stroke(105, 90, 70);
strokeWeight(2)
textSize(90)
text('YOU ATE ALL', 40, 100)
textSize(150)
text('HUMUS!!!', 40, 250)
} else {
if (!mouth_was_open) {
fill(210, 180, 140);
stroke(105, 90, 70);
strokeWeight(2)
textSize(90);
text('HUMUS DAY!', 40, 100)
}
translate(width, 0)
scale(-1,1)
if (mouthOpen.some(x => x)) {
mouth_was_open = true
drawMouthContour()
}
if (mouth_was_open)
drawHumuses();
}
}
let polies = [];
function drawMouthContour() {
strokeWeight(3);
stroke(255, 0, 255); // Set stroke to purple for visibility
noFill();
polies = []
for (let prediction of predictions){
beginShape();
// Draw upper lip
prediction.annotations.lipsUpperInner.forEach(point => {
curveVertex(point[0], point[1]);
});
// Draw lower lip in reverse to complete the loop
let poly = []
prediction.annotations.lipsLowerInner.slice().reverse().forEach(point => {
curveVertex(point[0], point[1]);
poly.push(createVector(point[0], point[1]))
});
polies.push(poly)
endShape(CLOSE);
}
}
function drawHumuses() {
fill(210, 180, 140); // Light brown color for humus
stroke(105, 90, 70);
strokeWeight(1)
for (let i = humuses.length - 1; i >= 0; i--) {
let humus = humuses[i];
if (!humus.caught) {
ellipse(humus.x, humus.y, diameter, diameter);
humus.y += 3;
if (humus.y > height) {
humus.y = 0;
humus.x = random(width);
} else {
for (let i=0; i<Math.min(polies.length, mouthOpen.length); i++) {
if (mouthOpen[i] && polies[i].length && collideCirclePoly(humus.x, humus.y, diameter, polies[i])) {
humus.caught = true; // Mark as caught
yaySound.play(); // Play sound
count++;
if(count==humusCount)
{
gameOver = true;
winSound.play()
}
}
}
}
}
}
}
function checkMouthOpen() {
mouthOpen = []
for (let prediction of predictions) {
// Analyze the prediction to determine if the mouth is open
// This is a placeholder; you'll need to implement this based on FaceMesh landmarks
const mouthTop = prediction.scaledMesh[13];
const mouthBottom = prediction.scaledMesh[14];
if (mouthTop && mouthBottom) {
const distance = dist(mouthTop[0], mouthTop[1], mouthBottom[0], mouthBottom[1]);
mouthOpen.push(distance > diameter); // Adjust threshold as needed
}
}
}