SpriteKit background not fitting to screen on iPhone 6 plus - ios

I am using a scale mode fill to load a scene with a background with size of 640x1136 as follows:
SKView * skView = (SKView *)self.view;
skView.ignoresSiblingOrder = YES;
MainMenu *scene = [MainMenu sceneWithSize: self.view.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
[skView presentScene:scene];
I am then loading the background inside the screen:
SKSpriteNode *menuBg = [SKSpriteNode spriteNodeWithImageNamed:#"mainBg"];
menuBg.anchorPoint = CGPointZero;
menuBg.position = CGPointZero;
[self addChild:menuBg];
And I expected the backgorund to fill the screen, however it won't resize to fill the screen. I am only holding a #2x background image - what am I doing wrong?

You are not positioning the node in the center of the scene and therefore it won't be scaled correctly with the Aspect Fill scalemode.
Try this instead:
menuBg.anchorPoint = CGPointMake(0.5, 0.5);
menuBg.position = CGPointMake(self.size.width/2, self.size.height/2)
It will set the anchor to the center of your node, and position the node in the center of the scene.

Related

SKSpriteNode position

I am trying to (learn how to) build a game using SpriteKit and i ran into a problem that has been bugging me for hours.
I have a class named Tank with the following constructor:
+ (instancetype)tankAtPosition:(CGPoint)position {
Tank *tank = [self spriteNodeWithImageNamed:#"tank_base_1"];
tank.position = position;
tank.anchorPoint = CGPointMake(0.5, 0.5);
return tank;
}
In my scene i have the following constructor:
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
SKSpriteNode *background = [SKSpriteNode spriteNodeWithImageNamed:#"level_bg_1"];
background.xScale = 0.40f;
background.yScale = 0.40f;
background.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
[self addChild:background];
Tank *tank = [Tank tankAtPosition:CGPointMake(CGRectGetMidX(self.frame), 512)];
[self addChild:tank];
}
return self;
}
which compiled results in the following render:
Everything ok for now, however, if i change the y of the tank to 256:
Tank *tank = [Tank tankAtPosition:CGPointMake(CGRectGetMidX(self.frame), 256)];
I get this:
As far as i know, the bottom is y = 0 and and the middle point y = 512, so when i specify a y = 256 it should be centered in the bottom half of the screen. Why is is near the edge?
The testing device is a ipad retina mini and in the Deployment Info > Devices i specified iPad.
What am i missing? Thank you.
i figured it out. the frame size was all messed up because i set my game to run in landscape only. solution: initialize the scene in viewDidLayoutSubviews instend of viewDidLoad
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
// Configure the view.
SKView * skView = (SKView *)self.view;
skView.showsFPS = YES;
skView.showsNodeCount = YES;
// Create and configure the scene.
SKScene * scene = [Level sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
// Present the scene.
[skView presentScene:scene];
}

adding a SpriteKit particle to existing app

Ive added a SpriteKit particle to my app - The skView has been added to an existing image view (myImageView). All works well but the skScenne cannot be set to clear colour to show myImage behind the emitter. You can change the colour but not to clear colour ?? `
SKView *skView = [[SKView alloc] initWithFrame:CGRectMake(0.0, 0.0, 768, 1024)];
[myImageView addSubview:skView];
SKScene *skScene = [SKScene sceneWithSize:skView.frame.size];
skScene.scaleMode = SKSceneScaleModeAspectFill;
skScene.backgroundColor = [UIColor clearColor];
SKEmitterNode *emitter = [NSKeyedUnarchiver unarchiveObjectWithFile:[[NSBundle mainBundle] pathForResource:#"MyParticle" ofType:#"sks"]];
emitter.position = CGPointMake(400,0);
[skScene addChild:emitter];
[skView presentScene:skScene];
[self.view addSubview:myImageView];
Unfortunately you can't make an SKView transparent in iOS 7. In iOS 8 it works by using:
skView.allowsTransparency = YES;
skScene.backgroundColor = [UIColor clearColor];
In iOS 7 you can add a large spriteView that is as big as your skView as background and set your myImage as texture.
I suggest you avoid setting the color of your SKScene to [UIColor clearColor] for performance reasons (use opaque views whenever possible). Instead, you can create an SKSpriteNode and add it to your scene as the background...
SKSpriteNode *background = [SKSpriteNode spriteNodeWithImageNamed:#"image"];
background.size = CGSizeMake(self.view.frame.size.width, self.view.frame.size.height);
// Bottom/left of your image
background.anchorPoint = CGPointZero;
background.position = CGPointZero;
// Make sure the background is behind other nodes in the scene
background.zPosition = -100;
[self addChild:background];
Since the background is added to the SKScene, it is automatically removed/released when you transition to a new scene.

Not working right, start and end positon

I'm trying to graph some trigonometric functions on an SKScene.. I'm using an SKShapeNode for each point in the screen so when it reaches the left side I remove if from the parent.
The problem is that, for some reason it only draws on a portion of the screen as if it were contained by a smaller view.. The position on the screen is not matching the real screen... for example if I place it at 100 it is actually at a different place.. Plus the size of the area where it graphs is reduced...
There is some code at the bottom
I hope someone could help me! Thank you very much!
Anything else that might help ask and I'll re-edit the post.
Thank you!
Here is some code:
- (void) createTrigonometricFunction
{
[self calculateFunction];
CGMutablePathRef pathToDraw = CGPathCreateMutable();
CGPathMoveToPoint(pathToDraw, NULL, groundOriginLocation.x,groundOriginLocation.y + groundPointPrevious.y);
CGPathAddLineToPoint(pathToDraw, NULL, groundOriginLocation.x + 1,groundOriginLocation.y + groundPointCurrent.y);
SKShapeNode * currentLine = [SKShapeNode node];
currentLine.position = CGPointMake(groundOriginLocation.x,groundOriginLocation.y);
currentLine.path = pathToDraw;
CGPathRelease(pathToDraw);
[currentLine setStrokeColor:[UIColor whiteColor]];
currentLine.name = #"terrainLine";
currentLine.lineWidth = 1;
[currentScene addChild: currentLine];
groundPointPrevious = groundPointCurrent;
//NSLog(#"%f - %f",currentLine.position.x,currentLine.position.y);
}
- (void) calculateFunction
{
groundDominio += 1;
groundPointCurrent.x = groundOriginLocation.x;
groundPointCurrent.y = 2*(sin(degreesToRadian(groundDominio)*2)/5*degreesToRadian(180))*cos(degreesToRadian(150) + degreesToRadian(groundDominio)*5)*sin(degreesToRadian(groundPointCurrent.x));
groundPointCurrent.y = radianToDegrees(groundPointCurrent.y);
}
//The view controller:: (This is how I load it)
- (void)viewDidLoad
{
[super viewDidLoad];
// Configure the view.
SKView * skView = (SKView *)self.view;
//skView.showsFPS = YES;
skView.showsNodeCount = YES;
// Create and configure the scene.
SKScene * scene = [MainGame sceneWithSize: skView.bounds.size];
//scene.scaleMode = SKSceneScaleModeAspectFill;
NSLog(#"%f $$ %f",self.view.frame.size.height,self.view.frame.size.width);
// Present the scene.
[skView presentScene:scene];
}
Do you draw on the scene or on another node?
If you are drawing on another node, your drawing will be off since the default anchor point for node is 0.5, 0.5 (it is pinned to scene with its center) but the actual 0.0 position inside the node is not its center.

Sprite Kit Particle Emitter Clear Background & Storyboard

I have placed some images and buttons on a storyboard connected to my view with a Particle Emitter on a SKView. The problem is that no matter how many places I set the background color to clearColor the background appears to be black and I cannot see the elements on my storyboard. With Particle Emitters can you use the storyboard?
SKView *skView = [[SKView alloc] initWithFrame:self.view.bounds];
skView.backgroundColor = [SKColor clearColor];
SKScene *scene = [SKScene sceneWithSize:self.view.bounds.size];
scene.backgroundColor = [SKColor clearColor];
// Set the scale mode to scale to fit the window
scene.scaleMode = SKSceneScaleModeAspectFit;
[skView presentScene:scene];
NSString *myParticlePath = [[NSBundle mainBundle] pathForResource:#"snowParticle" ofType:#"sks"];
SKEmitterNode *snowParticle = [NSKeyedUnarchiver unarchiveObjectWithFile:myParticlePath];
snowParticle.particlePosition = CGPointMake(0, 568);
[scene addChild:snowParticle];
[self.view addSubview:skView];
Thanks,

SKScene iPad height width reversed

I am trying to fill my SKScene with tiles, in an iPad app that only supports landscape mode. Within the scene I detect h & w as such:
int h = [UIScreen mainScreen].bounds.size.height;
int w = [UIScreen mainScreen].bounds.size.width;
Unfortunately, the dimensions sent back are the reverse of what they need to be. There are lots of topics in SO discussion this problem within the content of a view controller or a view, and the solution seems to be to detect screen size in viewWillAppear, not in viewDidLoad. This does not seem to be a valid solution for SKScenes, however.
Any suggestions?
Try, not using viewDidLoad and use this
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
SKView * skView = (SKView *)self.view;
if (!skView.scene) {
skView.showsFPS = YES;
skView.showsNodeCount = YES;
SKScene * scene = [MyScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
// Present the scene.
[skView presentScene:scene];
}
}
It doesn't make sense to initialize the scene in the layout handler. Resize the scene in the layout handler. (That's what it's for.)
#implementation SGOMyScene
{
SKScene *scene;
}
- (void)viewDidLoad
{
[super viewDidLoad];
SKView *skView = (SKView *)self.view;
skView.showsFPS = YES;
skView.showsNodeCount = YES;
scene = [SGOMyScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
[skView presentScene:scene];
}
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
SKView *skView = (SKView *)self.view;
scene.size = skView.bounds.size;
}
Your scene should implement - (void)didChangeSize:(CGSize)oldSize to move everything into the right place.
Hooray, now your game handles device rotations too.

Resources