I'm trying to position the background all over the scene background, but for some reason it puts it outside of screen.
This is what I used:
SKTexture *backgroundTexture = [self.atlas textureNamed:#"back"];
SKSpriteNode *background = [SKSpriteNode spriteNodeWithTexture:backgroundTexture size:self.view.frame.size];
background.position = (CGPoint) {CGRectGetMidX(self.view.frame), CGRectGetMidY(self.view.frame)};
[self addChild:background];
This is how it puts it:
You need to add your background image to the SKScene view and as such determine the coordinates from self.
SKSpriteNode *backgroundNode = [SKSpriteNode spriteNodeWithImageNamed:#"BackgroundImage"];
backgroundNode.position = CGPointMake(self.size.width/2, self.size.height/2);
backgroundNode.zPosition = 1;
[self addChild:backgroundNode];
Actually the problem was that in the new Xcode 6.3.1 when you create a new scene it adds a SKScene view of some kind, this view is bigger then the iPhone normal screen, maybe it's iPhone 6+ screen size that's why the background image was out of screen bounds. I just had to remove this view file and not reload it from code and then it worked out.
Thanks anyway, the comment above helped me to understand that.
Related
I am a beginner to iOS app coding but not to coding in general. I am following a tutorial for a sprite game kit app and I am having some trouble with the sizing of stuff. It came time to put in edges so the balls can bounce off of them. I noticed that the edges seemed to be off the screen, the balls would leave the screen then bounce back.
So I had xcode output the width/height, it said 320x568. I also change the scale mode by setting scene.scaleMode = SKSceneScaleModeAspectFit; and you can see the boundaries look like a square:
If I put the scaling back to normal by scene.scaleMode = SKSceneScaleModeAspectFill; It shows the screen like this:
but the balls still go off the screen.
By the way, I believe I am setting the edge nodes correctly to be on the left and right edge so I don't think that is the issue.
// Add edges
SKNode *leftEdge = [[SKNode alloc] init];
leftEdge.physicsBody = [SKPhysicsBody bodyWithEdgeFromPoint:CGPointMake(0, 0) toPoint:CGPointMake(0, self.size.height)];
leftEdge.position = CGPointMake(0, 0);
[self addChild:leftEdge];
SKNode *rightEdge = [[SKNode alloc] init];
rightEdge.physicsBody = [SKPhysicsBody bodyWithEdgeFromPoint:CGPointMake(0, 0) toPoint:CGPointMake(0, self.size.height)];
rightEdge.position = CGPointMake(self.size.width, 0);
[self addChild:rightEdge];
In your GameScene file (or whatever you may have called the SKScene file), add this method to the start of didMoveToView:
self.size = self.view.frame.size;
What is happening is that your game thinks the screen is running a different size. You need to change self.size to the actual size of the frame you are working with. The above method works with SKSceneScaleModeAspectFill, but I have not yet tested it with the other modes. Good luck!
I'm having a little trouble implementing a background change when the player hits a certain score.
I'm using the if(self.score>=10) line to tell my game to change the background but it doesn't seem to be working. I have no errors with this line but no results either.
What I have:
#implementation Scene{
SKScrollingNode * floor;
SKScrollingNode * back;
SKLabelNode * scoreLabel;
}
- (void) createBackground
{
back = [SKScrollingNode scrollingNodeWithImageNamed:#"back" inContainerWidth:WIDTH(self)];
if(self.score>=10){
back = [SKScrollingNode scrollingNodeWithImageNamed:#"image2" inContainerWidth:WIDTH(self)];
[back setAnchorPoint:CGPointZero];
[back setPhysicsBody:[SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame]];
back.physicsBody.categoryBitMask = backBitMask;
back.physicsBody.contactTestBitMask = birdBitMask;
[self addChild:back];
}
there are certain points you have to keep in your mind i think your both background contains physics body
1)may be and the time of transition they first background colliding with second background and they preventing each other to swap
change your collisionBitMask for both background ->prevent them for colliding
for eg
bg.physicsBody.categoryBitMask=bg1;
bg.physicsBody.collisionBitMask=0;
bg.physicsBody.contactTestBitMask=bg2;
bg.physicsBody.categoryBitMask=bg2;
bg.physicsBody.collisionBitMask=0;
bg.physicsBody.contactTestBitMask=bg1;
or use skaction to swap backgrounds
The way i would do this would be to create a brand new SKScene entirely with a new background.
Or if you want them to scroll to the next background. I would create two backgrounds.
Ex.
//this syntax is wrong (dont remember)
//initializing
SKSpriteNode *bg1 = [SKSpritenode spritenodefromImage:#"bg1"];
SKSpriteNode *bg1 = [SKSpritenode spritenodefromImage:#"bg1"];
bg1.position = CGPointMake(self.size.width/2, self.size.height/2);
bg2.position = CGPointMake(self.size.width/2 + bg1.size.width, self.size.height/2);
//////////////////////////////
//then when you want to scroll them
-(void)scrollBackgrounds
{
bg1.position = CGPointMake(bg1.position.x - 5, self.size.height/2);
bg2.position = CGPointMake(bg2.position.x -5 , self.size.height/2);
}
I am having a little trouble doing something that is supposed to be very simple.
I cannot get the floor of my tiles to display above a background picture. However I can get all my other game objects to show from my control pad, to my HUD to even coins and monsters set up in the same tile map. Basically everything appears in front the background like I expect the floor of my tilemap so it looks like im walking on air. I have tried many things like changing which layer i add the background picture or the tilemap floor too, or even tried setting it the same way i set my characters but same results. Tilemap floor is always at the back.
Adding my Set up code, Hope it is helpful too solving the problem.
I created this BG sprite since, I wanted my tilemap to scroll vertically or horzi. automatically. So the easiest way I found to do that was to make the tilemap the child of the "bg" and scroll the "bg" hence scrolling the tile map. However, I have tried setting the background as the child of the bg and setting the Z for both of them but that didnt seem to help.
Thanks in advance for any help in solving this
#implementation GameLevelScene
{
SKNode *_worldNode;
SKSpriteNode *bg;
SKSpriteNode *bkg;
}
Init
-(id)initWithSize:(CGSize)size level:(int)level {
if (self = [super initWithSize:size]) {
// [self showBackground];
NSDictionary *levelData = config[#"levels"][level];
//[show background];
if (levelData[#"tmxFile"]) {
[self showBackground];
_tileMap = [ JSTileMap mapNamed:levelData[#"tmxFile"]];
}
//self.backgroundColor = [SKColor colorWithRed:.4 green:.4 blue:.95 alpha:1.0];
// UIImage *bkgb =[UIImage imageNamed:#"land.jpg"];
// self.position=CGPointZero;
// self.anchorPoint=CGPointZero;
// self.backgroundColor=[UIColor colorWithPatternImage:bkgb];
//Above code shows no picture but it changes the color
[self setUpWorld];
[self createChar];
[self controlPadNode];
//[show background];
}
return self;
}
setUpWorld
- (void)setUpWorld
{
bg = [SKSpriteNode spriteNodeWithImageNamed:#"bg3"];
bg.userInteractionEnabled=NO;
bg.anchorPoint = CGPointZero;
bg.zPosition=0;
bg.position = CGPointZero;
bg.name = #"bg";
[self addChild:bg];
_worldNode = [SKNode node];
if (_tileMap) {
[bg addChild:_tileMap];
}
[bg addChild:_worldNode];
self.physicsWorld.contactDelegate = self;
}
create char
- (void)createChar
{
_Layer = [[TmxTileMapLayer alloc]
initWithTmxObjectGroup:[_tileMap
groupNamed:#"LevelOneObjects"]
tileSize:_tileMap.tileSize
gridSize:_bgLayer.gridSize];
[self addChild:_Layer];
}
Create Control
- (SKSpriteNode *)controlPadNode
//-(void)controlPad
{
SKSpriteNode *controlPadNode = [SKSpriteNode spriteNodeWithImageNamed:#"controller.png"];
controlPadNode.position = CGPointMake(100,50);
controlPadNode.name = #"controlPadNode";
controlPadNode.zPosition = 1.0;
[self addChild:controlPadNode];
}
background
-(void)showBackground
{
bkg = [SKSpriteNode spriteNodeWithImageNamed:#"desert_land.jpg"];
bkg.userInteractionEnabled=NO;
bkg.anchorPoint = CGPointZero;
bkg.position = CGPointZero;
bkg.zPosition=-1;
bkg.name = #"bkg";
// [self addChild:bkg];
//[_tileMap addChild:bkg];
// [_worldNode addChild:bkg];
[bg addChild:bkg];
}
Set your bkg.zposition to 1 and set your bg.zPosition to 2.
Also, the whole point of having a tile map is NOT to use a gigantic background picture but to instead use tiles.
** Update **
I just tested your code and ran a sample project myself. I assume you are using the Tiled app for your tiles. I ran variations on parents (self, worldNode, etc...) and zPositions. The bottom line is you cannot do it. Tiled does not have an alpha channel for its background color options. So either the background image is covered by the tile map or, in your case, the background image covers the tile map.
Your possible solutions are to either not use Tiled and place your tiles manually or to look for another tile app which has an alpha channel.
I noticed that where you define the wall properties of the tile if you say
SKSpriteNode* wall =
[SKSpriteNode spriteNodeWithColor:[SKColor greenColor]
size:CGSizeMake(w, h)];
the green color will be uptop of the background. Bit of a dirty fix than an answer
I am trying to put together a tile-map for a game background. The tiling works in portrait mode but when I switch to landscape, I get a blank screen.
The code is listed below:
-(SKNode *)createBackgroundNode
{
SKNode *backgroundNode = [SKNode node];
for (int nodeCount = 0; nodeCount < 20; nodeCount++) {
NSString *backgroundImageName = [NSString stringWithFormat: #"Background%02d", nodeCount+1];
SKSpriteNode *node = [SKSpriteNode spriteNodeWithImageNamed: backgroundImageName];
node.anchorPoint = CGPointMake(0.0f, 0.0f);
node.position = CGPointMake(nodeCount * 320.0f, 0.0f);
//node.position = CGPointMake(160.0f, nodeCount * 64.0f);
[backgroundNode addChild: node];
}
return backgroundNode;
}
Basically it is a game that is only played in landscape mode, and I need the tiles to be placed horizontally one after the other to create the map.
Any help with this is appreciated! Thanks in advance!
Edit: Sorry if I wasn't clear, my game only supports landscape orientation. When my iPhone is in landscape orientation, I am unable to see my map. If I play with the settings in XCode and allow the app to be in portrait orientation, I am able to see the tile map going across the screen; however, this is NOT what I want and I only did that to see if it works.
Switching screen orientation while using tile maps is not advisable. Once you have loaded your tile map, you would be better off staying in the selected orientation mode. AT least that has been my own experience using the Tiled app.
I'm trying to set a background texture and I want it to cover the entire screen.
I prepared the background files exactly to size in photoshop before hand. There are 2 files in my project:
background.png - 1024x768px
background#2x.png - 2048x1536px
I am running the following code:
SKTexture *backgroundTexture = [SKTexture textureWithImageNamed:#"background"];
SKSpriteNode *background = [SKSpriteNode spriteNodeWithTexture:backgroundTexture];
background.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
background.size = CGSizeMake(750, 550);
[self addChild:background];
And it is giving me this result http://d.pr/i/Ej2m - notice that the entire screen is almost filled and the background size is background.size = CGSizeMake(750, 550). Why is this?
You manually changed the sprite's size:
background.size = CGSizeMake(750, 550);
So it will display in a smaller region (750x550) than its original size (1024x768). Allow me to say: d'uh! ;)