One time initialisation of a variable in cocos2d-x - c++

I am working on one game in cocos2d-x (iOS). There I have created few scenes and did transitions in between those scenes. During each transition init() of each scene(layer) is called (Also constructor is called each time before init()). My question is, How can I make ONLY ONE time initialisation of my variable inside this init() or constructor, even when init() is called each time? Or any OTHER alternative solution for the same?
CCUserDefault::sharedUserDefault()->setBoolForKey("firstTimeInit", false);
bool firstTimeInit = CCUserDefault::sharedUserDefault()->getBoolForKey("firstTimeInit");
if (!firstTimeInit)
{
for(int i = 0; i < 10; i++)
{
char szName[22] = {0};
sprintf(szName, "Rank%i", i);
CCUserDefault::sharedUserDefault()->setIntegerForKey(szName,0);
CCUserDefault::sharedUserDefault()->flush();
int score = CCUserDefault::sharedUserDefault()->getIntegerForKey(szName);
vScore.push_back(score);
}
CCUserDefault::sharedUserDefault()->setBoolForKey("firstTimeInit",true); }
I wrote this code inside init() method.. and I want that firstTimeInit which I made false, initialise only once.
EDIT #####
In cocos2d-x for every transition init() method is called that is why every time our initialisation takes place. Also I want this one time initialisation even after I quit my game and rerun. I tried it by using CCUserDefault's setBoolForKey() but in vain,as it is also in init().

This will do what you are after
bool val = cocos2d::CCUserDefault::sharedUserDefault()->getBoolForKey("initialized");
if (val != true){
cocos2d::CCUserDefault::sharedUserDefault()->setBoolForKey("initialized", true);
cocos2d::CCLog(" initializing value ");
}

currently whats happening :-
1>game starts you put firstTimeInit=false, which makes the if condition true;
2>then you assign firstTimeInit=true in the end.
3> you quit and game starts again and runs step 1 ,which will override present value in firstTimeInit from true to false,again making the if condition true so you need to remove first statement
CCUserDefault::sharedUserDefault()->setBoolForKey("firstTimeInit", false);
so that once the key is set to true it is never set to false;
Assumption:But I am assuming if a boolean key is not present then getting its value always returns false. Checked several times , and it returned false.

Related

Loop through all buttons in a QButtonGroup

In my project, I have a QButtonGroup with 256 pushbuttons in it. I also gave each button an id like this:
void MainWindow::AddBlocksToGroup()
{
QButtonGroup* blockGroup = new QButtonGroup(this);
blockGroup->addButton(ui->Oblock_0, 0);
...
blockGroup->addButton(ui->Oblock_255, 255);
}
I am trying to loop through all the buttons in the group and change their text but I keep getting errors when my program reaches the part where I loop through the buttons. This is what I currently have to loop through them:
for(int i = 0; i <= 255; i++)
{
blockGroup->button(i)->setText("Test"); //Read access violation?
}
I always get a read access violation in my loop when my program reaches this point. Why is this?
Thanks for your time.
I would do this for the iteration code:
foreach(QAbstractButton *button, blockGroup->buttons()) {
button->setText("Test");
}
If this still gives you crashes, then there's something else going on in your program that is invalidating those button pointers.
I know it has been a long time, you probably have already solved this. If not, maybe you need to check whether blockGroup->buttons() return value is an empty list or not. If it is an empty list, then your program crashes.
You seem to be creating a local variable called blockGroup in your AddBlocksToGroup() function. Perhaps what you are trying to do is initialize your MainWindow member variable that uses the same name?
So instead of: QButtonGroup* blockGroup = new QButtonGroup(this);
you should do: blockGroup = new QButtonGroup(this);

C++ do while loop

I have a vector holding 10 items (all of the same class for simplicity call it 'a'). What I want to do is to check that 'A' isn't either a) hiding the walls or b) hiding another 'A'. I have a collisions function that does this.
The idea is simply to have this looping class go though and move 'A' to the next position, if that potion is causing a collision then it needs to give itself a new random position on the screen. Because the screen is small, there is a good chance that the element will be put onto of another one (or on top of the wall etc). The logic of the code works well in my head - but debugging the code the object just gets stuck in the loop, and stay in the same position. 'A' is supposed to move about the screen, but it stays still!
When I comment out the Do while loop, and move the 'MoveObject()' Function up the code works perfectly the 'A's are moving about the screen. It is just when I try and add the extra functionality to it is when it doesn't work.
void Board::Loop(void){
//Display the postion of that Element.
for (unsigned int i = 0; i <= 10; ++i){
do {
if (checkCollisions(i)==true){
moveObject(i);
}
else{
objects[i]->ResetPostion();
}
}
while (checkCollisions(i) == false);
objects[i]->SetPosition(objects[i]->getXDir(),objects[i]->getYDir());
}
}
The class below is the collision detection. This I will expand later.
bool Board::checkCollisions(int index){
char boundry = map[objects[index]->getXDir()][objects[index]->getYDir()];
//There has been no collisions - therefore don't change anything
if(boundry == SYMBOL_EMPTY){
return false;
}
else{
return true;
}
}
Any help would be much appreciated. I will buy you a virtual beer :-)
Thanks
Edit:
ResetPostion -> this will give the element A a random position on the screen
moveObject -> this will look at the direction of the object and adjust the x and Y cord's appropriately.
I guess you need: do { ...
... } while (checkCollisions(i));
Also, if you have 10 elements, then i = 0; i < 10; i++
And btw. don't write if (something == true), simply if (something) or if (!something)
for (unsigned int i = 0; i <= 10; ++i){
is wrong because that's a loop for eleven items, use
for (unsigned int i = 0; i < 10; ++i){
instead.
You don't define what 'doesn't work' means, so that's all the help I can give for now.
There seems to be a lot of confusion here over basic language structure and logic flow. Writing a few very simple test apps that exercise different language features will probably help you a lot. (So will a step-thru debugger, if you have one)
do/while() is a fairly advanced feature that some people spend whole careers never using, see: do...while vs while
I recommend getting a solid foundation with while and if/else before even using for. Your first look at do should be when you've just finished a while or for loop and realize you could save a mountain of duplicate initialization code if you just changed the order of execution a bit. (Personally I don't even use do for that any more, I just use an iterator with while(true)/break since it lets me pre and post code all within a single loop)
I think this simplifies what you're trying to accomplish:
void Board::Loop(void) {
//Display the postion of that Element.
for (unsigned int i = 0; i < 10; ++i) {
while(IsGoingToCollide(i)) //check is first, do while doesn't make sense
objects[i]->ResetPosition();
moveObject(i); //same as ->SetPosition(XDir, YDir)?
//either explain difference or remove one or the other
}
}
This function name seems ambiguous to me:
bool Board::checkCollisions(int index) {
I'd recommend changing it to:
// returns true if moving to next position (based on inertia) will
// cause overlap with any other object's or structure's current location
bool Board::IsGoingToCollide(int index) {
In contrast checkCollisions() could also mean:
// returns true if there is no overlap between this object's
// current location and any other object's or structure's current location
bool Board::DidntCollide(int index) {
Final note: Double check that ->ResetPosition() puts things inside the boundaries.

passing variable arguments to listener method in a loop

I want to pass args while calling service in loop. The problem is 1- If I use anonymous function as in following code;
for (var j:int = 0; j < listItems.length; j++)
{
_service.addEventListener(ResultEvent.RESULT, _anonymous = function(event:ResultEvent):void{
thumbnailResultHandler(event,listItems[k].ObjectID)
});
}
then, when starts running thumbnailResultHandler, pushing the latest value of j, and so latest value of listItems array. Because they are working async.
2- If I use following option to pass args;
_anonymous = onClick(listItems[j].ObjectID,j);
_service.addEventListener(ResultEvent.RESULT, _anonymous);
in for loop, and here is onClick function
public function onClick(n:Number,k:Number):Function
{
_service.removeEventListener(ResultEvent.RESULT,_anonymous);
return function(event:ResultEvent):void
{
trace( count++) ;//traces 25 times but must be just 5.
}
}
then, when thumbnailResultHandler runs, this method access both I passed values to onClick function and then works 5x5 times instead of 5 times working.
This must work once in each resultHandler , but reading both parameters in every result.
ASSUME listItems.length = 5
Any suggestion how can I fix this issue ?

CLI/C++ Tetris block crashes when check if cell is occupied is empty MSVisualStudio 2008

Here is my code for checking if future move is legal, I have assumed its legal and copied move into mySquares array. I then call this method in the game cycle set in the form and in the timer handler which is:
canvas->drawGrid();
testBlock->drawBlock();
testBlock->moveDown();//this method has checkBounds for when hit sides, top & bottom
if(newBlock->canMoveDown()==false)
{
newBlock->addMySelfToGameBoard();
mainGameBoard->updateGrid();
}
//timer1 handler finish
bool TTetrisBlock::canMoveDown()
{
array<Point>^ temporaryCopy = gcnew array<Point>(4);
bool canGoDown = true;
for(int i=0;i<mySquares->Length;i++)
{
//Set future move
temporaryCopy[i].X = mySquares[i].X;
temporaryCopy[i].Y = mySquares[i].Y+1;
}
//Check if future move cells are full, if not assign values to mySquares
//Check if future move is legal
for(int j=0;j<temporaryCopy->Length;j++)
{
if(gameBoard->isCellOccupied(temporaryCopy[j].X,temporaryCopy[j].Y) == true)
{
mySquares[j].X = temporaryCopy[j].X;
mySquares[j].Y = temporaryCopy[j].Y;
}
}
return canGoDown;
}
//end of moveDown
in my gameboard class i have the method which checks if TCell is occupied or not. TGameBoar holds an array of TCells which has a color and bool isOccupied = false;
bool TGameBoard::isCellOccupied(int c,int r)
{
//Checks if TCell is occupied
return myGrid[c,r]->getIsOccupied();
}
It Crashes and indicates here was the problem, Im currently learning C++ at school. I would appreciate some help. I am also struggling with the Keydown for moving left and right using e->KeyData == Keys::Left) etc. and creating a newblock when gone through loop.
I have my project rar if you want to check it out. I have all the classes done, its just putting it together is the hard bit.
Project Tetris
I see three problems.
First you should only move mySquares when isCellOccupied returns false (not true as you currently have it). I suspect this is the cause of your crash as it looks like you will be moving a block into a cell that is already occupied.
Second, when isCellOccupied returns true you should set canGoDown to false and break out of your for loop (or better yet, make canGoDown (==true) an additional condition of your for loop i.e. j < temporaryCopy->Length && canGoDown). As it is, your function always return true because it is never set to false and that can't be right.
Just making an assumption here, but don't all mySquares consist of 4 elements? You are initializing temporaryCopy with 4 elements but it isn't clear whether mySquares has 4 elements. If not, this could be dangerous as in your first loop you are looping on mySquares->Length and addressing temporaryCopy with that index value, which could be out of range. And then later doing the opposite. It might be better to use a constant (4) in all all loops or better yet, always use mySquares->Length (especially when creating the temporaryCopy array) to ensure that both arrays contain the same number of elements.

How is it that lastTimeTargetAdded is ever not 0

Im beginning work with Cocos2d and have been working off this tutorial (link is for part 9) the past few days.
In reading the source and trying to understand it I have reached a section that doesnt make any sense to me.
-(void)gameLogic:(ccTime)dt {
static double lastTimeTargetAdded =0;
double now = [[NSDate date] timeIntervalSince1970];
AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
if(lastTimeTargetAdded == 0 || now - lastTimeTargetAdded >= delegate.curLevel.spawnRate) {
[self addTarget];
lastTimeTargetAdded = now;
}
}
called via this:
[self schedule:#selector(gameLogic:) interval:0.2];
With the fact that lastTimeTargetAdded is created and set each time the function runs how is it ever not 0? And if thats the case what is the point of lastTimeTargetAdded = now? With the if statement being an OR (||) it never evaluates the other side of it so why is that even there?
I understand well enough what the function does just not so much how it does it. This method is suppose to spawn creeps based on their spawn rate. Making sure all the creeps in the wave arent just dumped on screen. And the method does do that well enough.
it is a static var ... the first statement sets to 0 only on the first invocation of gameLogic. On each subsequent invocation, lastTimeTargetAdded has the value that was set in the previous invocation.