I have a small game and I wish to present, in the menu, 2 game modes:
I have the first up and running from my original sprite kit scene and, in order to build my second one, I added another view to the storyboard, created another scene, linked them up just like the originals:
// Configure the view.
SKView * skView = (SKView *)self.view;
skView.showsFPS = NO;
skView.showsNodeCount = NO;
skView.multipleTouchEnabled = YES;
// Create and configure the scene.
SKScene * scene = [MyScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
and linked it to another button in my menu. The problem was, whenever i would press the button to go to the second game mode I would get a SIGABRT Thread 1 error. I made sure everything I linked was declared and valid and still got the error. I then removed the second SKScene (MyScene) and the view was loaded with no problem... just no content.
Is there a specific way I must proceed in order to have another View linked to a SpriteKit game?
Related
Im having a problem. When i present a new scene in spritekit (with objective c) It only shows a gray color with node and fps count on the screen.
I have animated the scene in the .sks file so it should not look like this.
The transition when im presenting the new scene also works, but it just wont show the images and background that i animated in the .sks file.
Here is the code on how i do it.
//In gameviewcontroller.m
// Creating and configuring the scene.
GameScene *Level1 = [GameScene nodeWithFileNamed:#"GameSceneLevel1"];
Level1.scaleMode = SKSceneScaleModeAspectFill;
// GameScene.m inside touchesbegan
SKTransition *reveal = [SKTransition doorwayWithDuration:4];
GameScene *Level1 = [GameScene sceneWithSize:self.view.bounds.size];
Level1.scaleMode = SKSceneScaleModeAspectFill;
[self.view presentScene:Level1 transition:reveal];
You have originally loaded scene from .sks file and as you said you have some animations there. Later on, (inside touchesBegan) you are creating a scene by providing a size (using sceneWithSize static method). So the scene is not loaded from from the archive.
To fix the problem, load your scene like you did initially, in the GameViewController.
EDIT:
To transition between two scenes you have to create two .sks files. You can name them like this : MenuScene and GameScene (you already have this one by default). Note that when you create these files you don't have to write an extension (.sks) but rather just file name. Then you have to create corresponding .m and .h files. So create MenuScene.m and MenuScene.h. GameScene .m and .h files are there by default.
MenuScene should be a subclass (not necessarily direct subclass) of an SKScene.
Then inside of your view controller:
- (void)viewDidLoad
{
[super viewDidLoad];
SKView * skView = (SKView *)self.view;
GameScene *scene = [GameScene nodeWithFileNamed:#"GameScene"];
scene.scaleMode = SKSceneScaleModeAspectFill;
scene.size = skView.bounds.size;
[skView presentScene:scene];
}
Later on in your GameScene's touchesBegan method if you want to transition to the MenuScene, you should do something like this :
MenuScene *nextScene = [MenuScene nodeWithFileNamed:#"MenuScene"];
SKTransition *transition = [SKTransition fadeWithDuration:3];
[self.view presentScene:nextScene transition:transition];
Similarly, to transition back to the GameScene, in your MenuScene's touchesBegan, do this:
GameScene *nextScene = [GameScene nodeWithFileNamed:#"GameScene"];
SKTransition *transition = [SKTransition fadeWithDuration:3];
[self.view presentScene:nextScene transition:transition];
Of course right before each transition you can set scene's scale mode to match the scale mode of the old scene.
From your code, it looks like you are trying to make a transition to the same scene: GameScene -> GameScene. That is certainly possible, but are you sure you wanted that ?
If so, just use the code I've provided for MenuScene's touchesBegan method.
I've done some searching but haven't found anything directly addressing my issue: I have an SKScene with several SKNodes each with SKSpriteNode objects for my game, and I am using a background UIImageView (there are some things I need to do with background that cannot be reasonable done with sprite kit - to my knowledge at least); the problem I'm having is that the UIImageView appears above everything and I can't see my game objects.
In my view controller (.m file) I have the following code to call my scene
#implementation GameViewController
- (void)viewDidLoad
{
[super viewDidLoad];
SKView * skView = (SKView *)self.view;
SKScene * scene = [GameScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
[skView presentScene:scene];
}
In the GameScene above, I have several SKNodes where all my game objects are children of (for example nodeHDU, nodePlay, nodePauseMenu...), and I am using a UIImageView as my background (I am switching between background scenes over time and am using some nice transitions such as UIViewAnimationOptionTransitionCrossDissolve; couldn't accomplish this with a SKSpriteNode as background without using multiple SKSpriteNodes and an intricate array of SKActions so I"m using UIImageView)
UIView *backgrounds = [[UIView alloc] init];
[self.view insertSubview:backgrounds belowSubview:self.view];
UIImageView *imageBackground = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,self.view.frame.size.width,self.view.frame.size.height)];
[backgrounds addSubview:imageBackground];
[backgrounds sendSubviewToBack:imageBackground];
[imageBackground setImage:[UIImage imageNamed:#"1-A.png"]];
imageBackground.alpha=1.0;
However, the ImageBackground above is the only thing I see when running the app in Xcode. The other objects from my game (children of other nodes) exist, and various NSLog statements are getting called, but they seem to appear behind the ImageBackground I have. The code above "belowSubview" and "sendSubviewToBack" don't help.
So How can I send the imageBackground to actually be the background?
Your problem is here that you are directly setting SKView as a controller view. To overcome from this issue don't make self.view a type of SKView. Do the following step in your storyboard or Xib :
Add an UIImageView on the controller's view first. Set the image as well.
Then add a SKView over the UIImageViewand set UIClearColor to the background colour.
So the complete hierarchy is like UIViewController->UIView->UIImageView->SKView
I am making an app that will switch to a different screen when it reaches a random number of clicks on the screen. I am using a button that is hidden to segue to the end screen. When I hide the button in the viewDidLoad, it will not appear when called in another method after it reaches the required number of randomized clicks Why does the hidden button not become visible?
-(void)viewDidLoad
{
[super viewDidLoad];
Final.hidden = YES;
SKView * skView = (SKView *)self.view;
skView.showsNodeCount = NO;
SKScene * scene = [BellPepperMyScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
[skView presentScene:scene];
}
-(IBAction)GoToNewScreen:(id)sender {
Final.hidden = false;
}
-(void)goToEndScreen{
[self GoToNewScreen:nil];
}
Assuming Final is a UIButton, there are a few things you want to be aware of. First is that you should be setting Final.alpha = 0, and not Final.hidden = YES. This can cause problems with it receiving touch events.
You should also make sure that you have the order of the views setup right. If you want to makes sure that the button is visible you can call [self.view bringSubviewToFront:Final].
I made a game using sprite kit in landscape mode. The only allowed orientations are landscape left and landscape right. When I select the banner ad in my game, rather than freezing the scene and returning to the original point in the game, the entire scene reinitializes itself (music player restarts, content shows as start screen, etc).
The same thing happens when I flip the phone around so that the orientation switches. How can I prevent this?
As for when you flip your phone you need this...
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
SKView * skView = (SKView *)self.view;
if ( !skView.scene ) {...
SKScene * scene = [MenuScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
[skView presentScene:scene];
}
}
I'm still looking into the iAd issue, I'll update if I figure anything out.
Thanks for the response. That was the problem. I had been initializing the scene in the viewWillLayoutSubviews method in my root view controller. I moved the scene initialization to the viewDidLoad method and it fixed the issue.
I have a viewcontroller with an SKview (I'm working with spritekit) inside of it and every time I change the orientation of the phone (from landscape one way to landscape another way or vise versa) it reloads the viewcontroller as if I had just opened the app (the viewcontroller is the initial one).
Is there a work around for it?
I can't seem to find anyone having the same problem.
Code:
http://pastie.org/8669630
You are setting up your SKView in viewWillLayoutSubview which gets called every time device is rotated (view frame changes).
Which is good, because view will have correct dimensions, but you should place some var to know should you set up the view again. For example BOOL sceneSetUp
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
if(!self.sceneSetUp){
// Configure the view.
SKView * skView = (SKView *)self.view;
//skView.showsFPS = YES;
// Create and configure the scene.
SKScene * startScene = [StartViewController sceneWithSize:skView.bounds.size];
startScene.scaleMode = SKSceneScaleModeAspectFill;
SKScene * scene = [gameViewController sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
// Present the scene.
[skView presentScene:startScene];
//[skView presentScene:scene];
self.sceneSetUp = YES;
}
}