We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I have been stuck at one point for a little while, which is how to do collision detection with ellipses and images.
I'm trying to make a kinect game with skeleton calibration. With six boxes on both sides, changing color, user has to put any of left,right hand or left, right foot to extend to the colored boxes on the side to finish each round.
I've attached two photos of screenshot for a better understanding.
I believe most of the functional stuff is done here but I just can't find out how I can make ellipses(on LRhand,LRfoot) to detect the buttons on both sides. Once it detects all color-changed buttons being collided with ellipses(LRhand,LRfoot), it needs to be able to up the round by 1 and followed by the next round buttons.
I've tried using dist() but it doesn't seem to work well or maybe I'm just not too expert enough to do it.
EVEN A LITTLE BIT OF HELP WILL BE VERY APPRECIATED! THANKS!
To get a better idea, the following is my code:
import SimpleOpenNI.*;
SimpleOpenNI kinect;
PFont font;
String time = "60";
int t;
int interval = 60;
int stage = 1;
void setup() {
size(640, 480);
kinect = new SimpleOpenNI(this);
kinect.enableDepth();
// turn on user tracking
kinect.enableUser();
font = createFont("Arial", 30);
PImage depth = kinect.depthImage();
fill(0);
}
void draw() {
kinect.update();
PImage depth = kinect.depthImage();
image(depth, 0, 0);
// make a vector of ints to store the list of users
IntVector userList = new IntVector();
// write the list of detected users into our vector
kinect.getUsers(userList);
// if we found any users
if (userList.size() > 0) {
// get the first user
int userId = userList.get(0);
// if we’re successfully calibrated
if (stage == 1) {
if (kinect.isTrackingSkeleton(userId) == false){
text("ARE YOU FLEXIBLE ENOUGH?!", width/2 - 100, height/2 - 200);
text("please calibrate to start the game!", width/2 - 100, height/2);
}
}
if ( kinect.isTrackingSkeleton(userId) == true && stage == 1){
stage = 2;
}
if(stage == 2){
t = interval-int(millis()/1000);
time = nf(t , 3);
fill(255);
if(t <= 10){
fill(255,0,0);
}
if(t == 0){
text("GAMEOVER", width/2 - 100, height/2 - 150);
println("GAME OVER");
noLoop();
interval+=60;}
text(time, width/2, height/2 - 130);
}
float dL = 100;
float dR = 100;
// check if the skeleton is being tracked
if (kinect.isTrackingSkeleton(1))
{
drawLHand(1);
drawRHand(1);
drawRFoot(1);
drawLFoot(1);
// get the distance between joints
PVector pL = new PVector(-500, 0, 1000);
PVector pR = new PVector(500, 0, 1000);
float handDistanceL = getJointDistance(1, SimpleOpenNI.SKEL_LEFT_HAND, pL);
float handDistanceR = getJointDistance(1, SimpleOpenNI.SKEL_LEFT_HAND, pR);
dL = map(handDistanceL, 0, 2000, 0, height);
dR = map(handDistanceR, 0, 2000, 0, height);
}
println(dL + ", " + dR);
int round = 0;
int score = 0;
PImage button1,button1p,button2,button2p,button3,button3p,button4,button4p;
button1 = loadImage("button1.jpg");
button1p = loadImage("button1p.jpg");
button2 = loadImage("button2.jpg");
button2p = loadImage("button2p.jpg");
button3 = loadImage("button3.jpg");
button3p = loadImage("button3p.jpg");
button4 = loadImage("button4.jpg");
button4p = loadImage("button4p.jpg");
if (kinect.isTrackingSkeleton(1) == true){
round = 1;
image(button1p,width/2 - 320, height/2 -190);
image(button3,width/2 - 320, height/2 -57);
image(button1,width/2 - 320, height/2 +76);
image(button4,width/2 + 220, height/2 -190);
image(button2,width/2 + 220, height/2 -57);
image(button4,width/2 + 220, height/2 +76);
score += 0;
text("score: " + score, 30, 10);
text("round: " + round, 30, 40);
}
if(round == 2){
image(button1p,width/2 - 320, height/2 -190);
image(button3,width/2 - 320, height/2 -57);
image(button1,width/2 - 320, height/2 +76);
image(button4p,width/2 + 220, height/2 -190);
image(button2,width/2 + 220, height/2 -57);
image(button4,width/2 + 220, height/2 +76);
score += 20;
}
if(round == 3){
image(button1p,width/2 - 320, height/2 -190);
image(button3p,width/2 - 320, height/2 -57);
image(button1,width/2 - 320, height/2 +76);
image(button4,width/2 + 220, height/2 -190);
image(button2,width/2 + 220, height/2 -57);
image(button4,width/2 + 220, height/2 +76);
score += 40;
}
if(round == 4){
image(button1p,width/2 - 320, height/2 -190);
image(button3,width/2 - 320, height/2 -57);
image(button1,width/2 - 320, height/2 +76);
image(button4p,width/2 + 220, height/2 -190);
image(button2,width/2 + 220, height/2 -57);
image(button4p,width/2 + 220, height/2 +76);
score += 40;
}
if(round == 5){
image(button1p,width/2 - 320, height/2 -190);
image(button3,width/2 - 320, height/2 -57);
image(button1p,width/2 - 320, height/2 +76);
image(button4,width/2 + 220, height/2 -190);
image(button2p,width/2 + 220, height/2 -57);
image(button4,width/2 + 220, height/2 +76);
score += 60;
}
if(round == 6){
image(button1p,width/2 - 320, height/2 -190);
image(button3,width/2 - 320, height/2 -57);
image(button1,width/2 - 320, height/2 +76);
image(button4p,width/2 + 220, height/2 -190);
image(button2,width/2 + 220, height/2 -57);
image(button4p,width/2 + 220, height/2 +76);
score += 60;
}
if(round == 7){
image(button1p,width/2 - 320, height/2 -190);
image(button3,width/2 - 320, height/2 -57);
image(button1p,width/2 - 320, height/2 +76);
image(button4p,width/2 + 220, height/2 -190);
image(button2,width/2 + 220, height/2 -57);
image(button4p,width/2 + 220, height/2 +76);
score += 80;
}
if(round == 8){
image(button1p,width/2 - 320, height/2 -190);
image(button3,width/2 - 320, height/2 -57);
image(button1p,width/2 - 320, height/2 +76);
image(button4p,width/2 + 220, height/2 -190);
image(button2p,width/2 + 220, height/2 -57);
image(button4,width/2 + 220, height/2 +76);
score += 100;
}
if ( kinect.isTrackingSkeleton(userId) == false) {
image(button1,width/2 - 320, height/2 -190);
image(button3,width/2 - 320, height/2 -57);
image(button1,width/2 - 320, height/2 +76);
image(button4,width/2 + 220, height/2 -190);
image(button2,width/2 + 220, height/2 -57);
image(button4,width/2 + 220, height/2 +76);
}
if ( kinect.isTrackingSkeleton(userId)) {
drawSkeleton(userId);
stage = 2;
}
}
}
// draw the skeleton with the selected joints
void drawSkeleton(int userId)
{
// draw limbs
kinect.drawLimb(userId, SimpleOpenNI.SKEL_HEAD, SimpleOpenNI.SKEL_NECK);
kinect.drawLimb(userId, SimpleOpenNI.SKEL_NECK, SimpleOpenNI.SKEL_LEFT_SHOULDER);
kinect.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_SHOULDER, SimpleOpenNI.SKEL_LEFT_ELBOW);
kinect.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_ELBOW, SimpleOpenNI.SKEL_LEFT_HAND);
kinect.drawLimb(userId, SimpleOpenNI.SKEL_NECK, SimpleOpenNI.SKEL_RIGHT_SHOULDER);
kinect.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_SHOULDER, SimpleOpenNI.SKEL_RIGHT_ELBOW);
kinect.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_ELBOW, SimpleOpenNI.SKEL_RIGHT_HAND);
kinect.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_SHOULDER, SimpleOpenNI.SKEL_TORSO);
kinect.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_SHOULDER, SimpleOpenNI.SKEL_TORSO);
kinect.drawLimb(userId, SimpleOpenNI.SKEL_TORSO, SimpleOpenNI.SKEL_LEFT_HIP);
kinect.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_HIP, SimpleOpenNI.SKEL_LEFT_KNEE);
kinect.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_KNEE, SimpleOpenNI.SKEL_LEFT_FOOT);
kinect.drawLimb(userId, SimpleOpenNI.SKEL_TORSO, SimpleOpenNI.SKEL_RIGHT_HIP);
kinect.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_HIP, SimpleOpenNI.SKEL_RIGHT_KNEE);
kinect.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_KNEE, SimpleOpenNI.SKEL_RIGHT_FOOT);
}
// Event-based Methods
void onNewUser(SimpleOpenNI curContext, int userId)
{
println("onNewUser - userId: " + userId);
println("\tstart tracking skeleton");
curContext.startTrackingSkeleton(userId);
}
void onLostUser(SimpleOpenNI curContext, int userId)
{
println("onLostUser - userId: " + userId);
}
void drawRHand( int userID) {
PVector leftHand = new PVector();
float confidence = kinect.getJointPositionSkeleton(userID, SimpleOpenNI.SKEL_RIGHT_HAND, leftHand);
PVector convertedLeftHand = new PVector();
kinect.convertRealWorldToProjective(leftHand, convertedLeftHand);
fill(255,0,0);
float ellipseSizee = map(convertedLeftHand.z, 700, 2500, 50, 1);
ellipse(convertedLeftHand.x, convertedLeftHand.y, ellipseSizee, ellipseSizee);
}
void drawLHand(int userID) {
// make a vector to store the left hand
PVector rightHand = new PVector();
// put the position of the left hand into that vector
float confidencee = kinect.getJointPositionSkeleton(userID, SimpleOpenNI.SKEL_LEFT_HAND, rightHand);
// convert the detected hand position to "projective" coordinates that will match the depth image
PVector convertedRightHand = new PVector();
kinect.convertRealWorldToProjective(rightHand, convertedRightHand);
// and display it
fill(255, 100, 0);
float ellipseSize = map(convertedRightHand.z, 700, 2500, 50, 1);
ellipse(convertedRightHand.x, convertedRightHand.y, ellipseSize, ellipseSize);
}
void drawRFoot( int userID) {
PVector leftFoot = new PVector();
float confidence = kinect.getJointPositionSkeleton(userID, SimpleOpenNI.SKEL_RIGHT_FOOT, leftFoot);
PVector convertedLeftFoot = new PVector();
kinect.convertRealWorldToProjective(leftFoot, convertedLeftFoot);
fill(255,0,0);
float ellipseSizeee = map(convertedLeftFoot.z, 700, 2500, 50, 1);
ellipse(convertedLeftFoot.x, convertedLeftFoot.y, ellipseSizeee, ellipseSizeee);
}
void drawLFoot( int userID) {
PVector rightFoot = new PVector();
float confidence = kinect.getJointPositionSkeleton(userID, SimpleOpenNI.SKEL_LEFT_FOOT, rightFoot);
PVector convertedRightFoot = new PVector();
kinect.convertRealWorldToProjective(rightFoot, convertedRightFoot);
fill(255,0,0);
float ellipseSizeee = map(convertedRightFoot.z, 700, 2500, 50, 1);
ellipse(convertedRightFoot.x, convertedRightFoot.y, ellipseSizeee, ellipseSizeee);
}
// prints out the distance between any two joints
float getJointDistance(int userId, int joint1Id, PVector v)
{
float d = 0; // to store final distance value
// two PVectors to hold the position of two joints
PVector joint1 = new PVector();
// get 3D position of both joints
kinect.getJointPositionSkeleton(userId, joint1Id, joint1);
d = distance3D(joint1, v); // calculate the distance between the two joints
return d;
}
// calculate the distance between any two points in 3D space and return it as a float
float distance3D(PVector point1, PVector point2)
{
float diff_x, diff_y, diff_z; // to store differences along x, y and z axes
float distance; // to store final distance value
// calculate the difference between the two points
diff_x = point1.x - point2.x;
diff_y = point1.y - point2.y;
diff_z = point1.z - point2.z;
// calculate the Euclidean distance between the two points
distance = sqrt(pow(diff_x, 2)+pow(diff_y, 2)+pow(diff_z, 2));
return distance; // return the distance as a float
}
Answers
have you try using a regular webcam rather then the kinect ?
if you want to see whether a point is within a rectangle then it's just a case of
you know the positions and sizes of the boxes and you know the positions of the foot / hand...
DON'T load images within draw(). draw executes 60 times a second. do it in setup().