Destory It!

https://drive.google.com/file/d/1Zx1tmusa2bh9BNDsMLyvhkaiUFLenOb_/view?usp=sharing

I create a game that user need to use their wrist to destroy the box. The box is generated randomly position. Each time will create 5 random box. After the 5 boxes are destroyed, will generate 5 random box again.

p5link: https://editor.p5js.org/YuhongSun/sketches/f2uk6lMWP

let video;
let bodyPose;
let poses = [];
let squares = [];
let score = 0;
let gameTimer = 30;
let gameActive = false;
let numSquares = 5;  

function preload() {
  bodyPose = ml5.bodyPose({ flipped: true });
}

function setup() {
  createCanvas(640, 480);
  video = createCapture(VIDEO, { flipped: true });
  video.size(640, 480);
  video.hide();
  bodyPose.detectStart(video, gotPoses);
  resetGame();
}

function draw() {
  background(0);
  image(video, 0, 0, width, height);

  if (gameActive) {
    updateGame();
    displayScoreAndTime();
  }

  if (gameTimer <= 0) {
    displayFinalScore();
    noLoop();  
  }
}

function resetGame() {
  squares = createRandomSquares(numSquares);
  score = 0;
  gameTimer = 30;
  gameActive = true;
  loop();  
}

function updateGame() {
  if (poses.length > 0 && poses[0].keypoints.length > 0) {
    let pose = poses[0];
    drawWristCircles(pose);
    checkCollision(pose);
  }
  drawSquares();
}

function drawSquares() {
  fill(0, 255, 0);
  noStroke();
  squares.forEach(square => {
    rect(square.x, square.y, square.size, square.size);
  });
}

function drawWristCircles(pose) {
  let leftWrist = pose.keypoints[9];
  let rightWrist = pose.keypoints[10];

  if (leftWrist && leftWrist.confidence > 0.1) {
    fill(255, 0, 0);
    noStroke();
    circle(leftWrist.x, leftWrist.y, 30);  
  }

  if (rightWrist && rightWrist.confidence > 0.1) {
    fill(255, 0, 0);
    noStroke();
    circle(rightWrist.x, rightWrist.y, 30);  
  }
}

function checkCollision(pose) {
  var leftWrist = pose.keypoints[9];
  var rightWrist = pose.keypoints[10];

  if (leftWrist && leftWrist.confidence > 0.1) {
    checkWristCollision(leftWrist);
  }
  if (rightWrist && rightWrist.confidence > 0.1) {
    checkWristCollision(rightWrist);
  }
  if (squares.length === 0) { 
    squares = createRandomSquares(numSquares);
  }
}

function findKeypointByName(keypoints, name) {
  for (var i = 0; i < keypoints.length; i++) {
    if (keypoints[i].name === name) {
      return keypoints[i];
    }
  }
  return null;
}

function checkWristCollision(wrist) {
  var newSquares = [];
  for (var i = 0; i < squares.length; i++) {
    if (wrist.x > squares[i].x && wrist.x < squares[i].x + squares[i].size &&
        wrist.y > squares[i].y && wrist.y < squares[i].y + squares[i].size) {
      score++;
    } else {
      newSquares.push(squares[i]);
    }
  }
  squares = newSquares; 
}

function createRandomSquares(num) {
  let newSquares = [];
  for (let i = 0; i < num; i++) {
    let size = random(20, 50);
    newSquares.push({
      x: random(0, width - size),
      y: random(0, height - size),
      size: size
    });
  }
  return newSquares;
}

function displayScoreAndTime() {
  fill(255);
  textSize(24);
  textStyle(BOLD);
  text(`Score: ${score}`, 30, 40);
  text(`Time Left: ${gameTimer}`, 30, 70);
  if (frameCount % 60 == 0 && gameTimer > 0) {
    gameTimer--;
  }
}

function displayFinalScore() {
  fill(255);
  textSize(64);
  textStyle(BOLD);
  textAlign(CENTER);
  text(`Your Score: ${score}`, width / 2, height / 2 + 30);
}

function mousePressed() {
  if (!gameActive || gameTimer <= 0) {
    resetGame();
  }
}

function gotPoses(results) {
  if (results.length > 0) {
    poses = results;
  }
}

Open Sourcing the Origin Stories

There are many professional aspects of knowledge in the dataset, and for data users, they may not have knowledge of all the principles of the dataset. Although the album already includes some basic introductions to the models, how to make them understand what these models can do in a simple way may be more intuitive for them, which can help them better use these datasets.