SKScene: bounds of scene - ios

How can I get the bound of scene?
I'm testing with demo and I initialize scene in this way:
GameScene *scene = [GameScene unarchiveFromFile:#"GameScene"];
scene.scaleMode = SKSceneScaleModeAspectFill;
So, when I tap on screen I log:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
CGPoint location = [touch locationInNode: self];
NSLog(#"%f, %f", location.x, location.y);
}
}
When I press left-bottom I get circa 300-0 while I'm expecting 0-0.
How can I get the top-bottom-left-right bounds? I can't find a method like:
[scene getBounds]
Scene.frame prints: (0,0,1024,768) that not corresponds!!

You need to set the size of the GameScene to be equal to the size of its SKView. You can either do this in the didMoveToView of your GameScene:
-(void)didMoveToView:(SKView *)view {
[super didMoveToView: view];
self.size = view.bounds.size;
}
Or, you can set the size when you instantiate your GameScene:
SKView * skView = (SKView *)self.view;
// ...
GameScene *scene = [GameScene unarchiveFromFile:#"GameScene"];
scene.scaleMode = SKSceneScaleModeAspectFill;
scene.size = skView.bounds.size;
[skView presentScene:scene];

Initialize scene like this:
GameScene *scene = [GameScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
Test coordinates like this:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
/* Pressed node */
SKNode *node = [self nodeAtPoint:location];
NSLog(#"x - %f; y - %f", location.x, location.y);
}

Related

how to make a button in Sprite kit for touchesBegan

basically for now I got TitleScene, where are present name of the my game and when tap anywhere on screen it jumps to GameScene, it looks something like this:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
SKScene *scene = [GameScene sceneWithSize:self.size];
SKTransition *transition = [SKTransition pushWithDirection:SKTransitionDirectionUp duration:1.0f];
[self.view presentScene:scene transition:transition];
}
My question how can i change this method to button?
maybe give your sprite a name of "button" so you know which one youre touching
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
/* Called when a touch begins */
for (UITouch *touch in touches) {
CGPoint location = [touch locationInNode:self];
SKNode *touchedNode = [self nodeAtPoint:location];
if (touchedNode && [touchedNode.name isEqual:#"button"]) {
// your code here
}
}
}

Returning To Previous Scene In Same Condition

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).

How to call leaderboard from SKNode Button in MenuScene

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];

Error for SKScene alloc

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.

Linking HUDLayer to GameplayLayer properly

I'm trying to pass the touch location from GameplayLayer to HUDLayer to see if user presses control buttons.
HudLayer.mm
-(void) handleTouchAtLocation:(CGPoint) location {
NSLog(#"Touch passed to HUD");
}
Gameplay.mm
enum {
kHudLayer = 2;
};
+(CCScene *) scene {
CCScene *scene = [CCScene node];
HudLayer *hud = [HudLayer node];
[scene addChild:hud z:kHudLayer];
GameplayLayer *layer = [GameplayLayer node];
[scene addChild:layer];
return scene;
}
-(void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
for( UITouch *touch in touches ) {
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL: location];
[self handTouchAtPoint:(location)];
}
}
-(void) handleTouchAtPoint:(CGPoint)location {
NSLog(#"Touch At Point");
HudLayer *h1 = (HudLayer *)[self.parent getChildWithTag:kHudLayer];
[h1 handleTouchAtLocation:location];
}
HudLayer.h is imported in GameplayLayer.h.
I'm getting the "Touch At Point" log but it's not going through to HUD layer for some reason..
The only explanation is that self.parent has no child with the tag kHudLayer. If you set a breakpoint in handleTouchAtPoint you'll notice h1 being nil after the getChildWithTag line did execute.

Resources