This is my first post and I'm trying to use the Apple SpriteKit .
I believe that I misunderstand how to move sprites using the framework. I have a simple example in which I would like to move hero in a simple UP , DOWN , LEFT , RIGHT direction, based on the location of the crane corresponding to the location of the "hero". As soon as the hero enters the block , the "hero" must stop.
For testing purposes, I'm just trying to click above the βheroβ by hitting the wall of blocks at the top of the screen. Then, after the collision, click below "hero." I expected the βheroβ to move to the wall of blocks in the bottom row; however, it seems that the βheroβ continues to move up and through the upper wall. I am sure that I am making a fundamental flaw, I would appreciate any help.
thanks
Here is the scene I wrote:
static inline CGPoint CGPointSubtract(const CGPoint a, const CGPoint b) { return CGPointMake(ax - bx, ay - by); } typedef enum DIRECTION_e { UP, DOWN, LEFT, RIGHT } DIRECTION_t; typedef NS_OPTIONS(uint32_t, CNPhysicsCategory) { PhysicsCategoryBlock = 1 << 0, PhysicsCategoryHero = 1 << 1 }; @interface LevelScene () @property (nonatomic) SKSpriteNode * hero; @property (nonatomic) BOOL inMotion; @end @implementation LevelScene -(id) initWithSize:(CGSize)size { if (self = [super initWithSize:size]) { self.physicsWorld.gravity = CGVectorMake(0,0); self.physicsWorld.contactDelegate = self; [self createLevel]; [self createHero]; self.inMotion = NO; } return self; } - (void) createHero { [self addHeroAtRow:5 column:2]; } - (void) createLevel { self.backgroundColor = [SKColor blackColor]; self.scaleMode = SKSceneScaleModeAspectFit; [self addBlockAtRow:1 column:1]; [self addBlockAtRow:1 column:2]; [self addBlockAtRow:1 column:3]; [self addBlockAtRow:10 column:1]; [self addBlockAtRow:10 column:2]; [self addBlockAtRow:10 column:3]; } - (void) addBlockAtRow:(NSInteger)row column:(NSInteger)column { SKSpriteNode *block = [[SKSpriteNode alloc] initWithColor:[SKColor brownColor] size:CGSizeMake(64,64)]; block.position = CGPointMake(32 + (column * 64), 32 + ((11-row) * 64)); block.name = @"block"; block.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:block.size]; block.physicsBody.dynamic = NO; block.physicsBody.categoryBitMask = PhysicsCategoryBlock; block.physicsBody.collisionBitMask = PhysicsCategoryBlock | PhysicsCategoryHero; block.physicsBody.contactTestBitMask = PhysicsCategoryBlock | PhysicsCategoryHero; [self addChild:block]; } - (void) addHeroAtRow:(NSInteger)row column:(NSInteger)column { self.hero = [[SKSpriteNode alloc] initWithColor:[SKColor redColor] size:CGSizeMake(64,64)]; self.hero.position = CGPointMake(32 + (column * 64), 32 + ((11-row) * 64)); self.hero.name = @"hero"; self.hero.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(self.hero.size.width/2, self.hero.size.height/2)]; self.hero.physicsBody.usesPreciseCollisionDetection = YES; self.hero.physicsBody.dynamic = YES; self.hero.physicsBody.categoryBitMask = PhysicsCategoryHero; self.hero.physicsBody.collisionBitMask = PhysicsCategoryHero | PhysicsCategoryBlock; self.hero.physicsBody.contactTestBitMask = PhysicsCategoryHero | PhysicsCategoryBlock; [self addChild:self.hero]; NSLog(@"ADDING HERO: %f, %f", self.hero.position.x, self.hero.position.y); } - (void)didBeginContact:(SKPhysicsContact *)contact { if (contact.bodyA.categoryBitMask == PhysicsCategoryBlock && contact.bodyB.categoryBitMask == PhysicsCategoryHero) { [self.hero removeAllActions]; self.hero.position = contact.bodyB.node.position; NSLog(@"COLLISION: %f, %f", self.hero.position.x, self.hero.position.y); self.inMotion = NO; } else if (contact.bodyB.categoryBitMask == PhysicsCategoryBlock && contact.bodyA.categoryBitMask == PhysicsCategoryHero) { [self.hero removeAllActions]; self.hero.position = contact.bodyA.node.position; NSLog(@"COLLISION: %f, %f", self.hero.position.x, self.hero.position.y); self.inMotion = NO; } } - (void) moveHeroTowardDirection:(DIRECTION_t)direction { CGPoint location; switch (direction) { case UP: { location = CGPointMake(self.hero.position.x, self.hero.position.y + 600); } break; case DOWN: { location = CGPointMake(self.hero.position.x, self.hero.position.y + -600); } break; case LEFT: { location = CGPointMake(self.hero.position.x + -600, self.hero.position.y); } break; case RIGHT: { location = CGPointMake(self.hero.position.x + 600, self.hero.position.y); } break; default: return; } NSLog(@"MOVE POSITION: %f, %f", location.x, location.y); SKAction *action = [SKAction moveTo:location duration:10]; [self.hero runAction:action]; } -(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { if (self.inMotion) return; self.inMotion = YES; UITouch *touch = [touches anyObject]; CGPoint touchLocation = [touch locationInView:self.view]; CGPoint diff = CGPointSubtract(self.hero.position, touchLocation); NSLog(@"TOUCH POSITION: %f, %f", touchLocation.x, touchLocation.y); NSLog(@"HERO POSITION: %f, %f", self.hero.position.x, self.hero.position.y); NSLog(@"DIFF POSITION: %f, %f", diff.x, diff.y);