We are trying to create an interactive video player, which contains 10 short video files, but it has to have a certain functionality: 1st video playing automatically from beginning. Once it is finished, the user must chose by an arrow click, which video to play next - there's two options. Once chosen option of video is finished to play, next video must start to play automatically. Once this video is done playing, there must be another choice between two other videos, just as the first time, and it goes on, till it ends by 10th video playing automatically.
There's two major problems - after first video being played and first choice being done, third video, that suppose to play automatically, doesn't play and the whole application gets stuck. Also, while the first default video is playing, keys pressed are triggering other two videos to play, meanwhile they suppose to play ONLY when the first video is done playing.
To make it more understandable, the structure of video playing order and interactivity points, here's the illustration of it:
We hope we formulate the problem so it is easy to understand. Any help or tips would be highly appreciated.
import processing.video.*;
Movie [] mov = new Movie [10];
Boolean playMovie0 = true;
Boolean playMovie1 = false;
Boolean playMovie2 = false;
Boolean playMovie3 = false;
Boolean playMovie4 = false;
Boolean playMovie5 = false;
Boolean playMovie6 = false;
Boolean playMovie7 = false;
Boolean playMovie8 = false;
Boolean playMovie9 = false;
void setup (){
size (810, 540);
mov [0] = new Movie (this, "Vid0.mp4");
mov [1] = new Movie (this, "Vid1.mp4");
mov [2] = new Movie (this, "Vid2.mp4");
mov [3] = new Movie (this, "Vid3.mp4");
mov [4] = new Movie (this, "Vid4.mp4");
mov [5] = new Movie (this, "Vid5.mp4");
mov [6] = new Movie (this, "Vid6.mp4");
mov [7] = new Movie (this, "Vid7.mp4");
mov [8] = new Movie (this, "Vid8.mp4");
mov [9] = new Movie (this, "Vid9.mp4");
mov[0].play();
}
void draw (){
if (playMovie0 == true){
image(mov[0], 0, 0, width, height);
if (mov[0].time() >= mov[0].duration()){
mov[0].stop();
playMovie0 =false;
}
if (key == CODED){
if (keyCode == LEFT){
playMovie1 = true;
mov[1].play();
image(mov[1], 0, 0, width, height);
} else if (keyCode == RIGHT){
playMovie2 = true;
mov[2].play();
image(mov[2], 0, 0, width, height);
}
}
}
if (mov[1].time() >= mov[1].duration()){
mov[1].stop();
playMovie1 = false;
playMovie3 = true;
} else if (mov[2].time() >= mov[2].duration()){
mov[2].stop();
playMovie2 = false;
playMovie3 = true;
}
if (playMovie0 == false && playMovie1 == false && playMovie2 == false && playMovie3 == true){
mov[3].play();
image(mov[3], 0, 0, width, height);
if (mov[3].time() >= mov[3].duration()){
mov[3].stop();
playMovie3 = false;
}
if (key == CODED){
if (keyCode == LEFT){
playMovie4 = true;
mov[4].play();
image(mov[4], 0, 0, width, height);
} else if (keyCode == RIGHT){
playMovie5 = true;
mov[5].play();
image(mov[5], 0, 0, width, height);
}
}
}
if (mov[4].time() >= mov[4].duration()){
mov[4].stop();
playMovie4 = false;
playMovie6 = true;
} else if (mov[5].time() >= mov[5].duration()){
mov[5].stop();
playMovie5 = false;
playMovie6 = true;
}
if (playMovie0 == false && playMovie1 == false && playMovie2 == false &&
playMovie3 == false && playMovie4 == false && playMovie5 == false && playMovie6 == true) {
mov[6].play();
image(mov[6], 0, 0, width, height);
if (mov[6].time() >= mov[6].duration()){
mov[6].stop();
playMovie6 = false;
}
if (key == CODED){
if (keyCode == LEFT){
playMovie7 = true;
mov[7].play();
image(mov[7], 0, 0, width, height);
} else if (keyCode == RIGHT){
playMovie8 = true;
mov[8].play();
image(mov[8], 0, 0, width, height);
}
}
}
if (mov[7].time() >= mov[7].duration()){
mov[7].stop();
playMovie7 = false;
playMovie9 = true;
} else if (mov[8].time() >= mov[8].duration()){
mov[8].stop();
playMovie8 = false;
playMovie9 = true;
}
if (playMovie0 == false && playMovie1 == false && playMovie2 == false &&
playMovie3 == false && playMovie4 == false && playMovie5 == false &&
playMovie6 == false && playMovie7 == false && playMovie8 == false && playMovie9 == true){
mov[9].play();
image(mov[9], 0, 0, width, height);
}
}
void movieEvent (Movie m)
{
m.read();
}
Please carefully read this similar answer on the topic of playing back a list of videos. It covers a couple of handy tips such as not repeating yourself and using arrays.
The only part that makes your question different is managing states, which at the moment are at least 3:
playing an automatic video
presenting a next video select screen
playing a selected video
These states alternate until the end of the playlist is reached.
This is known as a finite state machine and making one isn't as hard as it may seem. There a few 'ingredients' you'll need:
A variable to keep track of the current state
A list of variables for each separate state;
Once you have these, you simply need to check what the current state is and based on the decisions available in this state, select the next.
For example in the automatic video playing, a decision can be made at the end of the video:
is it the last video
if not, go to the select screen
On the select screen, the decision is based on key input:
if left is pressed, play the next video
if right is pressed, play the 2nd video after the current
and so on.
Here is this concept as code, with comments explaining each part:
import processing.video.*;
int numMovies = 10;//total number of movies
Movie [] mov = new Movie [numMovies];//a list of all the movie objects, currently not initialized
int currentMovieIndex = 0;//index of the movie currently playing
int movieIndexOffset;//the offset in index between the selected/automatic movies (skip 1 or 2 videos?)
//application states
int STATE_WAITING_FOR_KEY = 0;
int STATE_PLAYING_SELECTED_MOVIE = 1;
int STATE_PLAYING_AUTOMATIC_MOVIE = 2;
int currentState = STATE_PLAYING_AUTOMATIC_MOVIE;
//just for debugging:
String[] stateLabels = {"waiting for key","playing selected movie","playing automatic movie"};
//a 'magic number' helpful to find out when a movie finishes playing
float movieEndDuration = 0.039719;
String selectScreenText = "Use the left or right keys to select the next video";
void setup (){
size (810, 540);
noStroke();
textSize(24);
for(int i = 0 ; i < numMovies; i++){
//initialize each movie object in the list
mov[i] = new Movie(this, "vid"+i+".mp4");
}
//start playback
mov[currentMovieIndex].play();
}
void draw (){
if(currentState == STATE_WAITING_FOR_KEY) drawWaitKeyState();
if(currentState == STATE_PLAYING_AUTOMATIC_MOVIE ||
currentState == STATE_PLAYING_SELECTED_MOVIE) drawMovie();
}
//rendering
void drawWaitKeyState(){
background(0);
text(selectScreenText,(width-textWidth(selectScreenText)) * 0.5,height * 0.5);
}
void drawMovie(){
background(0);
image(mov[currentMovieIndex],0,0);
}
//events
void keyReleased(){
if(currentState == STATE_WAITING_FOR_KEY){
if(keyCode == LEFT) {
movieIndexOffset = 1;//current movie index plus 1
playSelectedMovie();
}
if(keyCode == RIGHT) {
movieIndexOffset = 2;//current movie index plus 2
playSelectedMovie();//current movie index plus 2
}
}
}
/*
A - auto
S - selected
movie index type: A - S - A - S - A - S - A
movie index: 0 - 1 - 3 - 4 - 6 - 7 - 9
- 2 / 5 / - 8 /
*/
void playSelectedMovie(){
currentState = STATE_PLAYING_SELECTED_MOVIE;
currentMovieIndex += movieIndexOffset;
mov[currentMovieIndex].play();
println("selection made, playing movie at index " + currentMovieIndex);
}
void movieEvent (Movie m)
{
if(currentState == STATE_PLAYING_AUTOMATIC_MOVIE || currentState == STATE_PLAYING_SELECTED_MOVIE){
m.read();
//handy for debugging movie end
// println(m.time() + " / " + m.duration() + " / " + (m.time() + movieEndDuration));
//hacky check movie end
if((m.time() + movieEndDuration) >= m.duration()){
println("movie at index " + currentMovieIndex + " finished playback, current state: " + stateLabels[currentState]);
//if the current state is an automatic video, the next state will be a choice screen
if(currentState == STATE_PLAYING_AUTOMATIC_MOVIE) {
//if it's not the last movie
if(currentMovieIndex < numMovies-1){
currentState = STATE_WAITING_FOR_KEY;
}else{
println("all movies finished playing, either reset to first movie or set an end screen");
}
}
//if the current state is a selected video, the next state will be an automatic video
if(currentState == STATE_PLAYING_SELECTED_MOVIE) {
currentState = STATE_PLAYING_AUTOMATIC_MOVIE;
//reverse 1 or 2 by subtracting from 3
//if the previous choice was to skip 2, automatically skip 1 ( 3 - 2 = 1), if the previous choice was to skip 1, automatically skip 2 ( 3 - 1 = 2)
int automaticOffset = 3 - movieIndexOffset;
currentMovieIndex += automaticOffset;
mov[currentMovieIndex].play();
println("automatically playing movie at index " + currentMovieIndex);
}
}
}
}
Related
I've coded an algorithm that can enter multiple trades based on several signals from different indicators. I am now trying to figure out how to close half of my open positions (partial close) when they've reached a target profit range and then add a trailing stop on the other half of those particular trades that have been closed.
Any ideas on how this can be done? The main issue I'm having is when it comes to writing a code that allows the EA to detect when an open order is the other half of a previously closed order.
Any advice will be much appreciated.
//CLOSING ORDER LOOP
int ticket = OrderTicket();
double orderlots = OrderLots();
for (int b = OrdersTotal() -1 ; b >=0 ;b--)
{
if (!OrderSelect (b, SELECT_BY_POS, MODE_TRADES))continue;
if (OrderSymbol() == Symbol() && OrderType() <= OP_SELL && NormalizeDouble(orderlots,1) == NormalizeDouble(lots, 1))
//CHECK PARTIAL CLOSE
{
if(OrderType() == OP_BUY && (Bid - OrderOpenPrice()) >= TakeProfit)
{
if(!OrderClose(ticket, orderlots/2, Bid, 3, Blue))
return;
}
else
{
if(OrderType() == OP_SELL && (OrderOpenPrice() - Ask) >= (TakeProfit))
{
if(!OrderClose(ticket, orderlots/2, Ask, 3, Blue))
{
bool answer = OrderSelect (b, SELECT_BY_POS, MODE_TRADES);
ticket = OrderTicket();
orderlots = OrderLots();
}
return;
//REDECLARE TICKETS
}
}
if (OrderSymbol() == Symbol() && OrderType() <= OP_SELL && NormalizeDouble(orderlots,1) != NormalizeDouble(lots, 1))continue;
//END
{
if(OrderType() == OP_BUY)
{
if(Bid - OrderOpenPrice() > stopLossATR)
{
if(!OrderModify(ticket, OrderOpenPrice(),Bid + (stopLossATR), OrderTakeProfit(), 0 , Green))
return;
}
}
else
if(OrderType() == OP_SELL)
{
if(OrderOpenPrice() - Ask > (stopLossATR))
{
if(!OrderModify(ticket, OrderOpenPrice(), Ask + (stopLossATR), OrderTakeProfit(), 0 , Green))
return;
if (!OrderSelect (b, SELECT_BY_POS, MODE_TRADES))continue;
}
}
}
}
}
I have an issue where 'at random' the character sometimes appears in the text box. This happens when I destroy the ftexture (text) and create a new sprite texture (Main character).
If anyone might have an idea why it does this? As I mentioned, it is a very rare occurrence and difficult to replicate reliably. When it happens, if I move my mouse over another hover able object, it then returns to normal again.
The code where this happens is here:
if (playerMessage != true && interactionMessage == "") {
if (gdSprite.x < gd && gdSprite.y < y || gdSprite.x > gd && gdSprite.y > y) {
playerIsMoving = 0;
}
else {
SDL_DestroyTexture(ftexture);
SDL_DestroyTexture(Textures::spriteTexture);
Textures::spriteTexture = SDL_CreateTextureFromSurface(renderer, Textures::spriteDown1);** //Makes player face you when you are hovering.**
}
interactionMessage = pob.HoverObjects(x, y, scene, gd, gy);
}
if (interactionMessage != "" && playerIsMoving !=1) {
pi.InteractionControllerHover(interactionMessage);
}
This appears to have fixed the problem. I nulled the ftexture after destroying it.
case SDL_MOUSEMOTION:
//Event Motion coordinates. Where the mouse moves on the screen.
x = event.motion.x;
y = event.motion.y;
gd = gdSprite.x;
gy = gdSprite.y;
if (event.motion.y > 589 && event.motion.x < 289 || event.motion.y == gy + 90 || event.motion.y == gy - 90 || event.motion.x == gd + 90 || event.motion.x == gd - 90) {
playerMessage = false;
}
//This addresses the movement to the left issue where the player never reaches to destination and prevents hover interaction.
if (playerMessage != true && interactionMessage == "") {
//Prevents sleep from kicking in when walking to a target.
if (gdSprite.x < gd && gdSprite.y < y || gdSprite.x > gd && gdSprite.y > y) {
playerIsMoving = 0;
}
else {
SDL_DestroyTexture(ftexture);
ftexture = nullptr;
SDL_DestroyTexture(Textures::spriteTexture);
Textures::spriteTexture = nullptr;
Textures::spriteTexture = SDL_CreateTextureFromSurface(renderer, Textures::spriteDown1); //Makes player face you when you are hovering.
}
interactionMessage = pob.HoverObjects(x, y, scene, gd, gy);
}
if (interactionMessage != "" && playerIsMoving !=1) {
pi.InteractionControllerHover(interactionMessage);
}
break;
case SDL_KEYDOWN:
switch (event.key.keysym.sym)
{
case SDLK_ESCAPE:
case SDLK_q:
gameover = 1;
break;
}
break;
}
}
Im trying to add settings to a snake game made in processing. I want to have something like easy, normal and hard or something along the lines of that and change the speed and maybe size of the grid. If anyone coudl explain how to id greatly appreciate it!
ArrayList<Integer> x = new ArrayList<Integer>(), y = new ArrayList<Integer>();
int w = 30, h = 30, bs = 20, dir = 2, applex = 12, appley = 10;
int[] dx = {0,0,1,-1}, dy = {1,-1,0,0};
boolean gameover = false;
void setup() {
size(600,600);
x.add(5);
y.add(5);
}
void draw() {
background(255);
for(int i = 0 ; i < w; i++) line(i*bs, 0, i*bs, height); //Vertical line for grid
for(int i = 0 ; i < h; i++) line(0, i*bs, width, i*bs); //Horizontal line for grid
for(int i = 0 ; i < x.size(); i++) {
fill (0,255,0);
rect(x.get(i)*bs, y.get(i)*bs, bs, bs);
}
if(!gameover) {
fill(255,0,0);
rect(applex*bs, appley*bs, bs, bs);
if(frameCount%5==0) {
x.add(0,x.get(0) + dx[dir]);
y.add(0,y.get(0) + dy[dir]);
if(x.get(0) < 0 || y.get(0) < 0 || x.get(0) >= w || y.get(0) >= h) gameover = true;
for(int i = 1; i < x.size(); i++) if(x.get(0) == x.get(i) && y.get(0) == y.get(i)) gameover = true;
if(x.get(0)==applex && y.get(0)==appley) {
applex = (int)random(0,w);
appley = (int)random(0,h);
}else {
x.remove(x.size()-1);
y.remove(y.size()-1);
}
}
} else {
fill(0);
textSize(30);
text("GAME OVER. Press Space to Play Again", 20, height/2);
if(keyPressed && key == ' ') {
x.clear(); //Clear array list
y.clear(); //Clear array list
x.add(5);
y.add(5);
gameover = false;
}
}
if (keyPressed == true) {
int newdir = key=='s' ? 0 : (key=='w' ? 1 : (key=='d' ? 2 : (key=='a' ? 3 : -1)));
if(newdir != -1 && (x.size() <= 1 || !(x.get(1) ==x.get(0) + dx[newdir] && y.get (1) == y.get(0) + dy[newdir]))) dir = newdir;
}
}
You need to break your problem down into smaller steps:
Step one: Can you store the difficulty in a variable? This might be an int that keeps track of a level, or a boolean that switches between easy and hard. Just hardcode the value of that variable for now.
Step two: Can you write your code so it changes behavior based on the difficulty level? Use the variable you created in step one. You might use an if statement to check the difficulty level, or maybe the speed increases over time. It's completely up to you. Start out with a hard-coded value. Change the value to see different behaviors.
Step three: Can you programatically change that value? Maybe this requires a settings screen where the user chooses the difficulty, or maybe it gets more difficult over time. But you have to do the first two steps before you can start this step.
If you get stuck on a specific step, then post an MCVE and we'll go from there.
I have this method here which renders my players movement. It swaps between 3 images, standing, left leg forward, and right leg forward.
It swaps images very fast so how can I change the speed of the rendering?
public static void renderUpwardWalking() {
ImageIcon[] frames = { CharacterSheet.up, CharacterSheet.upLeftLeg,
CharacterSheet.upRightLeg };
if (Key.up && Character.direction == "up") {
currentFrame++;
if (currentFrame == 3)
currentFrame = 1;
Character.character.setIcon(frames[currentFrame]);
} else if (!Key.up && Character.direction == "up") {
currentFrame = 0;
}
}
This is usually done on timer.
Decide on a frame pattern and a frequency. You seem to have chosen the frame pattern CharacterSheet.up, CharacterSheet.upLeftLeg, CharacterSheet.upRightLeg. Let's say you want to swap frame every 400 ms.
Get the time from a clock with sufficient resolution. System.nanoTime() is usually accurate enough.
long frameTime = 400L * 1000000L; // 400 ms in nanoseconds Edit
currentFrame = (System.nanoTime() / frametime) % frames.length;
You can change the scale of your currentFrame counter, and use its range to control your frame rate:
//Let this go from 1...30
int currentFrameCounter;
.
.
.
currentFrameCounter++;
if(currentFrameCounter == 30) currentFrameCounter = 0;
//Take a fraction of currentframeCounter for frame index ~ 1/10 frame rate
//Note care to avoid integer division
currentFrame = (int) (1.0*currentFrameCounter / 10.0);
Putting it all together in a general model:
int maxCounter = 30; //or some other factor of 3 -- controls speed
int currentFrameCounter;
public static void renderUpwardWalking() {
ImageIcon[] frames = { CharacterSheet.up, CharacterSheet.upLeftLeg,
CharacterSheet.upRightLeg };
if (Key.up && Character.direction == "up") {
currentFrameCounter++; //add
if(currentFrameCounter == maxCounter) currentFrameCounter = 0;
currentFrame = (int) (1.0*currentFrameCounter / (maxCounter/3.0));
Character.character.setIcon(frames[currentFrame]);
} else if (!Key.up && Character.direction == "up") {
currentFrame = 0;
}
}
I am developing an XNA game that is using Kinect. The player seen on the screen is the real image of the person who is playing in front of Kinect sensor. For eliminating the background and getting only the player's image I am doing these operations in kinect.AllFramesReady:
using (ColorImageFrame colorVideoFrame = imageFrames.OpenColorImageFrame())
{
if (colorVideoFrame != null)
{
//Getting the image of the colorVideoFrame to a Texture2D named colorVideo
}
//And setting its information on a Color array named colors with GetData
colorVideo.GetData(colors);
}
using (DepthImageFrame depthVideoFrame = imageFrames.OpenDepthImageFrame())
{
if (depthVideoFrame != null){
//Copying the the image to a DepthImagePixel array
//Using only the pixels with PlayerIndex > 0 to create a Color array
//And then setting the colors of this array from the 'colors' array by using MapDepthPointToColorPoint method, provided by Kinect SDK
//Finally I use SetData function in order to set the colors to a Texture2D I created before
}
}
But the performance is very low unsurprisingly. Because I have to use GetData for a color array with 640*480 = 307200 length (because of the ColorImageFormat) and SetData for another color array with 320*480 = 76800 length (because of the DepthImageFormat) in every frame!
I wonder if there is any other solutions for this problem, any alternatives for SetData and GetData maybe. Because I know that these functions moving data between the GPU and CPU and that is an expensive operation for big data. Thanks for any help.
The Kinect for Windows Toolbox comes with a "GreenScreen-WPF" example, which should provide some insight into processing the information. Because you are working in XNA there may be some differences, but the overall concepts should work between the two examples.
The example works by extracting multiple players. Here is the business end of the processing function:
private void SensorAllFramesReady(object sender, AllFramesReadyEventArgs e)
{
// in the middle of shutting down, so nothing to do
if (null == this.sensor)
{
return;
}
bool depthReceived = false;
bool colorReceived = false;
using (DepthImageFrame depthFrame = e.OpenDepthImageFrame())
{
if (null != depthFrame)
{
// Copy the pixel data from the image to a temporary array
depthFrame.CopyDepthImagePixelDataTo(this.depthPixels);
depthReceived = true;
}
}
using (ColorImageFrame colorFrame = e.OpenColorImageFrame())
{
if (null != colorFrame)
{
// Copy the pixel data from the image to a temporary array
colorFrame.CopyPixelDataTo(this.colorPixels);
colorReceived = true;
}
}
// do our processing outside of the using block
// so that we return resources to the kinect as soon as possible
if (true == depthReceived)
{
this.sensor.CoordinateMapper.MapDepthFrameToColorFrame(
DepthFormat,
this.depthPixels,
ColorFormat,
this.colorCoordinates);
Array.Clear(this.greenScreenPixelData, 0, this.greenScreenPixelData.Length);
// loop over each row and column of the depth
for (int y = 0; y < this.depthHeight; ++y)
{
for (int x = 0; x < this.depthWidth; ++x)
{
// calculate index into depth array
int depthIndex = x + (y * this.depthWidth);
DepthImagePixel depthPixel = this.depthPixels[depthIndex];
int player = depthPixel.PlayerIndex;
// if we're tracking a player for the current pixel, do green screen
if (player > 0)
{
// retrieve the depth to color mapping for the current depth pixel
ColorImagePoint colorImagePoint = this.colorCoordinates[depthIndex];
// scale color coordinates to depth resolution
int colorInDepthX = colorImagePoint.X / this.colorToDepthDivisor;
int colorInDepthY = colorImagePoint.Y / this.colorToDepthDivisor;
// make sure the depth pixel maps to a valid point in color space
// check y > 0 and y < depthHeight to make sure we don't write outside of the array
// check x > 0 instead of >= 0 since to fill gaps we set opaque current pixel plus the one to the left
// because of how the sensor works it is more correct to do it this way than to set to the right
if (colorInDepthX > 0 && colorInDepthX < this.depthWidth && colorInDepthY >= 0 && colorInDepthY < this.depthHeight)
{
// calculate index into the green screen pixel array
int greenScreenIndex = colorInDepthX + (colorInDepthY * this.depthWidth);
// set opaque
this.greenScreenPixelData[greenScreenIndex] = opaquePixelValue;
// compensate for depth/color not corresponding exactly by setting the pixel
// to the left to opaque as well
this.greenScreenPixelData[greenScreenIndex - 1] = opaquePixelValue;
}
}
}
}
}
// do our processing outside of the using block
// so that we return resources to the kinect as soon as possible
if (true == colorReceived)
{
// Write the pixel data into our bitmap
this.colorBitmap.WritePixels(
new Int32Rect(0, 0, this.colorBitmap.PixelWidth, this.colorBitmap.PixelHeight),
this.colorPixels,
this.colorBitmap.PixelWidth * sizeof(int),
0);
if (this.playerOpacityMaskImage == null)
{
this.playerOpacityMaskImage = new WriteableBitmap(
this.depthWidth,
this.depthHeight,
96,
96,
PixelFormats.Bgra32,
null);
MaskedColor.OpacityMask = new ImageBrush { ImageSource = this.playerOpacityMaskImage };
}
this.playerOpacityMaskImage.WritePixels(
new Int32Rect(0, 0, this.depthWidth, this.depthHeight),
this.greenScreenPixelData,
this.depthWidth * ((this.playerOpacityMaskImage.Format.BitsPerPixel + 7) / 8),
0);
}
}
If you are interested in only a single player, you could look into using the player mask to more quickly extract the appropriate pixel set. You'd fi
using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
{
if (skeletonFrame != null && skeletonFrame.SkeletonArrayLength > 0)
{
if (_skeletons == null || _skeletons.Length != skeletonFrame.SkeletonArrayLength)
{
_skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
}
skeletonFrame.CopySkeletonDataTo(_skeletons);
// grab the tracked skeleton and set the playerIndex for use pulling
// the depth data out for the silhouette.
this.playerIndex = -1;
for (int i = 0; i < _skeletons.Length; i++)
{
if (_skeletons[i].TrackingState != SkeletonTrackingState.NotTracked)
{
this.playerIndex = i+1;
}
}
}
}
You can then step through the depth data to extract the appropriate bits:
depthFrame.CopyPixelDataTo(this.pixelData);
for (int i16 = 0, i32 = 0; i16 < pixelData.Length && i32 < depthFrame32.Length; i16++, i32 += 4)
{
int player = pixelData[i16] & DepthImageFrame.PlayerIndexBitmask;
if (player == this.playerIndex)
{
// the player we are tracking
}
else if (player > 0)
{
// a player, but not the one we want.
}
else
{
// background or something else we don't care about
}
}
I'm pulling this code from a control I use to produce a silhouette, so it does not deal with the color stream. However, making a call to MapDepthFrameToColorFrame at the appropriate time should allow you to deal with the color stream data and extract the corresponding pixels to the player's mask.