Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialJared Watkins
10,756 PointsMy ground node is not appearing.
There is nothing there, and I'm can't find what I'm missing. Can someone tell me what I've missed?
from groundNode.m:
#import "GroundNode.h"
#import "Util.h"
@implementation GroundNode
+ (instancetype) groundWithSize:(CGSize)size {
GroundNode *ground = [self spriteNodeWithColor:[SKColor greenColor] size:size];
ground.name = @"ground";
ground.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:size];
ground.position = CGPointMake(size.width/2, size.height/2);
return ground;
}
From GamePlayScene.m:
GroundNode *ground = [GroundNode groundWithSize:CGSizeMake(self.frame.size.width, 22)];
[self addChild:ground];
15 Answers
Brittany Stubbs
22,979 Pointstry adding this into your GroundNode.M implementation class: try messing around with the value changing from 1, to 15 etc.. it seems to be hiding the green box behind the background by default.
hope this helps.
ground.zPosition = 1;
Jared Watkins
10,756 PointsThis worked. Thanks Brittany!
lovekesh bhagat
1,572 PointsShort and easy thanks
Stone Preston
42,016 Pointsare you sure its not just dropping off the screen because of gravity? what do you have gravity set to in your physics world?
try commenting out the line that sets the gravity force and see if the ground node stays put. that way you can see if its actually being added to the scene correctly
Jared Watkins
10,756 PointsI'm not sure. Here is what I have for physicsWorld:
self.physicsWorld.gravity = CGVectorMake(0, -9.8);
self.physicsWorld.contactDelegate = self;
Stone Preston
42,016 Pointscomment out the gravity line and try running the app, does the ground node appear?
// self.physicsWorld.gravity = CGVectorMake(0, -9.8);
self.physicsWorld.contactDelegate = self;
Jared Watkins
10,756 PointsThanks Stone. although, no change.
Stone Preston
42,016 Pointscan you post the full code you have in your gamePlayScene
Jared Watkins
10,756 PointsDefinitely
//
// GamePlayScene.m
// Space Cat
//
// Created by Jared Watkins on 12/16/14.
// Copyright (c) 2014 Jared Watkins. All rights reserved.
//
#import "GamePlayScene.h"
#import "MachineNode.h"
#import "SpaceCatNode.h"
#import "ProjectileNode.h"
#import "SpaceDogNode.h"
#import "GroundNode.h"
#import "Util.h"
@interface GamePlayScene ()
@property (nonatomic) NSTimeInterval lastUpdateTimeInterval;
@property (nonatomic) NSTimeInterval timeSinceEnemyAdded;
@property (nonatomic) NSTimeInterval totalGameTime;
@property (nonatomic) NSInteger minSpeed;
@property (nonatomic) NSTimeInterval addEnemyTimeInterval;
// SFX
@property (nonatomic) SKAction *damageSFX;
@property (nonatomic) SKAction *explodeSFX;
@property (nonatomic) SKAction *laserSFX;
@end
@implementation GamePlayScene
-(void)didMoveToView:(SKView *)view {
self.lastUpdateTimeInterval = 0;
self.timeSinceEnemyAdded = 0;
self.addEnemyTimeInterval = 1.5;
self.totalGameTime = 0;
self.minSpeed = SpaceDogMinSpeed;
/* Setup your scene here */
SKSpriteNode *background = [SKSpriteNode spriteNodeWithImageNamed:@"background_1"];
background.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
background.xScale = 1.18;
background.yScale = 1.18;
[self addChild:background];
MachineNode *machine = [MachineNode machineAtPosition:CGPointMake(CGRectGetMidX(self.frame), 12) ];
[self addChild:machine];
SpaceCatNode *spaceCat = [SpaceCatNode spaceCatAtPosition:CGPointMake(machine.position.x, machine.position.y-2)];
[self addChild:spaceCat];
// Add Physics to the scene (World)
self.physicsWorld.gravity = CGVectorMake(0, -9.8);
self.physicsWorld.contactDelegate = self;
GroundNode *ground = [GroundNode groundWithSize:CGSizeMake(self.frame.size.width, 22)];
[self addChild:ground];
[self setupSounds];
}
// SFX
- (void) setupSounds {
self.damageSFX = [SKAction playSoundFileNamed:@"Damage.caf" waitForCompletion:NO];
self.explodeSFX = [SKAction playSoundFileNamed:@"Explode.caf" waitForCompletion:NO];
self.laserSFX = [SKAction playSoundFileNamed:@"Laser.caf" waitForCompletion:NO];
}
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
CGPoint position = [touch locationInNode:self];
[self shootProjectileTowardsPosition:position];
}
}
- (void) shootProjectileTowardsPosition:(CGPoint)position {
SpaceCatNode *spaceCat = (SpaceCatNode*)[self childNodeWithName:@"SpaceCat"];
[spaceCat performTap];
MachineNode *machine = (MachineNode *)[self childNodeWithName:@"machine"];
ProjectileNode *projectile = [ProjectileNode projectileAtPosition:CGPointMake(machine.position.x, machine.position.y + machine.frame.size.height - 15)];
[self addChild:projectile];
[projectile moveTowardsPosition:position];
// SFX - Laser
[self runAction:self.laserSFX];
}
// place enemies
- (void) addSpaceDog {
NSUInteger randomSpaceDog = [Util randomWithMin:0 max:2];
// randomly place spaceDogs
SpaceDogNode *spaceDog = [SpaceDogNode spaceDogOfType:randomSpaceDog];
// vary the velocity between -100 and -50 as found in Util.h
float dy = [Util randomWithMin:SpaceDogMinSpeed max:spaceDogMaxSpeed];
spaceDog.physicsBody.velocity = CGVectorMake(0, dy);
// keep the spaceDogs within the bounds of the frame
float y = self.frame.size.height + spaceDog.size.height; // right above the height of the frame
float x = [Util randomWithMin:10 + spaceDog.size.width max:self.frame.size.width - spaceDog.size.width - 10]; // between the left edge and right edge of the screen. left side (min) has 10 point margin.
spaceDog.position = CGPointMake(x, y);
[self addChild:spaceDog];
// Hared Coded add 2 spaceDogs
// SpaceDogNode *spaceDogA = [SpaceDogNode spaceDogOfType:SpaceDodTypeA];
// spaceDogA.position = CGPointMake(100, 300);
// [self addChild:spaceDogA];
//
// SpaceDogNode *spaceDogB = [SpaceDogNode spaceDogOfType:SpaceDogTypeB];
// spaceDogB.position = CGPointMake(200, 300);
// [self addChild:spaceDogB];
}
// add spaceDogs depending on how many seconds have passed since the last spaceDog was added
- (void) update:(NSTimeInterval)currentTime {
if ( self.lastUpdateTimeInterval) {
self.timeSinceEnemyAdded += currentTime - self.lastUpdateTimeInterval;
self.totalGameTime += currentTime - self.lastUpdateTimeInterval;
}
// add a space dog if one hasn't been added in the last addEnemyTimeInterval in seconds
if (self.timeSinceEnemyAdded > self.addEnemyTimeInterval ) {
[self addSpaceDog];
self.timeSinceEnemyAdded = 0;
}
// set the last update to the current time
self.lastUpdateTimeInterval = currentTime;
// Increase the difficulty over time
// if 480 second or 8 minutes have passed
if (self.totalGameTime > 480) {
self.addEnemyTimeInterval = 0.50;
self.minSpeed = -160;
// 4 minutes
} else if ( self.totalGameTime > 240 ) {
self.addEnemyTimeInterval = 0.65;
self.minSpeed = -150;
// 2 minutes
} else if ( self.totalGameTime > 20 ) {
self.addEnemyTimeInterval = .75;
self.minSpeed = -125;
// 30 seconds
} else if ( self.totalGameTime > 10 ) {
self.addEnemyTimeInterval = 1.00;
self.minSpeed = -100;
}
}
- (void) didBeginContact:(SKPhysicsContact *)contact {
SKPhysicsBody *firstBody, *secondBody;
// check which categoryBitMask is bigger by comparing enemy = 0010 to projectile 0000
if ( contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask ) {
firstBody = contact.bodyA;
secondBody = contact.bodyB;
} else {
firstBody = contact.bodyA;
secondBody = contact.bodyB;
}
if ( firstBody.categoryBitMask == collisionCategoryEnemy && secondBody.categoryBitMask == collisionCategoryProjectile ) {
NSLog(@"BAM!");
SpaceDogNode *spaceDog = (SpaceDogNode *)firstBody.node;
ProjectileNode *projectile = (ProjectileNode *)secondBody.node;
// SFX - Explode
[self runAction:self.explodeSFX];
// if the projectile and spaceDog collide, remove them from the scene
[spaceDog removeFromParent];
[projectile removeFromParent];
} else if (firstBody.categoryBitMask == collisionCategoryEnemy && secondBody.categoryBitMask == collisionCategoryGround ) {
NSLog(@"Hit Ground");
// SFX - Damage
[self runAction:self.damageSFX];
// remove spaceDog if it hits the ground
SpaceDogNode *spaceDog = (SpaceDogNode *)firstBody.node;
[spaceDog removeFromParent];
}
[self createDebrisAtPosition:contact.contactPoint];
}
// debris
- (void) createDebrisAtPosition:(CGPoint)position {
NSInteger numberOfPieces = [Util randomWithMin:5 max:20];
for (int i=0; i < numberOfPieces; i++) {
NSInteger randomPiece = [Util randomWithMin:1 max:4];
NSString *imageName = [NSString stringWithFormat:@"debri_%d",randomPiece];
SKSpriteNode *debris = [SKSpriteNode spriteNodeWithImageNamed:imageName];
debris.position = position;
[self addChild:debris];
debris.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:debris.frame.size];
debris.physicsBody.categoryBitMask = collisionCategoryDebris;
debris.physicsBody.contactTestBitMask = 0;
debris.physicsBody.collisionBitMask = collisionCategoryGround | collisionCategoryDebris;
debris.name = @"debris";
// scatter debris on explosion contact
debris.physicsBody.velocity = CGVectorMake([Util randomWithMin:-150 max:150],
[Util randomWithMin:150 max:350]);
[debris runAction:[SKAction waitForDuration:2.0] completion:^{
[debris removeFromParent];
}];
}
}
//-(void) update:(NSTimeInterval)currentTime {
//
// NSLog(@"%f",fmod(currentTime, 60));
//}
@end
And here is the full groundNode.m. I commented out the bodyWithRectangleOfSize line and have setupPhysicsBody, but even when I comment out setupPhysicsBody, and uncomment bodyWithRectangleOfSize, The ground still does not appear.
//
// GroundNode.m
// Space Cat
//
// Created by Jared Watkins on 12/17/14.
// Copyright (c) 2014 Jared Watkins. All rights reserved.
//
#import "GroundNode.h"
#import "Util.h"
@implementation GroundNode
+ (instancetype) groundWithSize:(CGSize)size {
GroundNode *ground = [self spriteNodeWithColor:[SKColor greenColor] size:size];
ground.name = @"ground";
// ground.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:size];
ground.position = CGPointMake(size.width/2, size.height/2);
[ground setupPhysicsBody];
return ground;
}
- (void) setupPhysicsBody {
self.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.frame.size];
self.physicsBody.affectedByGravity = NO;
self.physicsBody.dynamic = NO;
// collisions
self.physicsBody.categoryBitMask = collisionCategoryGround;
self.physicsBody.collisionBitMask = collisionCategoryDebris;
self.physicsBody.contactTestBitMask = collisionCategoryEnemy;
}
@end
Stone Preston
42,016 Pointswell that looks correct. not too sure why its not working. in your ground class try setting the position to something static:
ground.position = CGPointMake(200, 200);
maybe its an issue with the size being passed in or something
Jared Watkins
10,756 Pointsok, I see that the ground is mid screen because of the exploding debris, but it still doesn't appear.
Here's a screen shot: Imgur
The bigger problem is that the spaceDogs pass through the ground. it's like there are 5 space dogs stacked and only the top one is destroyed. the same thing happens with the projectiles when they contact the spaceDogs. Also the NSLog(@"Hit Ground"); does not get triggered or show up in the console. and the SFX for enemy hitting the ground is not triggered.
I won't be able to count lives for when the spaceDogs hit the ground.
An ideas?
Stone Preston
42,016 Pointsdid you uncomment the line that you commented out earlier
+ (instancetype) groundWithSize:(CGSize)size {
GroundNode *ground = [self spriteNodeWithColor:[SKColor greenColor] size:size];
ground.name = @"ground";
// ground.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:size];
ground.position = CGPointMake(size.width/2, size.height/2);
[ground setupPhysicsBody];
return ground;
}
Jared Watkins
10,756 PointsI have it like this:
+ (instancetype) groundWithSize:(CGSize)size {
GroundNode *ground = [self spriteNodeWithColor:[SKColor greenColor] size:size];
ground.name = @"ground";
// ground.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:size];
ground.position = CGPointMake(size.width/2, size.height/2);
[ground setupPhysicsBody];
return ground;
}
Stone Preston
42,016 Pointsun comment that line:
+ (instancetype) groundWithSize:(CGSize)size {
GroundNode *ground = [self spriteNodeWithColor:[SKColor greenColor] size:size];
ground.name = @"ground";
ground.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:size];
ground.position = CGPointMake(size.width/2, size.height/2);
[ground setupPhysicsBody];
return ground;
}
Jared Watkins
10,756 Pointsok, It's not appearing, and I can't tell an change.
Screenshot Imgur
//
// GroundNode.m
// Space Cat
//
// Created by Jared Watkins on 12/17/14.
// Copyright (c) 2014 Jared Watkins. All rights reserved.
//
#import "GroundNode.h"
#import "Util.h"
@implementation GroundNode
+ (instancetype) groundWithSize:(CGSize)size {
GroundNode *ground = [self spriteNodeWithColor:[SKColor greenColor] size:size];
ground.name = @"ground";
ground.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:size];
ground.position = CGPointMake(size.width/2, size.height/2);
[ground setupPhysicsBody];
return ground;
}
- (void) setupPhysicsBody {
self.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.frame.size];
self.physicsBody.affectedByGravity = NO;
self.physicsBody.dynamic = NO;
// collisions
self.physicsBody.categoryBitMask = collisionCategoryGround;
self.physicsBody.collisionBitMask = collisionCategoryDebris;
self.physicsBody.contactTestBitMask = collisionCategoryEnemy;
}
@end
Stone Preston
42,016 Pointshmm I really dont understand why its not green. it should be green. its not making much sense
Jared Watkins
10,756 PointsWell, I'm glad it's not just me. Thanks for your help, nonetheless.
Stone Preston
42,016 Pointscan you post your groundNode header file real quick
Jared Watkins
10,756 Pointssure
groundNode.h
//
// GroundNode.h
// Space Cat
//
// Created by Jared Watkins on 12/17/14.
// Copyright (c) 2014 Jared Watkins. All rights reserved.
//
#import <SpriteKit/SpriteKit.h>
@interface GroundNode : SKSpriteNode
+ (instancetype) groundWithSize:(CGSize)size;
@end
Stone Preston
42,016 Pointsalright that looks fine. was thinking maybe you inherited from the wrong class but thats fine
Jared Watkins
10,756 PointsI think there is a problem in GamePlayScene.m because The NSLog(@"Hit Ground"); is not being logged in the console. However, NSLog(@"BAM!"); is being logged.
- (void) didBeginContact:(SKPhysicsContact *)contact {
SKPhysicsBody *firstBody, *secondBody;
// check which categoryBitMask is bigger by comparing enemy = 0010 to projectile 0000
if ( contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask ) {
firstBody = contact.bodyA;
secondBody = contact.bodyB;
} else {
firstBody = contact.bodyA;
secondBody = contact.bodyB;
}
if ( firstBody.categoryBitMask == collisionCategoryEnemy && secondBody.categoryBitMask == collisionCategoryProjectile ) {
NSLog(@"BAM!");
SpaceDogNode *spaceDog = (SpaceDogNode *)firstBody.node;
ProjectileNode *projectile = (ProjectileNode *)secondBody.node;
// SFX - Explode
[self runAction:self.explodeSFX];
// if the projectile and spaceDog collide, remove them from the scene
[spaceDog removeFromParent];
[projectile removeFromParent];
} else if (firstBody.categoryBitMask == collisionCategoryEnemy && secondBody.categoryBitMask == collisionCategoryGround ) {
NSLog(@"Hit Ground");
// SFX - Damage
[self runAction:self.damageSFX];
// remove spaceDog if it hits the ground
SpaceDogNode *spaceDog = (SpaceDogNode *)firstBody.node;
[spaceDog removeFromParent];
}
[self createDebrisAtPosition:contact.contactPoint];
}
Johan Ospina
3,417 PointsI haven't gotten to the collision stuff in this app yet but I had the same ground not appearing thing and the only way i made it appear was that I set the zPosition property to 1.0. I'm not sure how this would impact the collision detection (you probably have to make all the dogNodes on zPosition 1.0 as well
Fahad Alrahbi
1,080 Pointsi have same problem !! any one can help us ?
Fahad Alrahbi
1,080 PointsThe problem because of BackGround try to comment
SKSpriteNode * background =[SKSpriteNode spriteNodeWithImageNamed:@"background_1"];
background.position=CGPointMake(self.size.width/2, self.size.height/2);
[self addChild:background];
and look what happen
David Rynn
10,554 PointsI had the same issue and tweaked the zPosition for both background and ground, as Brittany Stubbs suggested though I had to use the opposite settings...
on THGamePlayScene.m I set background.zPosition = 1;
and then I set ground.zPosition = 15;
Good luck!
Fahad Alrahbi
1,080 PointsFahad Alrahbi
1,080 Pointsif you solve your issue pls let us know how ? and what was the problem ?