Since my last post I got my first one-star review of SlippyFlippyPenguin. The Hard Mode bug did it. Someone else can’t start the game in hard mode. In my last entry, I set up a timer to fix what I thought is a user-related problem with the game. In the process, I found the real bug. If you tap the Hard Button you get this almost immediately:
The original user issue was that the game ended on entering hard mode. I can’t replicate the bug on any of my iOS7 devices, nor in any simulator. I thought the user wasn’t taking control of the penguin fast enough and thus I put the delay in to give the user time to prepare. Looking through the code I could not find anything that was different in start up between easy and hard mode.
So what’s different?
There is only one thing that is different: In the hard mode hitting the top or bottom means the game is over. But SlippyFlippy shouldn’t be there to hit anything. Then again, maybe he is.
The penguin sprite is set to be in the center of the game scene, but invisible. Let’s make him visible, and while we are at it add a little animation to the three-second start up.
if(countDownInt>0){ //if counting down to 0 show counter countDown.text = [NSString stringWithFormat:@"%i", countDownInt]; <strong>penguin.alpha = (currentTime-startTimer)/COUNTDOWN;</strong> }else { //if not show message, dismiss, whatever you need to do.
Based on last installment’s countdown timer, I added one line of code that takes the time passed and divides it by a constant for the length of our countdown, giving us a number between 1 and 0, and thus making a new alpha value every frame. SlippyFlippy then fades in evenly, changing every frame.
When I can see the penguin, the problem is clear: A touch to the screen while in countdown fires an impulse to the penguin, and he slams into the top of the screen, ending the game. We need to control that impulse. The impulse code is in the update:
method
/*code to slide the penguin */ if (doBounce){ //NSLog(@"BOUNCE!!!"); //code for debugging if (doBounceUp) { gravityLabel.text = @"⬇︎"; self.physicsWorld.gravity = CGVectorMake(0.0, -7.0); //set between -5 to -9 [penguin.physicsBody applyImpulse:CGVectorMake(0, 0)]; [penguin.physicsBody applyImpulse:CGVectorMake(0, 5)]; }else{ gravityLabel.text = @"⬆︎"; self.physicsWorld.gravity = CGVectorMake(0.0, 7.0); //set between 5 to 9 [penguin.physicsBody applyImpulse:CGVectorMake(0, 0)]; [penguin.physicsBody applyImpulse:CGVectorMake(0, -5)]; } doBounce = NO; //end bouncing until next touch }
This is a variation on the basic code I set up when describing physics in an earlier post. This code sends an impulse using the physics engine. Depending on the direction of gravity into the penguin, the impulse is up or down. The effect on the penguin the physics engine determines. But it only does that if the doBounce
flag is set to YES
. Once the bounce happens, it sets doBounce
to NO.
Where is dobouce
set?
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { /* Called when a touch begins */ for (UITouch *touch in touches) { CGPoint location = [touch locationInNode:self]; CGRect easyRect = [[self childNodeWithName:@"easy button"] frame]; CGRect hardRect = [[self childNodeWithName:@"hard button"] frame]; if (isShowingTitle){ //(...) snipped code for display before game starts }else { doBounce=YES; doBounceUp = (gravity < 0); } } }
I did cut out a large amount of code above for clarity, but I just want to make one point. As soon as isShowingTitle
is set to NO
, SlippyFlippy can bounce. With the delay in place, it there may be cases where touches fire before the rest of the screen sets up, slamming SlippyFlippy into the top, ending the game.
In that case the solution is simple. I need to freeze the penguin until the game starts.
If I add doBounce=NO
; to the countdown sequence, the problem disappears:
//reset counter if starting if (isStartingGameUp){ startTimer = currentTime; isStartingGameUp = NO; countDown.alpha=1.0; } int countDownInt = COUNTDOWN -(int)(currentTime-startTimer); if(countDownInt>0){ //if counting down to 0 show counter countDown.text = [NSString stringWithFormat:@"%i", countDownInt]; penguin.alpha = (currentTime-startTimer)/COUNTDOWN; doBounce=NO; }else { //if not show message, dismiss, whatever you need to do. if(!isShowingTitle){ penguin.physicsBody.affectedByGravity = YES; penguin.alpha = 1.0; if (![self childNodeWithName:@"obstacle"] )[self makeObstacle]; countDown.text=@"GO!"; countDown.alpha = 0; [countDown runAction:[SKAction fadeOutWithDuration:1.0] withKey:@"fadeOutTimerLabel"]; } }
This works, and the bug disappears. However, I have another thought, which might have bearing on the original reports of the bug. I’m going to make sure at the end of processing every frame, doBounce
is set to NO. It should not change anything, but I’m wondering if the timing of touch events and doBounce
is messing something up. So at the end of update:
I put:
doBounce=NO;
I was never able to replicate the original bug. I’m assuming the bug I found in the 3-second delay is the same bug. I submitted the app for review , and we will see in the next few days what happens. Outsode the app, I’ve added support communication on SlippyFlippyPenguin’s Web Page, so I hope I can get more info from those that have bugs in the future.
Leave a Reply