https://docs.google.com/presentation/d/1Z6SidOzB32I8VX1bTrDZAUZKZ5KchGT1NTqVsnP7EiE/edit?usp=sharing
let video;
let poseNet;
let poses = [];
let points = [];
let pacMan;
let score = 0;
let timer = 30;
let intervalID;
let startSound;
let gameStarted = false;
function preload() {
startSound = loadSound('/mnt/data/pacman_beginning.wav');
}
function setup() {
createCanvas(640, 480);
video = createCapture(VIDEO);
video.size(640, 480);
video.hide();
poseNet = ml5.poseNet(video, modelReady);
poseNet.on('pose', function(results) {
poses = results;
});
for (let i = 0; i < 5; i++) {
points.push(new Dot(random(width), random(height)));
}
pacMan = new PacMan();
startSound.play();
setTimeout(() => {
gameStarted = true;
intervalID = setInterval(() => {
if (timer > 0) {
timer--;
}
}, 1000);
}, 3000);
}
function modelReady() {
console.log('PoseNet model ready!');
}
function draw() {
background(220);
image(video, 0, 0, width, height);
if (!gameStarted) {
textSize(32);
fill(255, 0, 0);
textAlign(CENTER, CENTER);
text('Stand Up', width / 2, height / 2);
return;
}
pacMan.update();
pacMan.display();
for (let i = points.length - 1; i >= 0; i--) {
points[i].display();
if (pacMan.eats(points[i])) {
points.splice(i, 1);
score++;
}
}
textSize(24);
fill(0);
text(`Score: ${score}`, 10, 25);
text(`Time: ${timer}`, 10, 50);
if (timer <= 0) {
gameOver();
}
}
function gameOver() {
noLoop();
textSize(32);
fill(255, 0, 0);
textAlign(CENTER, CENTER);
text('Game Over!', width / 2, height / 2);
clearInterval(intervalID);
}
class PacMan {
constructor() {
this.x = width / 2;
this.y = height / 2;
this.size = 50;
}
update() {
if (poses.length > 0) {
let keypoints = poses[0].pose.keypoints;
let leftShoulder = keypoints.find(point => point.part === 'leftShoulder');
let rightShoulder = keypoints.find(point => point.part === 'rightShoulder');
if (leftShoulder && rightShoulder && leftShoulder.score > 0.2 && rightShoulder.score > 0.2) {
this.x = (leftShoulder.position.x + rightShoulder.position.x) / 2;
this.y = (leftShoulder.position.y + rightShoulder.position.y) / 2;
}
}
}
display() {
noStroke();
fill(255, 255, 0);
arc(this.x, this.y, this.size, this.size, PI / 4, -PI / 4);
}
eats(dot) {
let d = dist(this.x, this.y, dot.x, dot.y);
return d < this.size / 2 + dot.size / 2;
}
}
class Dot {
constructor(x, y) {
this.x = x;
this.y = y;
this.size = 20;
}
display() {
noStroke();
fill(255, 0, 0);
ellipse(this.x, this.y, this.size);
}
}