Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

newtomac123

macrumors newbie
Original poster
Jan 8, 2014
18
0
So I found this online video tutorial about basically beginning to create "games" in iOS. I've been doing well with the tutorial, but I have run into a road block. Basically I wanted to make the background from an image (which works fine). Then I placed an image at the bottom of the iOS screen in the center of the screen (also works fine). Now i'm trying to get another image placed on the screen (one is a brick,the other is a little plane) but they both do not work.... I've tried changing the ( [_bgLayer addChild:sprite1];) _bgLayer to my other variables and even to self, but the node will not add to the screen........ Anyone can point me in the right direction? I'm really not sure what happened...

The following is all in my game scene.m It was working fine until i tried to add the 3rd node (the plane shadow below or the player plane).

Code:
#import "GameScene.h"
#import "stdint.h"

@implementation GameScene{
    SKSpriteNode *planeShadow;
    
    SKNode *_bgLayer;
    SKNode *_gameLayer;
    SKNode *_HUDLayer;
    
    NSTimeInterval *_dt;
    NSTimeInterval *_lastUpdateTime;
    
    SKSpriteNode *_playerPlane;
    
}

//static const uint32_t planeCategory = 1 << 0;
//static const uint32_t worldCategory = 1 << 1;
//static const uint32_t skyCategory = 1 << 4;
//static const uint32_t pipeCategory = 1 << 2;
//static const uint32_t scoreCategory = 1 << 3;



-(void)didMoveToView:(SKView *)view {
   
  //  self.physicsWorld.gravity = CGVectorMake(0.0, -5.0);
    //self.physicsWorld.contactDelegate = self;
    
    
    /* Setup your scene here */
   
    self.backgroundColor = [SKColor whiteColor];
    
    _bgLayer = [SKNode node];
    [self addChild:_bgLayer];
    _gameLayer = [SKNode node];
    [self addChild:_gameLayer];
    _HUDLayer = [SKNode node];
    [self addChild:_HUDLayer];
    
    
    //planeShadow = [SKSpriteNode spriteNodeWithImageNamed:@"bric"];
    //planeShadow.zPosition = 11;
    //planeShadow.position = CGPointMake(60,500);
    //[_gameLayer addChild:planeShadow];
    
    
    SKTexture *backgroundTexture = [SKTexture textureWithImageNamed:@"secondcloud1"];
    //SKAction *moveBg = [SKAction moveByX:-backgroundTexture.size.width*2 y:0 duration:0.1*backgroundTexture.size.width];
    //SKAction *resetBg = [SKAction moveByX:backgroundTexture.size.width*2 y:0 duration:0];
    //SKAction *moveBackgroundForver = [SKAction repeatActionForever:[SKAction sequence:@[moveBg, resetBg]]];
    //for( int i = 0; i <2 + self.frame.size.width / ( backgroundTexture.size.width * 2); ++i){
     
        SKSpriteNode* sprite = [SKSpriteNode spriteNodeWithTexture:backgroundTexture];
        [sprite setScale:1.0];
        sprite.zPosition = -20;
    sprite.anchorPoint = CGPointMake(0.5, 0.0);
        sprite.position = CGPointMake(CGRectGetMidX(self.frame), 0);
       // [sprite runAction:moveBackgroundForver];
        [_bgLayer addChild:sprite];
       // }
    

    
    
    SKTexture *groundTexture = [SKTexture textureWithImageNamed:@"ground"];
    //SKAction *moveBg = [SKAction moveByX:-backgroundTexture.size.width*2 y:0 duration:0.1*backgroundTexture.size.width];
    //SKAction *resetBg = [SKAction moveByX:backgroundTexture.size.width*2 y:0 duration:0];
    //SKAction *moveBackgroundForver = [SKAction repeatActionForever:[SKAction sequence:@[moveBg, resetBg]]];
    //for( int i = 0; i <2 + self.frame.size.width / ( backgroundTexture.size.width * 2); ++i){
    
    SKSpriteNode* sprite1 = [SKSpriteNode spriteNodeWithTexture:groundTexture];
    [sprite1 setScale:1.0];
    sprite1.zPosition = 10;
    sprite1.anchorPoint = CGPointMake(0.5, 0.0);
    sprite1.position = CGPointMake(CGRectGetMidX(self.frame), 0);
    // [sprite runAction:moveBackgroundForver];
    [_bgLayer addChild:sprite1];



    
    _playerPlane = [SKSpriteNode spriteNodeWithImageNamed:@"pixelPlane"];
    _playerPlane.position = CGPointMake(60,400);
    _playerPlane.zPosition = 50;
   // _playerPlane.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(46,18)];
   // _playerPlane.physicsBody.dynamic = YES;
   // _playerPlane.physicsBody.allowsRotation = NO;
  //  _playerPlane.physicsBody.categoryBitMask = planeCategory;
  //  _playerPlane.physicsBody.collisionBitMask = worldCategory | skyCategory | pipeCategory;
  //  _playerPlane.physicsBody.contactTestBitMask = worldCategory | skyCategory | pipeCategory;
    [_gameLayer addChild:_playerPlane];

}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    /* Called when a touch begins */
    
    for (UITouch *touch in touches) {
        CGPoint location = [touch locationInNode:self];
        
        SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"];
        
        sprite.xScale = 0.5;
        sprite.yScale = 0.5;
        sprite.position = location;
        
        SKAction *action = [SKAction rotateByAngle:M_PI duration:1];
        
        [sprite runAction:[SKAction repeatActionForever:action]];
        
        [self addChild:sprite];
    }
}
 
Last edited:

solinari6

macrumors regular
Aug 13, 2008
101
13
Whenever I've had this happen, it's usually due to the sprite getting drawn offscreen. Try messing around with the position and anchor point to see if you can get it to show up.
 

newtomac123

macrumors newbie
Original poster
Jan 8, 2014
18
0
Sprite Question

My apologies:

https://www.youtube.com/watch?v=UuvsNwyngGI
is the video link.

I'll continue to mess with the anchor point/position

I was just moving things around, and still no luck... It appears that the node is not being put into either layer (bg/game/hud/self). It still states I have 2 nodes in the project when I start (the secondclounds.png and ground.png)...... Any other thoughts?

I'm sure it is something small that I somehow have been skipping over...
 
Last edited:

solinari6

macrumors regular
Aug 13, 2008
101
13
well I generally start trying weird stuff, so my advice is see if this works:

Don't add the game later to self until you put the sprite on it

Or, add the sprite to game layer, then remove game layer from self, and re-add it
 

newtomac123

macrumors newbie
Original poster
Jan 8, 2014
18
0
Sprite Question - Buttons

Thank you all so much for your help, but if anyone can enlighten me on one quick issue. So basically. I'm working in sprite kit and i wanted to create a button, which i did using the following code:
Code:
 SKSpriteNode* thisisstart = [SKSpriteNode spriteNodeWithImageNamed:@"maingame2.png"];
        thisisstart.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
        thisisstart.name = @"startbutton";
        [_bgLayer addChild:thisisstart];

It works fine, but the problem I am having is attempting to REMOVE the button after it is pressed. I have it setup with the following code to go to "New Game" after the button is pressed
Code:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    /* Called when a touch begins */
    
 
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInNode:self];
    SKNode *node = [self nodeAtPoint:location];
    
    if ([node.name isEqualToString:@"startbutton"]) {
        [self NewGame];
        [thisisstart removeFromParent];
    }
    
 }
The button works fine and it goes directly to NewGame. The issue though it that i Can't remove the thisisstart sprite node from the parent to get it out of the way. I've tried moving the [thisisstart removefromparent]; to multiple places, In my mind it should be working but it isn't. The button is present throughout the game, and no matter where I seem to put the line it doesn't work. I've even tried in if/else statements without much luck. Anyone have any idea why i'm unable to remove the sprite? Or am i declaring the button as the wrong type of sprite?

Thank you again!
 

Boris-VTR

macrumors regular
Apr 18, 2013
247
17
I bellieve you should remove node like this:
Code:
[thisisstart.node removeFromParent];
 

newtomac123

macrumors newbie
Original poster
Jan 8, 2014
18
0
Would not work.

I've changed the line to: [thisisstart.node removeFromParent];

but it is giving me an error:
'Property 'node' not found on object of type 'SKSpriteNode'.' Any ideas?
 

JohnsonK

macrumors regular
Mar 6, 2014
142
0
I've changed the line to: [thisisstart.node removeFromParent];

but it is giving me an error:
'Property 'node' not found on object of type 'SKSpriteNode'.' Any ideas?

SKSpriteNode is a node itself... Try removing the .node part
 

newtomac123

macrumors newbie
Original poster
Jan 8, 2014
18
0
Hrmm

Hrmm.. Still not working...

I had
Code:
[thisisstart removeFromParent];

Prior...... oh well.. thank you very much anyways.
 
Last edited:

chown33

Moderator
Staff member
Aug 9, 2009
10,748
8,421
A sea of green
Hrmm.. Still not working...

I had
Code:
[thisisstart removeFromParent];

Prior...... oh well.. thank you very much anyways.
Your posted code looks incomplete or inconsistent. The question I have is this:
Where does thisisstart get set (assigned a value), and what is its scope?​

You posted this code fragment:
Code:
 SKSpriteNode* thisisstart = [SKSpriteNode spriteNodeWithImageNamed:@"maingame2.png"];
        thisisstart.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
        thisisstart.name = @"startbutton";
        [_bgLayer addChild:thisisstart];
This code must be inside a method body or a function, and by default in those contexts, the variable thisisstart will have local scope. That is, thisisstart will not exist outside the method or function.

You also add the node thisisstart as a child of _bgLayer, whose variable name suggests it's an instance variable. That seems fine, but keep it in mind for later.

Next you posted this code:
Code:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    /* Called when a touch begins */
    
 
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInNode:self];
    SKNode *node = [self nodeAtPoint:location];
    
    if ([node.name isEqualToString:@"startbutton"]) {
        [self NewGame];
        [thisisstart removeFromParent];
    }
    
 }
My question here is:
Where is the variable thisisstart declared?
It's not declared in the method itself, so it must be declared as either an instance variable or a static variable. You haven't posted any code for either of those contexts, so no one knows.

The problem with thisisstart as either an ivar or a static var is the earlier code showed it being declared as a local variable (doesn't exist outside method). So the implied declaration of thisisstart in this second code fragment contradicts the implications of the first code fragment.

Even supposing thisisstart is a valid variable name in this method, the code doesn't make a lot of sense. You make several method calls to find the node that contains the point being touched, and then you remove thisisstart. Shouldn't you be removing the node you just found, whose variable name is 'node'? We know its name is even "startbutton", because there's an 'if' condition qualifying its removal. If thisisstart holds the button's node, then why bother finding that node by location?

Earlier you set the node "startbutton" as a child node of _bgLayer (first code fragment). Assuming _bgLayer is an ivar, you could find the child node of _bgLayer whose name is "startbutton" and remove that node. This would only be necessary if you weren't already finding a node by location.

If thisisstart is NOT a valid variable name in this method, then how does the posted code even compile?

Something is wrong here. Either you've edited code before posting it, meaning the code you posted hasn't been compiled, or there's a variable named 'thisisstart' (maybe static, maybe ivar) that's being hidden (shadowed) by the local variable 'thisisstart' that appears in the first code fragment posted. If the local variable 'thisisstart' is hiding the other variable, then that other variable will be nil when touchesBegan is run. You'd need to change the first code fragment to eliminate the local variable's definition.

You don't really need an ivar or static var for thisisstart, because you can find it by location, or by searching _bgLayer for a node named "startbutton". I can't really tell because you haven't posted enough code, but you may have shot yourself in the foot by making too many variables, and then getting confused about what each one holds.


I'm also wondering if touchesBegan is even the right method to be removing the start button. To me, a more logical place is in touchesEnded, for the obvious reason of that's where the touches ended.
https://developer.apple.com/library...titouch_background/multitouch_background.html

I could be wrong about touchesEnded vs. touchesBegan, because you haven't really posted enough code to determine what's happening (or intended to happen).

The code in your first post has its own touchesBegan method, which looks nothing at all like the one from your later post. So I honestly have no idea what class the second touchesBegan is actually in, nor what its relationship to the overall program is.
 
Last edited:
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.