xxxxxxxxxx
422
/*
Welcome to the "Reincarnation"!
Please read the instruction clearly below to start playing.
Play it with computers is recommended.
It is best to pay in one person.
Before you start, make sure you have your webcam attached.
If your laptop has a webcam embedded, then no worries.
1. Press the ">" button on the very top of the P5.JS interface to run.
2. Press "a" to get into fullscreen mode.
3. Press "space" to generate a new Season/Reincarnation.
4. Mouse Left Click = increasing the rectangle thing
5. Mouse Middle Click = increasing the circle thing
6. Mouse Drag Right Click = terminate all things targeted.
7. (Although Mouse is recommend) but, there is the Hand Tracking feature:
Sit in front of the desk with your computer or laptop, if your webcam is connected, the webcam can track your hand. When pinching your index and thumb fingers (one hand at a time), it does the same thing as Mouse Drag Right Click to terminate all living things.
8. Press "ESC" to exit the Fullscreen mode.
6. You can check the video here: https://vimeo.com/467863317 for more details.
7. Even you leave it running, it will go through its iteration as reincarnation.
8. Thank you for playing it!
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License (CC BY-NC-ND 4.0) (https://creativecommons.org/licenses/by-nc-nd/4.0/) that You must give appropriate credit, you may not use the material for commercial purposes. If you remix, transform, or build upon the material (including the code), you may not distribute the modified material.
I own the copyright and all rights reserved forever.
Jia-Rey(Gary) Chang
*/
let newWorld;
let bloops = [];
let foods = [];
let foodEaten = 0;
//handTracking
let handpose;
let video;
let hands = [];
let predictions = [];
let hand;
let preindexX = 0;
let preindexY = 0;
let prethumbX = 0;
let prethumbY = 0;
let indexX = 100;
let indexY = 100;
let thumbX = 400;
let thumbY = 400;
let modelReadyShow = false;
let goCount = 0;
let generation = 0;
let pinch = 0;
/*
let colorSpring = false;
let colorSummer = false;
let colorAutumn = false;
let colorWinter = false;
*/
let colorWeather = 0;
let scaling = false;
function preload() {
handPose = ml5.handPose({ flipped: true });
}
function setup() {
//avoid right click browser window pop-up
for (let element of document.getElementsByClassName("p5Canvas")) {
element.addEventListener("contextmenu", (e) => e.preventDefault());
}
//
createCanvas(windowWidth, windowHeight);
print(width);
print(height);
//handTracking
video = createCapture(VIDEO);
video.size(windowWidth, windowHeight);
handPose.detectStart(video, gotHands);
// This sets up an event that fills the global variable "predictions"
// with an array every time new hand poses are detected
// Hide the video element, and just show the canvas
video.hide();
//
newWorld = new world(8, 100);
}
/*
function modelReady() {
console.log("Model ready!");
modelReadyShow = true;
}
*/
function windowResized() {
resizeCanvas(windowWidth, windowHeight);
}
function draw() {
background(0);
//stroke(255,0,0);
//strokeWeight(10);
//line(0,0,2560,1440);
//circle(2560,1440,200);
boundary();
newWorld.display();
push();
if(scaling){
push();
scale(2560/1080, 1440/720);
}else{
push();
scale(1,1);
}
//scale(-1,1);
//handTracking
//image(video, 0, 0, width, );
if (hands.length > 0) {
// Find the index finger tip and thumb tip
let finger = hands[0].index_finger_tip;
let thumb = hands[0].thumb_tip;
indexX = finger.x;
indexY = finger.y;
thumbX = thumb.x;
thumbY = thumb.y;
hand = dist(indexX, indexY, thumbX, thumbY);
if (abs(hand) < 80 && abs(hand) >= 0) {
//fill(255,0,0);
//ellipse((indexX+thumbX)/2, (indexY+thumbY)/2, 100, 100);
let targetX = (indexX + thumbX) / 2;
let targetY = (indexY + thumbY) / 2;
stroke(255);
strokeWeight(5);
point(indexX, indexY);
point(thumbX, thumbY);
stroke(0, random(180, 255), 250, 100);
if(scaling){
strokeWeight(8/2);
}else{
strokeWeight(8);
}
line(targetX, 0, targetX, height);
line(0, targetY, width, targetY);
strokeWeight(8);
stroke(255);
noFill();
rectMode(CENTER);
if(scaling){
ellipse(targetX, targetY, 30, 30);
}else{
ellipse(targetX, targetY, 60, 60);
}
noStroke();
for (let i = bloops.length - 1; i >= 0; i--) {
let killBloop = bloops[i];
if (
killBloop.location.x*1080/2560 < (targetX + 20) &&
killBloop.location.x*1080/2560 > (targetX - 20)
) {
bloops.splice(i, 1);
}
if (
killBloop.location.y*720/1440 < (targetY + 20) &&
killBloop.location.y*720/1440 > (targetY - 20)
) {
bloops.splice(i, 1);
}
}
for(let i=0; i<foods.length; i++){
let killfood = foods[i];
if(killfood.location.x*1080/2560 < (targetX + 20) &&
killfood.location.x*1080/2560 > (targetX - 20)
){
foods.splice(i, 1);
}
if(killfood.location.y*720/1440 < (targetY + 20) &&
killfood.location.y*720/1440 > (targetY - 20)
){
foods.splice(i, 1);
}
}
}
}
// We can call both functions to draw all keypoints and the skeletons
//drawKeypoints();
//fill(255,0,0);
//
pop();
//if (foodEaten > 30 && bloops.length >= 5) {
if (foodEaten > 30) {
let newFood = new food(random(windowWidth), random(windowHeight));
foods.push(newFood);
//foodEaten = 0;
}
for (let i = 0; i < bloops.length; i++) {
let birthBloop = bloops[i];
if (birthBloop.health > 300) {
let originalDNA = new DNA();
let newBloop = new bloop(originalDNA);
newBloop.location.x = birthBloop.location.x;
newBloop.location.y = birthBloop.location.y;
bloops.push(newBloop);
birthBloop.health = birthBloop.health * 0.5;
}
}
if (bloops.length <= 0 || foods.length <= 0) {
newWorld = new world(8, 100);
generation = generation + 1;
}
if (mouseIsPressed && mouseButton === RIGHT) {
stroke(0, random(180, 255), 250, 100);
strokeWeight(5);
line(mouseX, 0, mouseX, height);
line(0, mouseY, width, mouseY);
strokeWeight(8);
stroke(255);
noFill();
rectMode(CENTER);
ellipse(mouseX, mouseY, 60, 60);
noStroke();
strokeWeight(1);
for (let i = bloops.length - 1; i >= 0; i--) {
let killBloop = bloops[i];
if (
killBloop.location.x < mouseX + 20 &&
killBloop.location.x > mouseX - 20
) {
bloops.splice(i, 1);
}
if (
killBloop.location.y < mouseY + 20 &&
killBloop.location.y > mouseY - 20
) {
bloops.splice(i, 1);
}
}
for(let i=0; i<foods.length; i++){
let killfood = foods[i];
if(killfood.location.x < mouseX + 20 &&
killfood.location.x > mouseX - 20
){
foods.splice(i, 1);
}
if(killfood.location.y < mouseY + 20 &&
killfood.location.y > mouseY - 20
){
foods.splice(i, 1);
}
}
}
/*
if(modelReadyShow == false){
textAlign(CENTER, CENTER);
textSize(120);
fill(255);
text(" READY", width/2, height/2);
}else{
if(goCount < 30){
textAlign(CENTER, CENTER);
textSize(150);
fill(255);
text(" GO!", width/2, height/2);
goCount = goCount + 1;
}
}
*/
let mode = generation%4
switch (generation%4) {
case 0:
colorWeather = 0;
break;
case 1:
colorWeather = 1;
break;
case 2:
colorWeather = 2;
break;
case 3:
colorWeather = 3;
break;
default:
}
}
// Callback function for when handPose outputs data
function gotHands(results) {
// Save the output to the hands variable
hands = results;
}
function boundary() {
noFill();
if(colorWeather == 0){
stroke(0, 255, 0,);
}
else if(colorWeather == 1){
stroke(0, 249, 255);
}
else if(colorWeather == 2){
stroke(233, 240, 63);
}
else{
stroke(87, 126, 155);
}
rectMode(CENTER);
rect(width / 2, height / 2, width - 20, height - 20);
noStroke();
for (let j = 0; j < height; j += 250) {
for (let i = 0; i < width; i += 250) {
stroke(255, 10);
line(i, 0, i, height);
line(0, j, width, j);
}
}
}
function keyPressed() {
if (key === " ") {
newWorld = new world(10, 100);
generation = generation + 1;
}
if (key == "a") {
let fs = fullscreen();
fullscreen(!fs);
scaling = (!scaling);
}
}
function mouseDragged() {
if (mouseButton === LEFT) {
let addFood = new food(mouseX, mouseY);
foods.push(addFood);
}
}
function mousePressed() {
if (mouseButton === LEFT) {
let addFood = new food(mouseX, mouseY);
foods.push(addFood);
}
if (mouseButton === CENTER) {
let originalDNA = new DNA();
let newBloop = new bloop(originalDNA);
newBloop.location.x = mouseX;
newBloop.location.y = mouseY;
bloops.push(newBloop);
}
}
//handTracking
// A function to draw ellipses over the detected keypoints
function drawKeypoints() {
for (let i = 0; i < predictions.length; i += 1) {
const prediction = predictions[i];
const keypointIn = prediction.landmarks[8];
const keypointTh = prediction.landmarks[4];
preindexX = keypointIn[0];
preindexY = keypointIn[1];
prethumbX = keypointTh[0];
prethumbY = keypointTh[1];
indexX = lerp(indexX, preindexX, 0.1);
indexY = lerp(indexY, preindexY, 0.1);
thumbX = lerp(thumbX, prethumbX, 0.1);
thumbY = lerp(thumbY, prethumbY, 0.1);
/*
for (let j = 0; j < prediction.landmarks.length; j += 1) {
const keypoint = prediction.landmarks[j];
fill(200,200,0);
noStroke();
ellipse(keypoint[0], keypoint[1], 5, 5);
}
*/
}
}