How to resume my game after call ended - cocos2d-iphone

I have developed a game. When i checked in iphone, i found that my game pause when an incoming call comes and restarts after attending and ending the call. How to make it resume instead of restart

Try checking the AppDelegate.m for this:
- (void)applicationWillResignActive:(UIApplication *)application {
[[CCDirector sharedDirector] pause];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[[CCDirector sharedDirector] resume];
}
That usually "pauses" the current scene when the application is interupted...say for a phone call.
If this doesn't help...maybe you could eyplain your problem further.
greetings

Related

Application does not respond to touches after running in background Cocos2D iPhone

Currently I'm fixing an old Cocos2D iPhone 1.0 game. There is a strange problem: when the application is being sent to background by the four-finger gesture(iPad) after returning it behaves like the touch began and didn't end, and there no way to end it because the application does not respond to touches. Also when I launch the application and do nothing, the screen becomes locked and after that the application some times does not respond to touches.
I guess that there is something I need to do in the following AppDelegate methods, but I can't figure out exactly:
- (void)applicationWillResignActive:(UIApplication *)application {
[[CCDirector sharedDirector] pause];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[[CCDirector sharedDirector] resume];
}
enter code here
- (void)applicationDidEnterBackground:(UIApplication*)application {
[[CCDirector sharedDirector] stopAnimation];
}
-(void) applicationWillEnterForeground:(UIApplication*)application {
[[CCDirector sharedDirector] startAnimation];
}
The problem was in -(void)ccTouchCanceled method not implemented

Making any given instance of a CCNode reactive to touch

So in my project I am using Cocos2D with CocosBuilder. I have assigned a few of my characters to be subclasses of CCNode with child CCSprites, etc.
I want these CCNodes to be reactive to touch - for example, if I touch any of them, they'd play a context sensitive animation. I only want to know how to make the node reactive to touch (or perhaps, having the layer reactive to touch which detects whether you've touched a sprite or not), the animation part is fine.
Any ideas? that would be lovely.
Sam
Turns out that this is fairly easy. In the header file of your class, you must define the class as implementing the protocol , like so:
#interface Foo : CCNode <CCTouchOneByOneDelegate>
{
}
and you must implement onEnter and onExit like this:
- (void)onEnter
{
[[[CCDirector sharedDirector] touchDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
[super onEnter];
}
- (void)onExit
{
[[[CCDirector sharedDirector] touchDispatcher] removeDelegate:self];
[super onExit];
}
and you must implement ccTouchBegan (if you're using the OneByOneDispatcher)

shooting intervals in cocos2d without CACurrentMediaTime()

I have a ship and I want to make it to shoot every 1 sec. So here's what I did,
#property (nonatomic, assign) float lastDamageTime;
and in the update method,
if (CACurrentMediaTime - self.lastDamageTime > 1)
{
self.lastDamageTime = CACurrentMediaTime;
[self shoot];
}
But the problem is, say I pause the game right after the ship shoot a bullet, and then 1 sec later, I resume the game, the if statement pass the check, and the ship will shoot another bullet immediately. And that's not what I want.
So, what can I do to make sure the ship fire bullets each sec weather I pause the game or not? Should I use CCTimer instead?
Thank you in advance for your answer.
You could try and schedule your shoots as a CCRepeatForever action, so that cocos2d deals with pause for you. It'd look something like this (assuming you're inside a custom ShipSprite).-
CCDelayTime *delay = [CCDelayTime actionWithDuration:1.0];
CCCallFunc *funcShoot = [CCCallFunc actionWithTarget:self selector:#selector(shoot)];
CCRepeatForever *repeat = [CCRepeatForever actionWithAction:[CCSequence actionOne:delay two:funcShoot]];
[self runAction:repeat];
Instead of CCRepeatForever you can try something like this
[self schedule:#selector(shoot) interval:1];
In your pause code unschedule the shooting
[self unschedule:#selector(shoot)];
In your code where it detects an enemy call
[self unschedule:#selector(shoot)];
[self performSelector:#selector(shoot)];
[self schedule:#selector(shoot) interval:1];
And it will shoot immediately, however it will only shoot once and then restart at 1 second intervals etc... so if you need to change that you can just adjust the timings

Cocos2d - Allow touches to be used by multiple classes (sneakyjoystick)

Evening all,
I'll start this question in the time honoured tradition by saying that I've had a good old search on SO and also in the wider world but I'm not quite getting my head around this...
I've implemented a sneakyJoystick which works wonderfully (It moves my sprite around quite happily) however I've now done myself a mischief in thinking about it's positioning.
What I'd like to do is simply change it's position to a touch location and have it move my sprite around but this seems to be out of my knowledge pool. I might be being an idiot but I cannot work it out.
The touch events are already sorted in the sneakyjoystick classes (available on github https://github.com/0xPr0xy/sneaky-joystick-cocos2d). At the moment if I create the joystick during the init method in a class called controlsLayer then everything works fine; Joystick appears and it allows me to move to sprite around
-(id) init
{
if( (self=[super init]) ) {
myJoystickBase = [[[SneakyJoystickSkinnedBase alloc] init] autorelease];
myJoystickBase.backgroundSprite = [CCSprite spriteWithFile:#"dpad.png"];
myJoystickBase.thumbSprite = [CCSprite spriteWithFile:#"joystick.png"];
myJoystickBase.joystick = [[SneakyJoystick alloc] initWithRect:CGRectMake(0, 0, 128, 128)];
myJoystickBase.position = ccp(64, 64);
myJoystickBase.backgroundSprite.opacity = 100;
myJoystickBase.thumbSprite.opacity = 100;
[self addChild:myJoystickBase];
myJoystick = [myJoystickBase.joystick retain];
[self scheduleUpdate];
}
return self;
}
So to begin with I thought about looking at how I could simply get it to show and hide itself and set it's location. To do this I created a ccTouchesbegan method which contains pretty much the same code as my init method did before. This works fine up to a point (the joystick appears centred wherever I touch) but the issue now is that I cannot interact with it. The joystick appears where i want but it will not recognise my movements (the stick on the joystick does not move which in turn means that my sprite is not being told to move either)
if( (self=[super init]) ) {
self.isTouchEnabled = YES;
[self scheduleUpdate];
}
return self;
}
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint location = [[CCDirector sharedDirector] convertToGL:[touch locationInView:[touch view]]];
location = [self convertToNodeSpace:location];
myJoystickBase = [[[SneakyJoystickSkinnedBase alloc] init] autorelease];
myJoystickBase.backgroundSprite = [CCSprite spriteWithFile:#"dpad.png"];
myJoystickBase.thumbSprite = [CCSprite spriteWithFile:#"joystick.png"];
myJoystickBase.joystick = [[SneakyJoystick alloc] initWithRect:CGRectMake(0, 0, 128, 128)];
myJoystickBase.position = location;
myJoystickBase.backgroundSprite.opacity = 100;
myJoystickBase.thumbSprite.opacity = 100;
[self addChild:myJoystickBase];
myJoystick = [myJoystickBase.joystick retain];
}
-(void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
[self removeChild:myJoystickBase cleanup:YES];
}
So to my uninitiated brain this is saying that when I touch the controlsLayer class it happily does what I've asked it to but it will not then pass this touch to other classes.
In a nutshell can a touch event be passed to multiple classes at the same time? The sneaky joystick class uses CCTargetedTouchDelegate which worked fine when it was the only thing looking for a touch. However now that I've added a -(void)ccTouchesBegan: in another class it's not happy.
Can anyone tell me if the problem is with the way I'm handling touches or is it possibly an issue with the way that I allocate the joystick in the touch method? Should I be allocating the joystick in the init method and be doing something else in the touchesBegan method? Trial and error isn't getting me anywhere useful at the moment. Feel like I'm banging my head against a brick wall. I'm happy to post up the full class files if necessary. Does this make sense?
The problem is that you create the joystick during touch began, and remove it on touch ended. This does not allow the joystick to receive a touch began event, since the event is already being processed at the time the joystick is being created.
You're also leaking the joystick due to the unnecessary retain (use ARC, please!).
Try creating the joystick in init, disable & hide it until a touch began event is received. This is also faster than recreating the joystick on every touch.
Also, should you have multiple touches enabled, keep in mind that you can receive up to 5 touch began events (5 fingers) without any touch ended in between. That would create 5 joysticks, but only remove one! Every time!

How to restart a level in an iPhone game

I want to restart the current scene i am on. I thought of using replaceScene and replace it with itself. Is that ok to do ?
Level2Scene *scene = [Level2Scene node];
[[CCDirector sharedDirector] replaceScene:scene];
Level2Scene is the current scene I am in.
Thanks
Abhinav
Using replaceScene: is a good way to restart the level, if levels are represented by scenes. Just make sure that if you have any global state (stored outside of the scene) that you reset that, too.