How do I loop through a set of 10 images more than once? - loops

I have a code block in cocos2d that creates a background by cycling through a set of 10 images like so:
- (void)addBackground{
CGSize winSize = [CCDirector sharedDirector].winSize;
//Add images to batchNode
float maxReach = 0;
for (int imageNumber=1; imageNumber < 13; imageNumber++) {
CCLOG(#"Adding image intro%d.png to the introAnimation.",imageNumber);
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
CCSprite *background = [CCSprite spriteWithFile:[NSString stringWithFormat:#"national_scenery_part%d-iPad.png",imageNumber]];
background.position = ccp((winSize.width/2)+maxReach, winSize.height/2);
[self addChild:background z:0];
maxReach = maxReach + background.contentSize.width;
} else {
CCSprite *background = [CCSprite spriteWithFile:[NSString stringWithFormat:#"national_scenery_part%d.png",imageNumber]];
background.position = ccp((winSize.width/2)+maxReach, winSize.height/2);
[self addChild:background z:0];
maxReach = maxReach + background.contentSize.width;
}
}
}
But of course it only loops once. I'd like it to loop 3 times. I was thinking of setting an integer to 0 and add 1 at the end of each loop and then run it again until it reaches 3. Does that sound like the best way to do this?

You can use nested FOR/WHILE loop for repeating it 3 times.
It should work well. I don't see any issue using this.

Related

Flash as3: Making ennemies with the same IA move differently from each other

So I'm making a game (at least trying to) and I have some ennemies that I spawn at a random position, and then I put them in an array. Then a function in a loop enterframe make the ennemies in that array move randomly around the map. So their movements are random, but they are all sync so they make the same patern of moves at the same time. I'm trying tu figure out how to make them move differently, or at least spawn with a random delay so that they are not all sync. That might be a basic question but I'm trying to make a game with what I currently understand and am able to explain, so I would really appreciate your explanations and advices.
Here is my code (with some of my french notes in it sorry about that, but i need to remember stuff so I can explain them in the test :d)
So the ennemies are the Dementors, from a movieclip "DementorAllSprite" which contains sprites of the ennemy facing different directions
Here is the code out of the loop enterframe
//set up var Dementor and array
//duration: random number between 0 et 150
//Facing: random number arrondi en dessous, donc entre 0 et 3
var DementorTimer = 0;
var DementorDuration = Math.random() * 150;
var DementorFacing: Number = Math.floor(Math.random() * 4);
var DementorSpeed: Number = 13;
var enemies_arr:Array = [];
Here is the loop function
PlayContainer.addEventListener(Event.ENTER_FRAME, PlayLoop);
function PlayLoop(loopEvent:Event):void
{
addDementor();
moveDementor();
function addDementor():void
{
//max number of ennemies
if(enemies_arr.length < 20)
{
//add le dementor if conditions check
var Dementor:DementorAllSprite = new DementorAllSprite();
//positions random on a grass container
var startX:int = Math.random() * 5760;
var startY:int = Math.random() * 3600 ;
Dementor.x = startX;
Dementor.y = startY;
//add Dementor to grass container and set their transparency (they gain alpha when they hit the Player )
GrassContainer.addChild(Dementor);
Dementor.alpha=0.4;
//store the object in an array
enemies_arr.push(Dementor);
}
}
//---Mouvements Dementors---//
//Timer = 0, Duration entre 0 et 25, chaque loop rajoute 1 au timer (DementorTimer ++;)
//jusqu'a ce que le if ne match plus, puis reset
//Facing mvmt: 0= back / 1= front / 2= right / 3= left
//Frames Dementor: 1= front / 2= back / 3= left / 4= right
//switch = if, else if, else if, ....
function moveDementor():void
{
//check les dementors de l'array (de 0 a leur nombre)
for (var j:int = 0; j < enemies_arr.length; j++)
{
if (DementorTimer < DementorDuration)
{
switch (DementorFacing)
{
case 0 :
enemies_arr[j].y-=DementorSpeed;
enemies_arr[j].gotoAndStop(2)
break;
case 1 :
enemies_arr[j].y+=DementorSpeed;
enemies_arr[j].gotoAndStop(1)
break;
case 2 :
enemies_arr[j].x+=DementorSpeed;
enemies_arr[j].gotoAndStop(4)
break;
case 3 :
enemies_arr[j].x-=DementorSpeed;
enemies_arr[j].gotoAndStop(3)
}
DementorTimer++;
}
//reset
else
{
DementorDuration = Math.random() * 150;
DementorFacing = Math.floor(Math.random() * 4);
DementorTimer = 0;
}
}
}
}
Also the dementors movement are pretty short since i put them in an array (originally there was only 1 and he did move like a lot before changing direction, now they change position pretty fast, i augmented the Duration to 150 ( it was way down before) and there a was a little change, but that's still weird)
Anyway thanks for your help and your attention
Well, I guess you need a few tweaks and changes.
var DList:Array = ["up", "down", "left", "right"];
var DHash:Object =
{
"up": {"frame":2, "x": 0, "y":-1},
"down": {"frame":1, "x": 0, "y": 1},
"left": {"frame":3, "x":-1, "y": 0},
"right": {"frame":4, "x": 1, "y": 0}
}
// Decides how many steps Dementor should take before next reset.
function resetDementor(target:DementorAllSprite):void
{
target.stepsLeft = int(10 + 10 * Math.random());
}
// Turns Dementor to a random direction.
function randomDirection(target:DementorAllSprite):void
{
target.direction = DList[int(DList.length * Math.random())];
target.gotoAndStop(DHash[target.direction]['frame']);
}
PlayContainer.addEventListener(Event.ENTER_FRAME, PlayLoop);
// First of all, for goodness sake, don't define functions inside functions.
function PlayLoop(e:Event):void
{
if (enemies_arr.length < 20) addDementor();
moveDementor();
}
function addDementor():void
{
//add le dementor if conditions check
var Dementor:DementorAllSprite = new DementorAllSprite();
//positions random on a grass container
var startX:int = Math.random() * 5760;
var startY:int = Math.random() * 3600 ;
Dementor.x = startX;
Dementor.y = startY;
// I guess DementorAllSprite is a MovieClip.
// Otherwise you need to add stepsLeft:int and direction:String to the class definition.
randomDirection(Dementor);
resetDementor(Dementor);
//add Dementor to grass container and set their transparency (they gain alpha when they hit the Player )
GrassContainer.addChild(Dementor);
Dementor.alpha=0.4;
//store the object in an array
enemies_arr.push(Dementor);
}
function moveDementor():void
{
//check les dementors de l'array (de 0 a leur nombre)
for (var j:int = 0; j < enemies_arr.length; j++)
{
// Get the reference to Dementor.
var Dementor:DementorAllSprite = enemies_arr[j];
// Check if Dementor needs a reset.
if (Dementor.stepsLeft < 0)
{
randomDirection(Dementor);
resetDementor(Dementor);
}
// Get the directions object with regard to Dementor's direction.
var aDir:Object = DHash[Dementor.direction];
// Move the Dementor.
Dementor.x += aDir['x'] * DementorSpeed;
Dementor.y += aDir['y'] * DementorSpeed;
// Reduce the number of steps to go.
Dementor.stepsLeft--;
}
}

Infinite execution of the code in google apps script

I have this code wich runs infinitly. I checked step by step and the error is in the last part of it where there is a loop.
I have in cell(f,3) the value 400 and respectively in cell(f,4) cell(f-1,4) cell(f-2,4) cell(f-3,4) : 200, 50, 20, 100
The cell(f,12) should show the value 270.
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Feuille 1");
var active = sheet.getActiveCell();
var f = active.getRowIndex();
var r = sheet.getRange(f,3).getValues();
var i = f
var cellule = sheet.getRange(i,4).getValues();
var C = 0
do {
C = C + cellule;
var destverif = sheet.getRange(f,12);
destverif.setValue(C);
i = i-1;
}while (C + cellule <= r);
}
You are using getValues() instead of getValue() which returns an array. Your while condition is essentially checking while(NaN + [["200"]] <= [["400"]]) which will not really work out, it seems as though it was returning true and you had a loop that was essentially while(true).
To correct this, use getValue() instead. This immediately corrects your infinite loop.
I chatted with you over gchat and determined your logic was also faulty for the output you expected. You are trying to take a set of data like this:
Get the value of the highlighted column starting at 200 and going up till your total is greater than or equal to 400. Once it hits this value, write into column 12 of that row 400 / AVERAGE(200,100,101)
I corrected your code, this code does the trick:
function getValues(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Feuille 1");
var active = sheet.getActiveCell();
var rowIndex = active.getRowIndex(); //Get the rowindex of the current active cell
var maxValue = sheet.getRange(rowIndex,3).getValue(); //Your max value is the active cells value
var currentValue = 0;
var activeRowIndex = rowIndex
var loopIndex = 0;
do{
var cellData = sheet.getRange(activeRowIndex, 4).getValue(); //Get the value of the cell next to the selectedCell
if(cellData !== ''){ //If the cell is not blank continue
currentValue += cellData; //Add up the total as we go
activeRowIndex --; //Subtract the row index so we can keep movign up
loopIndex++; //Iterate the loopIndex so we know how many numbers we have added up to calculate the average
} else {
break; //If the cell is blank, break out of the loop
}
} while (currentValue <= maxValue);
sheet.getRange(rowIndex, 12).setValue(maxValue/(currentValue/loopIndex)); //set the ranges value and do the math in line for the average.
}

Detecting and displaying number of players detected using Kinect

I'm trying to display number of players detected by Kinect sensor using an WPF application. In addition to displaying number of player I have also coloured the pixels based on their distance from the Kinect. Original goal was to measure the distance of the pixels and display the distance but I would also like to display how many people are in the frame. Here is the code snippets that I'm using now.
PS I have borrowed the idea from THIS tutorial and I'm using SDK 1.8 with XBOX 360 Kinect (1414)
private void _sensor_AllFramesReady(object sender, AllFramesReadyEventArgs e)
{
using (DepthImageFrame depthFrame = e.OpenDepthImageFrame())
{
if (depthFrame==null)
{
return;
}
byte[] pixels = GenerateColoredBytes(depthFrame);
int stride = depthFrame.Width * 4;
image.Source = BitmapSource.Create(depthFrame.Width, depthFrame.Height,
96, 96, PixelFormats.Bgr32, null, pixels, stride);
}
}
private byte[] GenerateColoredBytes(DepthImageFrame depthFrame)
{
//get the raw data from kinect with the depth for every pixel
short[] rawDepthData = new short[depthFrame.PixelDataLength];
depthFrame.CopyPixelDataTo(rawDepthData);
/*
Use depthFrame to create the image to display on screen
depthFrame contains color information for all pixels in image
*/
//Height * Width *4 (Red, Green, Blue, Empty byte)
Byte[] pixels = new byte[depthFrame.Height * depthFrame.Width * 4];
//Hardcoded loactions for Blue, Green, Red (BGR) index positions
const int BlueIndex = 0;
const int GreenIndex = 1;
const int RedIndex = 2;
//Looping through all distances and picking a RGB colour based on distance
for (int depthIndex = 0, colorIndex = 0;
depthIndex < rawDepthData.Length &&
colorIndex<pixels.Length; depthIndex++, colorIndex+=4)
{
//Getting player
int player = rawDepthData[depthIndex] & DepthImageFrame.PlayerIndexBitmask;
//Getting depth value
int depth =rawDepthData[depthIndex]>>DepthImageFrame.PlayerIndexBitmaskWidth;
//.9M or 2.95'
if (depth <=900 )
{
//Close distance
pixels[colorIndex + BlueIndex] = 0;
pixels[colorIndex + GreenIndex] = 0;
pixels[colorIndex + RedIndex] = 255;
//textBox.Text = "Close Object";
}
//.9M - 2M OR 2.95' - 6.56'
else if (depth >900 && depth<2000)
{
//Bit further away
pixels[colorIndex + BlueIndex] = 255;
pixels[colorIndex + GreenIndex] = 0;
pixels[colorIndex + RedIndex] = 0;
}
else if (depth > 2000)
{
//Far away
pixels[colorIndex + BlueIndex] = 0;
pixels[colorIndex + GreenIndex] = 255;
pixels[colorIndex + RedIndex] = 0;
}
//Coloring all people in Gold
if (player > 0)
{
pixels[colorIndex + BlueIndex] = Colors.Gold.B;
pixels[colorIndex + GreenIndex] = Colors.Gold.G;
pixels[colorIndex + RedIndex] = Colors.Gold.R;
playersValue.Text = player.ToString();
}
}
return pixels;
}
Current goal is to--
Detect total number of players detected and display them in a textBox
Colour them according to the distance logic i.e depth <=900 is red.
With current code I can detect player and color them in Gold but as soon as a player is detected the image freezes and when the player is out of the frame the image unfreezes and acts normal. Is it because of the loop?
Ideas, guidance, recommendation and criticism all are welcome.
Thanks!
Screenshots:
Get a static variable inside your form code
Then set this variable using your video frame routine (dont define it there).
And then update the textbox view, probaply in your _sensor_AllFramesReady
As the arrival of new frames runs in a different thread
I dont see all code maybe to update call textbox.show
the main loop looks a bit strange though, too complex.
basicly you use it to color every pixel in your image.
as the kinect360 has 320x240 pixels so that makes a depth array of size 76800
You might simply create 2 for next loops loops for X and Y and then inside this loop have a variable increase to pick the proper depth value.

JavaFX event handler for array

All this rectangles are added in grid and I want after click each of them to change the color to white, but program throwing and exception.
Can i do this with this way or I need to get the position of rectangle a make on his place a new one ?
Rectangle[] rec = new Rectangle[22 * 12];
for( int i = 0; i < 22 * 12; i++){
rec[i] = new Rectangle(32, 32);
rec[i].setStroke(Color.BLACK);
rec[i].setFill( Color.valueOf("#202020") );
rec[i].setStrokeWidth(1);
rec[i].setOnMouseClicked(e -> {
Rectangle r = new Rectangle(32, 32, Color.WHITE);
rec[i].setFill( Color.WHITE); // exception at this line -> i must be final or ...
});
}
As your compile error says, you can't access non-final variables in a lambda expression. You can get around this by putting your rectangle in a different (effectively-final) variable:
Rectangle[] rec = new Rectangle[22 * 12];
for( int i = 0; i < 22 * 12; i++){
Rectangle r = new Rectangle(32, 32);
r.setStroke(Color.BLACK);
r.setFill( Color.valueOf("#202020") );
r.setStrokeWidth(1);
r.setOnMouseClicked(e -> {
r.setFill( Color.WHITE);
});
rec[i] = r ;
}
}

Tic Tac Toe, playing with PC (random)

if (turn == tick) {
/*first player*/
Form1->Label1->Caption = "X pyr";
fields[row][kol] = 1;
Form1->BitBtn1->Glyph->LoadFromFile("tick.bmp");
turn = tack;
}
else {
do {
//random
row = rand() % 3;
kol = rand() % 3;
}
while (fields[row][kol] == 0);
/*cpu*/
Form1->Label1->Caption = "CPU";
fields[row][kol] = 2;
Form1->BitBtn1->Glyph->LoadFromFile("tack.bmp");
turn = tick;
}
}
The main problem is that when I make my move, computer just clicks on first element and after every next move it does the same.
Computer just uses first TicTacToe game board square.
If i understand correctly the fields variable contain the board with 0 for unoccupied cell, 1 for human player, 2 for CPU.
In this case the terminal condition of the while is wrong while (fields[row][kol] == 0);, you must loop when the cell is occupied (trying to search for free cells).
do {
//random
row = rand() % 3;
kol = rand() % 3;
}
while (fields[row][kol] != 0);
Note: you are initializing all elements of fields to 0, that don't appear in the code.
CPU player loops until it finds a row and col value which is not equal to 0. do-while loop below loops if fields[row][col] is equal to 0 meaning after the exit fields[row][col] will be different than 0.
do {
...
} while(fields[row][col] == 0)
// fields[row][col] is different than 0 here
In your case field value not equal to 0 means a square already used by human or computer, so computer does the same move every time.

Resources