I am building an iOS application using the spritekit framework, and I am trying to cause the screen to transition over to the next scene when the user taps the "start" button. I am able to get the screen to transition, and load the next scene, but it happens when the user taps ANYWHERE on the screen.I only want this to occur when the user taps the "start" spritenode. I created the start button using SKSpriteNode, and I named it startButton, using the name property.
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
SKAction *doNothing = [SKAction moveByX:0 y:0 duration:0];
if (startButton != nil)
{
[startButton runAction:doNothing completion:^{
SKScene *gamescene = [[GameScene alloc] initWithSize:self.size];
SKTransition *transition = [SKTransition doorsCloseHorizontalWithDuration:0.0];
[self.view presentScene:gamescene transition:transition];
}];
}
}
Thanks!
Instead of
if(startButton != nil){ }
try using this in the touchesBegan method
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
SKNode *node = [self nodeAtPoint:location];
if([node.name isEqualTo:#"startButton"]){
//start scene
}
Make sure that you set the name of the start button (label or sprite) like this
start.name = #"startButton";
EDIT:
Dont use
[startButton runAction:doNothing completion:^{
....
}
Instead, just transition right away
if([node.name isEqualTo:#"startButton"]){
SKScene *gamescene = [[GameScene alloc] initWithSize:self.size];
SKTransition *transition = [SKTransition doorsCloseHorizontalWithDuration:0.0];
[self.view presentScene:gamescene transition:transition];
}
Related
I have GamePlayScene that when ended, removes all nodes and displays the Score and an option to restart. I also have a button on that scene that takes you to another scene to display upgradable items. I would like to make a function that adds a back button on the "upgrade items" scene that returns me to the ended GamePlay scene. The code that I have right now returns me back to the GamePlay scene but restarts the game instead of displaying the Game Over text. I've tried searching online but I can't manage to find a good solution. My Code:
GamePlayScene.m
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
...
else if (self.restart) {
[[GameState sharedInstance] saveState];
if ([node.name isEqualToString:#"UpgradesButton"]){
UpgradeShipScene *upgradeScene = [UpgradeShipScene sceneWithSize:(self.frame.size)];
SKTransition *transition = [SKTransition fadeWithDuration:0.5];
[self.view presentScene:upgradeScene transition:transition];
}
...
}
UpgradesScene.m
-(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:#"BackButton"]){
for (SKNode *node in [self children]){
[node removeFromParent];
}
GamePlayScene *scene = [GamePlayScene sceneWithSize:self.view.bounds.size];
SKTransition *transition = [SKTransition fadeWithDuration:0.5];
[self.view presentScene:scene transition:transition];
}
}
You can use a SKNode as a "fake" SKScene, and then use a SKAction to animate it (to present or hide).
i'm trying to create an pause button in my game. at the moment when you click on the screen it will apply an impulse on the mover spriteNode. The problem is that it still applying the impulse when i click the pause button. How can i create an pause button without creating the impulse also.
i've tried changing the if statements to an else if and then making the last impulse part the else part, but this wont work.
touchBegan method:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
SKNode *node = [self nodeAtPoint:location];
//if fire button touched, bring the rain
if ([node.name isEqualToString:#"repeat"]) {
SKTransition *reveal = [SKTransition fadeWithDuration:2.0 ];
MyScene *newScene = [[MyScene alloc] initWithSize: CGSizeMake(self.size.width,self.size.height)];
// Optionally, insert code to configure the new scene.
[self.scene.view presentScene: newScene transition: reveal];
}
if ([node.name isEqualToString:#"home"]) {
SKTransition *reveal = [SKTransition fadeWithDuration:2.0 ];
Menu *newScene = [[Menu alloc] initWithSize: CGSizeMake(self.size.width,self.size.height)];
// Optionally, insert code to configure the new scene.
[self.scene.view presentScene: newScene transition: reveal];
}
if ([node.name isEqualToString:#"pause"]) {
[self pausedMenu];
}
if ([node.name isEqualToString:#"start"]) {
[self startMenu];
}
showpipes = showpipes + 1;
if (showpipes == 1) {
self.physicsWorld.gravity = CGVectorMake( 0.0, -5.0 );
SKAction* spawn = [SKAction performSelector:#selector(spawnPipes) onTarget:self];
SKAction* delay = [SKAction waitForDuration:2.0];
SKAction* spawnThenDelay = [SKAction sequence:#[spawn, delay]];
SKAction* spawnThenDelayForever = [SKAction repeatActionForever:spawnThenDelay];
[self runAction:spawnThenDelayForever];
}
started = 1;
if (noImpulse == 1) {
if (started == 1) {
mover.physicsBody.restitution = 0.0;
mover.physicsBody.velocity = CGVectorMake(0, 0);
[mover.physicsBody applyImpulse:CGVectorMake(0, 15)];
}
}
}
PAUSEDMENU METHOD:
-(void)pausedMenu
{
self.scene.paused = YES;
mover.scene.paused = YES;
[repeatButton removeFromParent];
[homeButton removeFromParent];
[menuBackground removeFromParent];
menuBackground = [SKSpriteNode spriteNodeWithColor:[SKColor colorWithWhite:0.0 alpha:0.3] size:CGSizeMake(self.frame.size.width*2, self.frame.size.height*2)];
[self addChild:menuBackground];
[pauseButton removeFromParent];
startButton = [SKSpriteNode spriteNodeWithImageNamed:#"staart"];
startButton.name = #"start";
startButton.position = CGPointMake(20, self.size.height-20);
startButton.size = CGSizeMake(40, 40);
[self addChild:startButton];
repeatButton = [SKSpriteNode spriteNodeWithImageNamed:#"repeat"];
repeatButton.name = #"repeat";
repeatButton.position = CGPointMake(self.size.width/2+30, self.size.height/2);
repeatButton.size = CGSizeMake(repeatButton.size.width/2, repeatButton.size.height/2);
[self addChild:repeatButton];
homeButton = [SKSpriteNode spriteNodeWithImageNamed:#"home"];
homeButton.name = #"home";
homeButton.position = CGPointMake(self.size.width/2-30, self.size.height/2);
homeButton.size = CGSizeMake(homeButton.size.width/2, homeButton.size.height/2);
[self addChild:homeButton];
}
Check out
https://developer.apple.com/library/ios/documentation/SpriteKit/Reference/SKView/Reference/Reference.html#//apple_ref/occ/instp/SKView/paused
If you pause your SKView that contains the game, all the state will be truly paused and you will be able to resume it after the pause menu has been dismissed. You'll have to present the pause menu in another SKView then the one that your game is contained in.
This question already has an answer here:
stop impulse on SKSpriteKit click
(1 answer)
Closed 8 years ago.
i'm creating an game where there is a pause button. For checking wether its touched i'm checking the location of the touch and if its equal to the paused button name.
When the pausedButton is clicked its call a method which pause the scene.
The problem is that in the touchBegan method whenever you touch the screen it apply an impulse, so when i press the pauseButton and unpause it the applyforce will come after. This is not ideal for the game. I've tried with a bool like shouldImpulse, but havent got it to work. here is my touchedBegan method:
-(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:#"home"]) {
SKTransition *reveal = [SKTransition fadeWithDuration:2.0 ];
Menu *newScene = [[Menu alloc] initWithSize: CGSizeMake(self.size.width,self.size.height)];
// Optionally, insert code to configure the new scene.
[self.scene.view presentScene: newScene transition: reveal];
}
if ([node.name isEqualToString:#"pause"]) {
[self pausedMenu];
}
if ([node.name isEqualToString:#"start"]) {
[self startMenu];
}
showpipes = showpipes + 1;
if (showpipes == 1) {
self.physicsWorld.gravity = CGVectorMake( 0.0, -5.0 );
SKAction* spawn = [SKAction performSelector:#selector(spawnPipes) onTarget:self];
SKAction* delay = [SKAction waitForDuration:2.0];
SKAction* spawnThenDelay = [SKAction sequence:#[spawn, delay]];
SKAction* spawnThenDelayForever = [SKAction repeatActionForever:spawnThenDelay];
[self runAction:spawnThenDelayForever];
}
started = 1;
if (started == 1) {
mover.physicsBody.restitution = 0.0;
mover.physicsBody.velocity = CGVectorMake(0, 0);
[mover.physicsBody applyImpulse:CGVectorMake(0, 15)];
}
}
You can do that with a simple IF, ELSE IF, ELSE:
if([node.name isEqualToString:#"home"])
{
// do stuff...
} else if ([node.name isEqualToString:#"pause"])
{
// do stuff...
} else if ([node.name isEqualToString:#"start"])
{
// do stuff...
} else
{
// do whatever else here...
}
I got the following Warning:
Incompatible pointer types sending 'MenuScene' to parameter of type 'uiviewcontroller'
I want to call the leaderboard from Game Center by klick on this button in my menu scene.
-(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:#"playButton"]) {
SKTransition *transition = [SKTransition fadeWithDuration:0.5];
MyScene *gameScene = [[MyScene alloc]initWithSize:CGSizeMake(self.size.width, self.size.height)];
[self.scene.view presentScene:gameScene transition:transition];
} else if ([node.name isEqualToString:#"leaderboardButton"]) {
[[GameCenterHelper defaultHelper] showLeaderboardOnViewController:self];
}
at this last lane, i got the warning
you should present a ViewController from root view controller, so you should do:
if ([node.name isEqualToString:#"leaderboardButton"]) {
UIViewController *vc = self.view.window.rootViewController;
[[GameCenterHelper defaultHelper] showLeaderboardOnViewController:vc];
In the SKScene gamescene I alloc the scene but it has an error message with No visible #interface with 'SKScene' declares the selector alloc.
I have think this means im not declaring it in my interface?? Corrections plz.
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
SKNode *node = [self nodeAtPoint:location];
// if play button touched, start transition to next scene
if ([node.name isEqualToString:#"play"]) {
NSLog(#"play pressed");
SKScene *GameScene = [[GameScene alloc] initWithSize:self.size];
SKTransition *flip = [SKTransition flipVerticalWithDuration:1.0];
[self.view presentScene:GameScene transition:flip];
}
}
It looks like you are trying to create a variable that is the same name as the class!
SKScene *GameScene = [[GameScene alloc] initWithSize:self.size];
This is probably confusing the compiler. Change the variable name of *GameScene to something else and see if that works.