How to stop position update, when pause button is pressed? - ios

I have this code to make the particles follow my b2body object:
-(void)updateMagicFruitParticlePosition:(ccTime)dt{
if (!gameManager.isPaused) {
magicFruitParticle.position = especialObject.ccPosition;
}
else
[self unschedule:_cmd];
}
The code works, but when the pause button is pressed and the player restarts the game, it crashes. Theoretically it should stop once the button was pressed, but it happens to be in the middle of the update even when the method has unscheduled.
The code below is what happens when the pause button is pressed:
-(void)pauseGame:(id)sender{
if (!gameManager.isPaused ) {
gameManager.isPaused = YES;
[gameManager pauseAllSoundEffects];
[gameManager pauseBackgroundMusic];
[[CCDirector sharedDirector] pause];
pauseLayer = [CCLayerColor layerWithColor:ccc4(0, 0, 0, 125) width:screenSize.width height:screenSize.height];
pauseLayer.position = CGPointZero;
[self addChild:pauseLayer z:kSecondLayer];
backgroundPauseA = [CCSprite spriteWithSpriteFrameName:#"BackgroundPauseA"];
backgroundPauseA.position = ccp(screenSize.width /2, screenSize.height /2);
[self addChild:backgroundPauseA z:kSuperiorLayer];
backgroundPauseB = [CCSprite spriteWithSpriteFrameName:#"BackgroundPauseB"];
backgroundPauseB.position = ccp(screenSize.width /2, screenSize.height /2);
[self addChild:backgroundPauseB z:kSuperiorLayer];
[self pauseMenu];
}
}
Is there any other way to make a particle effect follow an object or sprite? Or how can I fix it to work?
Any help will be appreciated!
Thanks!

Related

SpriteKit Pause and Resume SKView

I want to Pause and Unpause a Scene in SpriteKit, with 2 Buttons on the same position.
While the Scene is running, I want to show the 'Pause' Button.
While the Scene is paused, I want to hide the 'Pause' Button and show the 'Play' Button.
In SpriteKit you can use self.scene.view.paused which is defined in SpriteKit.
My Code:
#implementation MyScene {
SKSpriteNode *PauseButton;
SKSpriteNode *PlayButton;
}
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
[self Pause];
}
return self;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
/* Called when a touch begins */
UITouch * touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
SKNode * Node = [self nodeAtPoint:location];
if([Node.name isEqualToString:#"PauseButton"]){
self.scene.view.paused = YES;
[PauseButton removeFromParent];
[self Resume];
}
if([Node.name isEqualToString:#"PlayButton"]){
self.scene.view.paused = NO;
[PlayButton removeFromParent];
[self Pause];
}
}
-(void)Pause{
PauseButton = [SKSpriteNode spriteNodeWithImageNamed:#"Pause.png"];
PauseButton.position = CGPointMake(self.frame.size.width / 2, self.frame.size.height / 1.04);
PauseButton.zPosition = 3;
PauseButton.size = CGSizeMake(40, 40);
PauseButton.name = #"PauseButton";
[self addChild:PauseButton];
}
-(void)Resume{
PlayButton = [SKSpriteNode spriteNodeWithImageNamed:#"Play.png"];
PlayButton.position = CGPointMake(self.frame.size.width / 2, self.frame.size.height / 1.04);
PlayButton.zPosition = 3;
PlayButton.size = CGSizeMake(60, 60);
PlayButton.name = #"PlayButton";
[self addChild:PlayButton];
}
It pauses the Scene, but the there is still the Pause Button, and if I touch the Pause Button again, the Scene resumes. So now only the Images won't change. How can I fix this?
You can't update the button (or anything else in the scene) while the SKView is paused. In your touchesBegan method, you are pausing the view before updating the button (changing the order won't work). You will need to return to the run loop so your button is updated before pausing the game. Here's one way to do that:
This calls a method to pause the view after a short delay. Add this after your [self Resume] statement in touchesBegan, and delete self.scene.view.paused = YES.
[self performSelector:#selector(pauseGame) withObject:nil afterDelay:1/60.0];
This method pauses the SKView. Add this to your MyScene.m
- (void) pauseGame
{
self.scene.view.paused = YES;
}

Moving a camera in SpriteKit

//UPDATE
The updated code has been added that works as I expected. See didSimulatePhysics method in the updated code below. In my case, I only care about moving a character left or right on the x axis where 0 on the x axis is the absolute left and right on the x axis is a configurable value. The Apple adventure game really helped a lot too.
//ORIGINAL POST BELOW
I'm working with Apple SpriteKit and I'm struggling to implement a camera as I would like it to behave. What I've done in the code is load a sprite character, two buttons, and a red box that is off to the right outside of the view at the start. What I'd like to be able to do is move the character with the buttons, and once the player reaches the middle or end of the screen, the camera will then re-adjust to uncover what couldn't be seen in the view. So moving to the right should eventually show the red box that is off outside of the view initially once the player gets there. However, with the code I'm using below, I'm unable to get the camera to follow and adjust the coordinates to the main character at all. I've looked at Apple's advanced scene processing doc as well as a few other stack overflow posts but can't seem to get it right. If anyone could offer some advice it would be appreciated.
#define cameraEdge 150
-(id)initWithSize:(CGSize)size
{
if (self = [super initWithSize:size])
{
/* Setup your scene here */
//320 568
self.backgroundColor = [SKColor whiteColor];
myWorld = [[SKNode alloc] init];
[self addChild:myWorld];
mainCharacter = [SKSpriteNode spriteNodeWithImageNamed:#"0"];
mainCharacter.physicsBody.dynamic = YES;
mainCharacter.name = #"player";
mainCharacter.position = CGPointMake(20, 20);
CGRect totalScreenSize = CGRectMake(0, 0, 800, 320);
SKSpriteNode *box = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(60, 60)];
SKSpriteNode *boxTwo = [SKSpriteNode spriteNodeWithColor:[SKColor greenColor] size:CGSizeMake(60, 60)];
SKSpriteNode *boxThree = [SKSpriteNode spriteNodeWithColor:[SKColor blueColor] size:CGSizeMake(60, 60)];
boxThree.position = CGPointMake(40, 50);
[myWorld addChild:boxThree];
boxTwo.position = CGPointMake(1100, 50);
box.position = CGPointMake(650, 50);
[myWorld addChild:box];
[myWorld addChild:boxTwo];
self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:totalScreenSize];
self.physicsWorld.gravity = CGVectorMake(0, -5);
mainCharacter.name = #"mainCharacter";
mainCharacter.physicsBody.linearDamping = 0;
mainCharacter.physicsBody.friction = 0;
mainCharacter.physicsBody.restitution = 0;
mainCharacter.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:mainCharacter.size];
[myWorld addChild:mainCharacter];
[self addChild:[self buildLeftButton]];
[self addChild:[self buildRightButton]];
}
return self;
}
- (void)didSimulatePhysics
{
SKSpriteNode *hero = mainCharacter;
if(hero)
{
CGPoint heroPosition = hero.position;
CGPoint worldPosition = myWorld.position;
NSLog(#"%f", heroPosition.x);
CGFloat xCoordinate = worldPosition.x + heroPosition.x;
if(xCoordinate < cameraEdge && heroPosition.x > 0)
{
worldPosition.x = worldPosition.x - xCoordinate + cameraEdge;
self.worldMovedForUpdate = YES;
}
else if(xCoordinate > (self.frame.size.width - cameraEdge) && heroPosition.x < 2000)
{
worldPosition.x = worldPosition.x + (self.frame.size.width - xCoordinate) - cameraEdge;
self.worldMovedForUpdate = YES;
}
myWorld.position = worldPosition;
}
}
-(SKSpriteNode *)buildLeftButton
{
SKSpriteNode *leftButton = [SKSpriteNode spriteNodeWithImageNamed:#"left"];
leftButton.position = CGPointMake(20, 20);
leftButton.name = #"leftButton";
leftButton.zPosition = 1.0;
return leftButton;
}
-(SKSpriteNode *)buildRightButton
{
SKSpriteNode *leftButton = [SKSpriteNode spriteNodeWithImageNamed:#"right"];
leftButton.position = CGPointMake(60, 20);
leftButton.name = #"rightButton";
leftButton.zPosition = 1.0;
return leftButton;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
SKNode *node = [self nodeAtPoint:location];
if([node.name isEqualToString:#"leftButton"])
{
[mainCharacter.physicsBody applyImpulse:CGVectorMake(-120, 0)];
}
else if([node.name isEqualToString:#"rightButton"])
{
[mainCharacter.physicsBody applyImpulse:CGVectorMake(120, 10)];
}
}
If you want the view to always be centered on your player's position, modify your code with these points in mind:
1) Create a SKNode and call it myWorld, worldNode or any other name like that.
2) Add the worldNode [self addChild:worldNode];
3) Add all other nodes to the worldNode, including your player.
4) In the didSimulatePhysics method, add this code:
worldNode.position = CGPointMake(-(player.position.x-(self.size.width/2)), -(player.position.y-(self.size.height/2)));
Your view will now always be centered on your player's position.
Update May 2015:
If you are using a map created with Tiled Map Editor, you can use the free SKAToolKit framework. Features include player camera auto follow, test player, test HUD and sprite buttons.

Play/Pause buttons in a game

MY code:
-(SKSpriteNode*) pauseButton
{
SKSpriteNode* pauseButton = [SKSpriteNode spriteNodeWithImageNamed:#"pausebutton"];
pauseButton.position = CGPointMake(CGRectGetMaxX(self.frame) -30,CGRectGetMaxY(self.frame) - 30);
pauseButton.anchorPoint = CGPointMake(1.0, 1.0);
pauseButton.name = #"pauseButton";
pauseButton.zPosition = 160;
return pauseButton;
}
-(SKSpriteNode*) playButton
{
SKSpriteNode* playButton = [SKSpriteNode spriteNodeWithImageNamed:#"playbutton"];
playButton.position = CGPointMake(CGRectGetMaxX(self.frame)- 30, CGRectGetMaxY(self.frame) - 30);
playButton.anchorPoint = CGPointMake(1.0, 1.0);
playButton.name = #"playButton";
playButton.zPosition = -10;
return playButton;
}
In touchesBegan:
SKSpriteNode *pauseButton = (SKSpriteNode*)[self childNodeWithName:#"pauseButton"];
CGPoint location = [touch locationInNode:self];
if (!(gameIsOver))
{
if([pauseButton containsPoint:location])
{
if (self.scene.view.paused==YES)
{
[myTimer start];
pauseButton.zPosition = 160;
[self childNodeWithName:#"playButton"].zPosition = -10;
self.scene.view.paused = NO;
}
else if (self.scene.view.paused ==NO)
{
pauseButton.zPosition = -10;
[self childNodeWithName:#"playButton"].zPosition = 160;
[myTimer pause];
[self performSelector:#selector(pauseGame) withObject:Nil afterDelay:0.01];
}
}
-(void) pauseGame
{
self.scene.view.paused = YES;
}
My problems:
I do not want to use: [self performSelector:#selector(pauseGame) withObject:Nil afterDelay:0.01]; as its not accurate. I want to set self.scene.view.paused = YES; as soon as someone clicks the pause button. However, not setting a delay doesn't let the pause button change to play. Is there a way I can fix this.
Sometimes, my pause button doesn't change to play. I dont know why. This is rare though.
Any help would be appreciated.
Thanks

How to calibrate a sprites touchLocation after zoom

I add a sprite on the background sprite and then zoom (pinch) the background and by that the sprite as well.
After the zoom i want to be able to click right on the "zoomed" sprite and then move (pan) it. However, to catch the sprite i have to click outside of the sprite. I guess that is due to the zoom and coordinates.
I would really need some help how to make it so that i always only need to click on the actual sprite if it is in it's original state or zoomed up or down.
I will also implement UIScrollView so i can move around the background but would like to fix this first.
Here is the code i use to test this:
- (void)didMoveToView:(SKView *)view {
_background = [SKSpriteNode spriteNodeWithImageNamed:#"background"];
_background.name = #"background";
[_background setAnchorPoint:CGPointZero];
// _background.anchorPoint = CGPointMake(0.0, 0.1);
self.scaleMode = SKSceneScaleModeResizeFill;
[self addChild:_background];
SKLabelNode *texT = [SKLabelNode labelNodeWithFontNamed:#"Ariel"];
texT.text = #"X";
texT.position = CGPointMake(160, 260);
[_background addChild:texT];
_panGesture = [[UIPanGestureRecognizer alloc]initWithTarget:self action:#selector(handlePan:)];
[self.view addGestureRecognizer:_panGesture];
_pinchGesture = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:#selector(handlePinch:)];
[self.view addGestureRecognizer:_pinchGesture];
/* Setup your scene here */
self.backgroundColor = [SKColor colorWithRed:0.15 green:0.15 blue:0.3 alpha:1.0];
SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithImageNamed:#"Spaceship"];
sprite.xScale = 0.2;
sprite.yScale = 0.2;
sprite.position = CGPointMake(160, 260);
sprite.name = #"sprite";
[_background addChild:sprite];
}
- (void)handlePan:(UIPanGestureRecognizer *)sender {
NSLog(#"handlePan:");
if (![_currentNode.name isEqualToString:#"background"]) {
_touchLocation = [sender locationInView:sender.view];
_touchLocation = [self convertPointFromView:_touchLocation];
_currentNode.position = _touchLocation;
}
}
- (void)handlePinch:(UIPinchGestureRecognizer *) sender {
NSLog(#"handlePinch: %f",sender.scale);
[self runAction:[SKAction scaleBy:sender.scale duration:0]];
sender.scale = 1;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(#"touchesBegan");
//////DO THE FIRST TOUCH//////
_actualTouch = [touches anyObject];
_touchLocation = [_actualTouch locationInNode:self];
_currentNode = [self nodeAtPoint:_touchLocation];
NSLog(#"TouchBegan:_touchLocation:%#", NSStringFromCGPoint(_touchLocation));
NSLog(#"_currentNode.name: %#", _currentNode.name);
}
#end
I had this same problem and I found that the solution is to resize instead of scale. The physics seem to still work as expected and now the touch events will too. I came across this solution here. The scaleMode in your didMoveToView needs to be changed as well, see below.
self.scaleMode = SKSceneScaleModeAspectFill;
- (void)handlePinch:(UIPinchGestureRecognizer *) sender {
NSLog(#"handlePinch: %f",sender.scale);
//[self runAction:[SKAction scaleBy:sender.scale duration:0]];
self.size = CGSizeMake(self.size.width/sender.scale,self.size.height/sender.scale);
sender.scale = 1;
}
In my own implementation I had set upper and lower limits to the zoom level as well.

How to restart a Cocos2D application?

I am making a game, and everything works except the restart button. I would like the game to start again from the restart method, which loads everything onto the screen and sets up gameplay. However I get an error saying "Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[HelloWorldLayer resetAll:]: unrecognized selector sent to instance 0x9142c70'"
Below is the code for the main class (I'm assuming you guys don't need the other classes, as they work fine):
#import "HelloWorldLayer.h"
#import "AppDelegate.h"
#import "Block.h"
#import "Character.h"
#implementation HelloWorldLayer
-(id) init{ //Init method
if(self = [super initWithColor:ccc4(84,56,8,26)]){ //Initialise with a black background
[self restart];
}
return self;
}
-(void) setUpMenus{
moveRight = [CCMenuItemImage itemWithNormalImage:#"GoRightButton.png" selectedImage:#"GoRightButtonSelected.png" target: self selector:#selector(moveRightMethod:)];
moveLeft = [CCMenuItemImage itemWithNormalImage:#"GoLeftButton.png" selectedImage:#"GoLeftButtonSelected.png" target: self selector:#selector(moveLeftMethod:)];
moveUp = [CCMenuItemImage itemWithNormalImage:#"GoUpButton.png" selectedImage:#"GoUpButtonSelected.png" target: self selector:#selector(moveUpMethod:)];
moveDown = [CCMenuItemImage itemWithNormalImage:#"GoDownButton.png" selectedImage:#"GoDownButtonSelected.png" target: self selector:#selector(moveDownMethod:)];
moveRight.position = ccp(player.image.position.x - 10, player.image.position.y);
moveLeft.position = ccp(player.image.position.x - 80, player.image.position.y);
moveUp.position = ccp(player.image.position.x - 40, player.image.position.y + 30);
moveDown.position = ccp(player.image.position.x - 40, player.image.position.y - 30);
myScore.position = ccp(player.image.position.x - 20, player.image.position.y + 100);
mainMenu = [CCMenu menuWithItems:moveRight, moveLeft, moveUp, moveDown, nil];
[self addChild: mainMenu];
}
-(void) enemyMoveTowardsPlayer{
CGPoint playerPosition = player.image.position;
[enemy moveToLocationEnemy:&playerPosition];
}
-(void) moveRightMethod: (id) sender{
if(enemyExists == YES){
[self enemyMoveTowardsPlayer];
}
if(player.image.position.x < 5000){
[player move];
[self changeBack];
}
}
-(void) moveLeftMethod: (id) sender{
if(enemyExists == YES){
[self enemyMoveTowardsPlayer];
}
if(player.image.position.x > 20){
[player moveLeft];
[self change];
}
}
-(void) moveUpMethod: (id) sender{
if(enemyExists == YES){
[self enemyMoveTowardsPlayer];
}
if(player.image.position.y < 7000){
[player moveUp];
[self changeUp];
}
}
-(void) moveDownMethod: (id) sender{
if(player.image.position.y > -100){
[player moveDown];
[self changeDown];
}
if(enemyExists == YES){
[self enemyMoveTowardsPlayer];
}
}
-(void) callSpawnEnemy{
CCSprite *enemyImage = [CCSprite spriteWithFile:#"Lizard_Sprite.png"]; //Enemy picture
enemy = [[Character alloc] initWithImageAndNameAndProjectile:enemyImage
andAnotherParam:#"Enemy"];
//Enemy instantiation
enemy.image.position = ccp(100,400);
[self addChild:enemy.image]; //Add the enemy image object
enemyExists = YES;
}
-(void)ccTouchesBegan:(NSSet*)touches withEvent:(UIEvent*)event{
//CODE FOR HANDLING TOUCH EVENTS. THE BELOW CODE SIMPLY CREATES AND INSTANTIATES A TOUCH OBJECT AND STORES THE LOCATION
CGPoint touchLocation;
for(UITouch *touch in touches ) {
touchLocation = [touch locationInView: [touch view]];
CGPoint prevLocation = [touch previousLocationInView: [touch view]];
touchLocation = [[CCDirector sharedDirector] convertToGL: touchLocation];
prevLocation = [[CCDirector sharedDirector] convertToGL: prevLocation];
CGPoint diff = ccpSub(touchLocation,prevLocation);
[self setPosition: ccpAdd(self.position, diff)];
}
//
NSLog(#"%f", touchLocation.x);
NSLog(#"%f",touchLocation.y);
}
-(void) change{ //Code to change the image to a leftward facing sprite
CCTexture2D* tex = [[CCTextureCache sharedTextureCache] addImage:#"PlayerSpriteLeftHugeV2.png"];
[player.image setTexture: tex];
}
-(void) changeBack{ //Code to change the image to a rightward facing sprite
CCTexture2D* tex = [[CCTextureCache sharedTextureCache] addImage:#"PlayerSpriteHugeV2.png"];
[player.image setTexture: tex];
}
-(void) changeUp{ //Code to change the image to a leftward facing sprite
CCTexture2D* tex = [[CCTextureCache sharedTextureCache] addImage:#"PlayerSpriteUp.png"];
[player.image setTexture: tex];
}
-(void) changeDown{ //Code to change the image to a rightward facing sprite
CCTexture2D* tex = [[CCTextureCache sharedTextureCache] addImage:#"PlayerSpriteDown.png"];
[player.image setTexture: tex];
}
-(void) generate2dMap{ //Method to generate a 130 by 80 block map (10400 blocks)
for(int i = 20; i < 13000; i+=100){ //X coordinate. Increment by length of each block.
for(int g = 20; g < 8000; g+=100){ //Y coordinate. Increment by length of each block.
CGPoint p = CGPointMake(i, g); //Point for the block. Changes every time the loop goes through
int randNumber = rand() % 11; //Random number to determine the block type
if(randNumber < 1){ //Only 1 in 10 blocks should be gold blocks
Block* gold = [[Block alloc] initWithTypePositionAndImage:#"Gold" andImageName:[CCSprite spriteWithFile:#"GoldBlockHuge.png"]];
//Create a gold object and pass the appropriate information to the constructor
[allBlocks addObject: gold]; //Add the gold object to the mutable array
gold.image.position = p; //Set the block image position to be the current location
[self addChild:gold.image]; //Add the block image to the screen
}
else{ //More common. Should occur 9/10 times
Block* dirt = [[Block alloc]
initWithTypePositionAndImage:#"Dirt" andImageName:[CCSprite spriteWithFile:#"DirtBlockHuge.png"]];
//Create a dirt object and pass the appropriate information to the constructor
[allBlocks addObject: dirt]; //Add the dirt object to the mutable array
dirt.image.position = p; //Set the block image position to be the current location
[self addChild:dirt.image]; //Add the block image to the screen
}
}
}
}
-(void) checkScore{ //Update the score. Set the score object to be the score primative from the player object
[myScore setString:[NSString stringWithFormat:#"%d", player->score]];
stringScore = myScore.string;
}
-(BOOL) checkForCollisions{ //Method to check for collision detection
for(Block *b in allBlocks){ //Loop through all blocks to check if any have collided with the player image
CGRect playerRect = CGRectMake(player.image.position.x, player.image.position.y, 90, 84);
//Rectangle object for the player
CGRect blockRect = CGRectMake(b.image.position.x, b.image.position.y, 50, 50);
//Rectangle object for each block
if(CGRectIntersectsRect(playerRect, blockRect)){ //If the block is in the state of intersecting the player
amountOfBlocks++;
collisionSprite = b; //Set the collision object to be the block
if([collisionSprite.type isEqualToString:#"Gold"]){ //If it's collided with a gold object...
[player incrementScoreBy:100]; //Then increment the score by 100
}
else if([collisionSprite.type isEqualToString:#"Bronze"]){
[player incrementScoreBy:20];
}
else if([collisionSprite.type isEqualToString:#"Silver"]){
[player incrementScoreBy:50];
}
else if([collisionSprite.type isEqualToString:#"Dirt"]){
[player incrementScoreBy:2];
}
return YES; //There has been a collision, and you should terminate this round of the method
}
if(enemyExists == YES){
CGRect enemyRect = CGRectMake(enemy.image.position.x, enemy.image.position.y, 80,80);
if(CGRectIntersectsRect(enemyRect, blockRect)){
collisionSprite = b;
enemyHitBlock = YES;
return YES;
}
if(CGRectIntersectsRect(enemyRect, playerRect)){
enemyHitPlayer = YES;
return YES;
}
}
}
return NO; //There has not been a collision, and you should terminate this round of the method
}
-(void) update: (ccTime) dt{ //Update method called on regular interval that checks for collisions, updates the score
if(isDone == NO){
if([self checkForCollisions]){ //Check for collisions
[self removeChild:collisionSprite.image cleanup:YES]; //Remove the sprite if there has been a collision
[allBlocks removeObject:collisionSprite]; //Remove the object if there has been a collision
if(enemyExists == YES){
if(enemyHitPlayer == YES){
[self removeChild:enemy.image cleanup:YES];
enemyHitPlayer = NO;
enemyExists = NO;
}
if(enemyHitBlock == YES){
[self removeChild:collisionSprite.image cleanup:YES]; //Remove the sprite if there has been a collision
enemyHitBlock = NO;
}
}
}
mainMenu.position = ccp(player.image.position.x - 10, player.image.position.y);
myScore.position = ccp(player.image.position.x - 20, player.image.position.y + 100);
if(enemyExists == NO){
[self callSpawnEnemy];
}
[self checkScore]; //Update the score
if([stringScore intValue] >= 200){
[self endGame];
}
}
}
-(void) endGame{
isDone = YES;
endGameString = #"You reached the max score in ";
stringBlockCount = [NSString stringWithFormat:#"%d blocks", amountOfBlocks];
totalString = [endGameString stringByAppendingString:stringBlockCount];
endGameMessage = [CCLabelTTF labelWithString:totalString fontName:#"Times New Roman" fontSize:20];
CGSize winSize = [[CCDirector sharedDirector] winSize];
CGPoint point = ccp(winSize.height/2,winSize.width/2);
endGameMessage.position = point;
[self stopAllActions];
[self runAction:[CCFollow actionWithTarget:endGameMessage]];
[self removeAllChildrenWithCleanup:YES];
[self addChild: endGameMessage];
restart = [CCMenuItemImage itemWithNormalImage:#"RestartButton.png" selectedImage:#"RestartButtonSelected.png" target: self selector:#selector(resetAll:)];
restart.position = ccp(point.x - 500, point.y - 250);
restartMenu = [CCMenu menuWithItems:restart, nil];
[self addChild:restartMenu];
}
-(void) restart{
[self removeAllChildrenWithCleanup:YES];
NSLog(#"Got here");
isDone = NO;
amountOfBlocks = 0;
allBlocks = [[NSMutableArray alloc] init]; //Instantiate array that holds all blocks
collisionSprite = [[Block alloc] init]; //Instantiate object that holds the collision object
enemyCollisionSprite = [[Character alloc] init];
enemyHitBlock = NO;
enemyHitPlayer = NO;
[self generate2dMap]; //Generate the map
self.isTouchEnabled = YES; //Enable touch technology
CCSprite *playerImage = [CCSprite spriteWithFile:#"PlayerSpriteHugeV2.png"]; //Player image object
player = [[Character alloc] initWithImageAndNameAndProjectile:playerImage andAnotherParam:#"Player"];
//Instantiate player object
player.image.position = ccp(0,210); //Set player image position
//Set player projectile image position
stringScore = [NSString stringWithFormat:#"%d", player->score]; //Score object
myScore = [CCLabelTTF labelWithString:stringScore fontName:#"Times New Roman" fontSize:20];
//CCLabel representation of score
myScore.position = ccp(20,300); //Set position of label score
myScore.color = ccc3(255,255,255); //Set color of label score
[self addChild:myScore]; //Add the score object
[self addChild:player.image]; //Add the player image object
[self callSpawnEnemy];
[self setUpMenus];
[self moveForward];
[self schedule:#selector(update:) interval:0.005]; //Schedule updating on 0.005 second intervals
}
+(void) resetAll{
[[CCDirector sharedDirector] replaceScene:[HelloWorldLayer scene]];
}
-(void) moveForward{ //Method to move the camera forward
[self runAction:[CCFollow actionWithTarget:player.image]];
}
+(CCScene*) scene{
CCScene *scene = [CCScene node];
HelloWorldLayer *layer = [HelloWorldLayer node];
[scene addChild: layer];
return scene;
}
-(void) dealloc{
[super dealloc];
}
-(void) achievementViewControllerDidFinish:(GKAchievementViewController *)viewController{
AppController *app = (AppController*) [[UIApplication sharedApplication] delegate];
[[app navController] dismissModalViewControllerAnimated:YES];
}
-(void) leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController{
AppController *app = (AppController*) [[UIApplication sharedApplication] delegate];
[[app navController] dismissModalViewControllerAnimated:YES];
}
#end
Any thoughts?
Jake
It seems that you called a class method(+) where you need to call the instance method(-). You just need to reset all the resources but not the whole object. And, as a class method, your +(void)resetAll method is meaningless for it has no return value.
I suggest, you may put all your resource-init codes into a single method, when you need to restart, just call [self removeAllChildrenWithCleanup:] and call that specified resource-init method.

Resources