Accessing an object's local variable from a method Objective-c - objective-c

I'm trying to access an object's local variable from didBeginContact method. How's it possible ?
Let's say I've got a ball object and whenever it bounces from the player, that ball's bouncedFrom variable get's an identifier from the player.
This is my initBall method, which initialises a ball. It is called every 3-5(random) seconds.
-(void)initBall {
NSString *bouncedFrom;
bouncedFrom = #"";
ball = [SKSpriteNode spriteNodeWithImageNamed:#"ball"];
ball.name = ballCategoryName;
ball.zPosition = 0;
int cannonPos = (arc4random() % 3 ) + 1;
SKSpriteNode *cannon = (SKSpriteNode *)[self childNodeWithName:[NSString stringWithFormat:#"%i",cannonPos]];
ball.zPosition = 3;
ball.position = cannon.position;
ball.physicsBody.categoryBitMask = ballCategory;
ball.physicsBody.contactTestBitMask = wallCategory;
ball.physicsBody.collisionBitMask = wallCategory;
ball.physicsBody.usesPreciseCollisionDetection = YES;
[self addChild:ball];
ball.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:ball.frame.size.width/2];
ball.physicsBody.friction = 0.0f;
//Bounce back
ball.physicsBody.restitution = 1.0f;
//
ball.physicsBody.linearDamping = 0.0f;
ball.physicsBody.allowsRotation = NO;
switch (cannonPos) {
case 1:
ball.position = CGPointMake(ball.position.x+20, ball.position.y+20);
[ball.physicsBody applyImpulse:CGVectorMake(-1.0,1.0)];
break;
case 2:
ball.position = CGPointMake(ball.position.x-20, ball.position.y+15);
[ball.physicsBody applyImpulse:CGVectorMake(-1.0,1.0)];
break;
case 3:
ball.position = CGPointMake(ball.position.x-20, ball.position.y-15);
[ball.physicsBody applyImpulse:CGVectorMake(-1.0,-1.0)];
break;
case 4:
ball.position = CGPointMake(ball.position.x+20, ball.position.y-20);
[ball.physicsBody applyImpulse:CGVectorMake(-1.0,-1.0)];
default:
break;
}
What I want is something like this in the didBeginContact:
-(void)didBeginContact:(SKPhysicsContact *)contact {
SKPhysicsBody *firstBody;
SKPhysicsBody *secondBody;
if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask) {
firstBody = contact.bodyA;
secondBody = contact.bodyB;
} else {
firstBody = contact.bodyB;
secondBody = contact.bodyA;
}
if ((firstBody.categoryBitMask & ballCategory) !=0) {
SKNode *ball = contact.bodyB.node;
SKNode *player = contact.bodyA.node;
ball.bouncedFrom = PlayerCategory;
}
if ((firstBody.categoryBitMask & wallCategory) !=0) {
SKNode *ball = contact.bodyB.node;
SKAction *addScore = [SKAction runBlock:^{
if (ball.position.y < 0) playerScore--;
if (ball.position.x < 0) cpu2Score--;
if (ball.position.y > self.frame.size.height) cpu1Score--;
if (ball.position.x > self.frame.size.width) cpu3Score--;
}];
SKAction *removeNode = [SKAction removeFromParent];
SKAction *sequence = [SKAction sequence:#[addScore, removeNode]];
[ball runAction:sequence];
}
}
Both ball and xCategories are declared as static variables at the top of my code.
Is something like this possible ?

My first thought is that you should declare bouncedFrom as a class variable in the .h rather than declaring it in your init: method.
so in the .h should look like
#interface Ball: NSObject{<br>
NSString *bouncedFrom;<br>
}
#end

Related

Objective C Sprite Kit Multiple Collisions

I am currently working on a sprite kit game, with Objective-C. So far, I have everything working in order, however I am trying to accomplish multiple collisions and can't seem to accomplish this.
This is my code:
- (void)didBeginContact:(SKPhysicsContact *)contact
{
NSLog(#"contact!");
SKNode * nodeA = contact.bodyA.node;
SKNode *nodeB =contact.bodyB.node;
NSLog(#"%#", nodeA.name);
if ([contact.bodyA.node.name isEqualToString:#"david"] == YES ||
[contact.bodyB.node.name isEqualToString:#"david"] == NO) {
[self runAction:self.soundAction];
SKNode * nodeB = contact.bodyB.node;
SKAction * remove = [SKAction removeFromParent];
[nodeB runAction:remove];
counter++;
updateLabel = true;
}
else if([contact.bodyA.node.name isEqualToString:#"rock"] == YES ||
[contact.bodyB.node.name isEqualToString:#"rock"] == YES) {
SKAction * remove = [SKAction removeFromParent];
[nodeB runAction:remove];
for (int i = 0; i < 100; i++) {
SKSpriteNode * rock = [[SKSpriteNode alloc] initWithColor:[SKColor orangeColor] size:CGSizeMake(10, 10)];
rock.position = CGPointMake(CGRectGetMidX(self.frame) + skRand(-40, 40), CGRectGetMidY(self.frame) + 100 + skRand(-40, 40));
rock.name = #"rock";
rock.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:rock.size];
rock.physicsBody.usesPreciseCollisionDetection = YES;
rock.physicsBody.contactTestBitMask = 0x1;
[self addChild:rock];
CGVector dir = CGVectorMake(skRand(-5, 5), skRand(1, 4));
[rock.physicsBody applyImpulse:dir];
}
}
}

Gravity not affecting a node when endless background is enabled in sprite kit

When I implement the following code, my main character is not affected by gravity.
SKSpriteNode *ball = [SKSpriteNode spriteNodeWithImageNamed:#"ball.png"];
ball.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:ball.size.height/2];
ball.physicsBody.dynamic = YES;
ball.physicsBody.linearDamping = NO;
ball.physicsBody.angularDamping = NO;
ball.physicsBody.friction = 0;
ball.physicsBody.usesPreciseCollisionDetection = YES;
ball.position = CGPointZero;
ball.zPosition = 1;
[myWorld addChild:ball];
Here's the background
for (int i = 0; i < 2; i++) {
SKSpriteNode * bg = [SKSpriteNode spriteNodeWithImageNamed:#"background"];
//bg.anchorPoint = CGPointZero;
bg.position = CGPointMake(i * bg.size.width, 0);
bg.name = #"background.png";
//bg.physicsBody = [SKPhysicsBody bodyWithEdgeFromPoint:CGPointMake(-bg.frame.size.width/2, -bg.frame.size.height/2 +20) toPoint:CGPointMake(bg.frame.size.width/2, -bg.frame.size.height/2 + 20)];
bg.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:bg.frame];
[self addChild:bg];
}
I tried the code here Stack discussion here and everything works as expected, except the gravity on the y axis.
Gravity in the scene:
if (self = [super initWithSize:size]) {
self.anchorPoint = CGPointMake(0.5, 0.5);
self.physicsWorld.gravity = CGVectorMake(0, -2);
[self startGravityIncrease];
........
- (void)startGravityIncrease {
SKAction *blockAction = [SKAction runBlock:^{
CGVector gravity = self.physicsWorld.gravity;
gravity.dx += 0.6;
gravity.dy -= 0.3;
self.physicsWorld.gravity = gravity;
}];
SKAction *waitAction = [SKAction waitForDuration:5];
SKAction *sequenceAction = [SKAction sequence:#[waitAction, blockAction]];
SKAction *repeatAction = [SKAction repeatActionForever:sequenceAction];
[self runAction:repeatAction];
}
What am I doing wrong here?

SKSpriteNode collision detection error

I am creating a game where a ball is suppose to bounce off from platforms. I have set up physics properties for the ball and the platform(platform only attains physics property when it's below the ball). My problem is: the ball is not bouncing (I have applied impulse in didbegincontact method) when the ball makes contact with the platform, it however detects contact.
Here is my didBeginContact Code:
- (void) didBeginContact:(SKPhysicsContact *)contact {
SKSpriteNode *firstNode, *secondNode;
firstNode = (SKSpriteNode*) contact.bodyA.node;
secondNode = (SKSpriteNode*) contact.bodyB.node;
if ((contact.bodyA.categoryBitMask == ballCategory) && (contact.bodyB.categoryBitMask == solidPlatformCategory)) {
NSLog(#"Platform Hit");
CGPoint contactPoint = contact.contactPoint;
[_ball.physicsBody applyImpulse:CGVectorMake(0, 4) atPoint:contactPoint];
}
}
///// Here is the code for SKSpriteNode Ball
- (void) addBall {
_myBall = [SKSpriteNode spriteNodeWithImageNamed:#"ball.png"];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
_myBall.scale = 0.4;
} else {
_myBall.scale = 0.3;
}
_ball.position = CGPointMake(self.frame.size.width/2, _solidPlatform.position.y + 2.5*_ball.size.height);
_ball.zPosition = 2;
_ball.name = #"doodle";
_ball.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:_myDoodle.frame.size];
_ball.physicsBody.mass = 1.0;
_ball.physicsBody.restitution = 0.8;
_ball.physicsBody.dynamic = YES;
_ball.physicsBody.allowsRotation = NO;
_ball.physicsBody.usesPreciseCollisionDetection = YES;
_ball.physicsBody.categoryBitMask = ballCategory;
_ball.physicsBody.collisionBitMask = solidPlatformCategory;
_ball.physicsBody.contactTestBitMask = solidPlatformCategory;
//SKAction *moveUpAction = [SKAction moveByX:0.0 y:8*numberOfPlatforms duration:0.5];
[self addChild:_ball];
}
////Platform has been defined as (not a complete code):
_solidPlatform7.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:_solidPlatform7.frame.size];
_solidPlatform7.physicsBody.dynamic = NO;
_solidPlatform7.physicsBody.affectedByGravity = NO;
_solidPlatform7.physicsBody.usesPreciseCollisionDetection = YES;
_solidPlatform7.physicsBody.categoryBitMask = solidPlatformCategory;
PS: I am not getting any collusion detection if I define platform as bodyWithEdgeFromRect
difficult to answer without seeing some code, but I'll try:
If the ball does not bounce at all, check the restitution property. Higher values provide a higher "bounciness":
ball.physicsBody.restitution=0.8;
If you want the ball to bounce endless between bottom and ceiling you can invert the gravity after each collision:
self.physicsWorld.gravity = CGVectorMake(0, self.physicsWorld.gravity.dy * (-1));
Hope that helps. If not, please share some code.
I've tried your code. With some smaller changes it works:
- (void) addBall {
// Bottom platforms
for (int i=0; i<10; i++) {
SKSpriteNode *mySprite = [SKSpriteNode spriteNodeWithColor:[UIColor redColor] size:CGSizeMake(40, 20)];
CGPoint location = CGPointMake(i*40+60, 10);
//mySprite.size =CGSizeMake(20, 40);
mySprite.position=location;
mySprite.physicsBody=[SKPhysicsBody bodyWithRectangleOfSize:mySprite.size];
mySprite.physicsBody.dynamic=false;
mySprite.physicsBody.categoryBitMask=solidPlatformCategory;
[self addChild:mySprite];
}
_ball = [SKSpriteNode spriteNodeWithImageNamed:#"ball.png"];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
_ball.scale = 0.4;
} else {
_ball.scale = 0.3;
}
_ball.position = CGPointMake(self.frame.size.width/2, self.frame.size.width/2);
_ball.zPosition = 2;
_ball.name = #"doodle";
//_ball.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:_myDoodle.frame.size];
_ball.physicsBody=[SKPhysicsBody bodyWithCircleOfRadius:_ball.size.width/2];
_ball.physicsBody.mass = 1.0;
_ball.physicsBody.restitution = 1;
_ball.physicsBody.dynamic = YES;
_ball.physicsBody.allowsRotation = NO;
_ball.physicsBody.usesPreciseCollisionDetection = YES;
_ball.physicsBody.categoryBitMask = ballCategory;
_ball.physicsBody.collisionBitMask = solidPlatformCategory;
_ball.physicsBody.contactTestBitMask = solidPlatformCategory;
//SKAction *moveUpAction = [SKAction moveByX:0.0 y:8*numberOfPlatforms duration:0.5];
[self addChild:_ball];
}

How can I have a definite number of enemies(ex.10 only) randomly spawned outside of screen then going inside?

This is the orbivoid tutorial GameScene.m. So my problem is that, enemies spawning is just located somewhere in the lower left due to the CGPointMake. I want to make them already spawned outside of the screen at the start of the game with a definite number, randomly located(ex. 10 enemies already spawned outside of the screen at different locations). Can somebody please help me (some code, tips or something to implement for this)? I did not change anything in the GameScene.m so for the convenience of those who wants to help me. Thanks!
#implementation GameScene
{
BOOL _dead;
SKNode *_player;
NSMutableArray *_enemies;
SKLabelNode *_scoreLabel;
}
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
/* Setup your scene here */
self.backgroundColor = [SKColor colorWithRed:0.15 green:0.15 blue:0.3 alpha:1.0];
self.physicsWorld.gravity = CGVectorMake(0.0f, 0.0f);
self.physicsWorld.contactDelegate = self;
_enemies = [NSMutableArray new];
_player = [SKNode node];
SKShapeNode *circle = [SKShapeNode node];
circle.path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-10, -10, 20, 20)].CGPath;`
circle.fillColor = [UIColor blueColor];
circle.glowWidth = 5;
SKEmitterNode *trail = [SKEmitterNode orb_emitterNamed:#"Trail"];
trail.targetNode = self;
trail.position = CGPointMake(CGRectGetMidX(circle.frame), CGRectGetMidY(circle.frame));
_player.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:10];
_player.physicsBody.mass = 100000;
_player.physicsBody.categoryBitMask = CollisionPlayer;
_player.physicsBody.contactTestBitMask = CollisionEnemy;
[_player addChild:trail];
_player.position = CGPointMake(size.width/2, size.height/2);
[self addChild:_player];
}
return self;
}
- (void)didMoveToView:(SKView *)view
{
[self performSelector:#selector(spawnEnemy) withObject:nil afterDelay:1.0];
}
-(void)spawnEnemy
{
[self runAction:[SKAction playSoundFileNamed:#"Spawn.wav" waitForCompletion:NO]];
SKNode *enemy = [SKNode node];
SKEmitterNode *trail = [SKEmitterNode orb_emitterNamed:#"Trail"];
trail.targetNode = self;
trail.particleScale /= 2;
trail.position = CGPointMake(10, 10);
trail.particleColorSequence = [[SKKeyframeSequence alloc] initWithKeyframeValues:#[
[SKColor redColor],
[SKColor colorWithHue:0.1 saturation:.5 brightness:1 alpha:1],
[SKColor redColor],
] times:#[#0, #0.02, #0.2]];
[enemy addChild:trail];
enemy.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:6];
enemy.physicsBody.categoryBitMask = CollisionEnemy;
enemy.physicsBody.allowsRotation = NO;
enemy.position = CGPointMake(50, 50);
[_enemies addObject:enemy];
[self addChild:enemy];
if(!_scoreLabel) {
_scoreLabel = [SKLabelNode labelNodeWithFontNamed:#"Courier-Bold"];
_scoreLabel.fontSize = 200;
_scoreLabel.position = CGPointMake(CGRectGetMidX(self.frame),
CGRectGetMidY(self.frame));
_scoreLabel.fontColor = [SKColor colorWithHue:0 saturation:0 brightness:1 alpha:0.5];
[self addChild:_scoreLabel];
}
_scoreLabel.text = [NSString stringWithFormat:#"%02d", _enemies.count];
// Next spawn
[self runAction:[SKAction sequence:#[
[SKAction waitForDuration:5],
[SKAction performSelector:#selector(spawnEnemy) onTarget:self],
]]];
}
-(void)dieFrom: (SKNode*)killingEnemy
{
_dead = YES;
SKEmitterNode *explosion = [SKEmitterNode orb_emitterNamed:#"Explosion"];
explosion.position = _player.position;
[self addChild:explosion];
[explosion runAction:[SKAction sequence:#[
[SKAction playSoundFileNamed:#"Explosion.wav" waitForCompletion:NO],
[SKAction waitForDuration:0.4],
[SKAction runBlock:^{
// TODO: Revove these more nicely
[killingEnemy removeFromParent];
[_player removeFromParent];
}],
[SKAction waitForDuration:0.4],
[SKAction runBlock:^{
explosion.particleBirthRate = 0;
}],
[SKAction waitForDuration: 1.2],
[SKAction runBlock:^{
ORBMenuScene *menu = [[ORBMenuScene alloc] initWithSize:self.size];
[self.view presentScene:menu transition:[SKTransition doorsCloseHorizontalWithDuration:0.4]];
}],
]]];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self touchesMoved:touches withEvent:event];
}
-(void)touchesMoved: (NSSet *) touches withEvent:(UIEvent *)event
{
[_player runAction:[SKAction moveTo:[[touches anyObject] locationInNode:self] duration:.01]];
}
-(void)update:(CFTimeInterval)currentTime
{
CGPoint playerPos = _player.position;
for(SKNode *enemyNode in _enemies)
{
CGPoint enemyPos = enemyNode.position;
/* Uniform speed: */
CGVector diff = TCVectorMinus(playerPos, enemyPos);
CGVector normalized = TCVectorUnit(diff);
CGVector force = TCVectorMultiply(normalized, 4);
[enemyNode.physicsBody applyForce:force];
}
_player.physicsBody.velocity = CGVectorMake (0, 0);
}
-(void)didBeginContact:(SKPhysicsContact *)contact
{
if(_dead)
return;
[self dieFrom:contact.bodyB.node];
contact.bodyB.node.physicsBody = nil;
}
#end
This is only an educated guess, since I can’t test my code.
I think in your didMoveToView method you can do this
for (int i = 0; i < 10; i++)
[self performSelector:#selector(spawnEnemy) withObject:nil afterDelay:1.0];
to spawn 10 enemies at once.
In your spawnEnemy method you set the position of the enemies similar to this:
CGFloat x = arc4random() % 100 + size.width/2;
CGFLoat y = arc4random() % (int)size.height;
if (arc4random() % 2 == 0)
x = size.width/2 + x;
else
x = size.width/2 - x;
enemy.position = CGPointMake(x, y);
This should spawn the enemies beyond the left and right side of the screen, but within 100 points of the edge of the screen.
Of course you need to tweak this to your needs.

So the collision effect(explosion) doesn't work anymore after changing the player and enemy from SKShapeNode to a .png file [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I changed the custom circular shapes (SKShapeNode *circle) of the player and enemy to a .png file. Before changing the player and enemy to a .png file, there was this explosion effect after collision. However, after changing to .png file, the explosion effect does not happen anymore. Yes, the images bump each other which basically shows that there's collision. But the explosion effect after colliding with each other does not show anymore. How can I implement it again, I need some help please. Thank you very much!
#import "GameScene.h"
#import "CGVector+TC.h"
#import "ORBMenuScene.h"
enum {
CollisionPlayer = 1<<1,
CollisionEnemy = 1<<2,
};
#interface GameScene () <SKPhysicsContactDelegate>
#end
#implementation GameScene
{
BOOL _dead;
SKNode *_player;
NSMutableArray *_enemies;
SKLabelNode *_scoreLabel;
}
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
/* Setup your scene here */
self.backgroundColor = [SKColor colorWithRed:0.15 green:0.15 blue:0.3 alpha:1.0];
self.physicsWorld.gravity = CGVectorMake(0.0f, 0.0f);
self.physicsWorld.contactDelegate = self;
_enemies = [NSMutableArray new];
_player = [SKNode node];
_player = [SKSpriteNode spriteNodeWithImageNamed:#"Player.png"];
_player.position = CGPointMake(size.width/2, size.height/2);
_player.physicsBody.dynamic = YES;
_player.physicsBody.mass = 0.2;
_player.physicsBody.categoryBitMask = CollisionPlayer;
_player.physicsBody.contactTestBitMask = CollisionEnemy;
_player.physicsBody.collisionBitMask = CollisionEnemy;
_player.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:10];
_player.position = CGPointMake(size.width/2, size.height/2);
_player.physicsBody.allowsRotation = YES;
_player.physicsBody.usesPreciseCollisionDetection = YES;
_player.name = #"Player";
[_player setScale:1];
[self addChild:_player];
}
return self;
}
- (void)didMoveToView:(SKView *)view
{
[self performSelector:#selector(spawnEnemy) withObject:nil afterDelay:1.0];
}
-(void)spawnEnemy
{
[self runAction:[SKAction playSoundFileNamed:#"Spawn.wav" waitForCompletion:NO]];
SKNode *enemy = [SKNode node];
enemy = [SKSpriteNode spriteNodeWithImageNamed:#"Enemy.png"];
enemy.physicsBody.categoryBitMask = CollisionEnemy;
enemy.physicsBody.contactTestBitMask = CollisionPlayer;
enemy.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:6];
enemy.physicsBody.collisionBitMask = CollisionPlayer;
enemy.physicsBody.allowsRotation = YES;
enemy.physicsBody.dynamic = YES;
enemy.name = #"Enemy";
[enemy setScale:0.5];
CGFloat x = arc4random() % 70 + self.size.width/2;
CGFloat y = arc4random() % (int) self.size.height;
if (arc4random() % 2 == 0)
x = self.size.width/2 + x;
else
x = self.size.width/2 - x;
enemy.position = CGPointMake(x, y);
[_enemies addObject:enemy];
[self addChild:enemy];
if(!_scoreLabel) {
_scoreLabel = [SKLabelNode labelNodeWithFontNamed:#"Courier-Bold"];
_scoreLabel.fontSize = 200;
_scoreLabel.position = CGPointMake(CGRectGetMidX(self.frame),
CGRectGetMidY(self.frame));
_scoreLabel.fontColor = [SKColor colorWithHue:0 saturation:0 brightness:1 alpha:0.5];
[self addChild:_scoreLabel];
}
_scoreLabel.text = [NSString stringWithFormat:#"%02d", _enemies.count];
if (_enemies.count == 18) {
[self runAction:[SKAction sequence:#[
[SKAction waitForDuration:99999],
[SKAction performSelector:#selector(spawnEnemy) onTarget:self],
]]];
}
else {
[self runAction:[SKAction sequence:#[
[SKAction waitForDuration:1],
[SKAction performSelector:#selector(spawnEnemy) onTarget:self],
]]];
}
}
-(void)dieFrom: (SKNode*)killingEnemy
{
_dead = YES;
SKEmitterNode *explosion = [SKEmitterNode orb_emitterNamed:#"Explosion"];
explosion.position = _player.position;
[self addChild:explosion];
[explosion runAction:[SKAction sequence:#[
[SKAction playSoundFileNamed:#"Explosion.wav" waitForCompletion:NO],
[SKAction waitForDuration:0.4],
[SKAction runBlock:^{
// TODO: Revove these more nicely
[killingEnemy removeFromParent];
[_player removeFromParent];
}],
[SKAction waitForDuration:0.4],
[SKAction runBlock:^{
explosion.particleBirthRate = 0;
}],
[SKAction waitForDuration: 1.2],
[SKAction runBlock:^{
ORBMenuScene *menu = [[ORBMenuScene alloc] initWithSize:self.size];
[self.view presentScene:menu transition:[SKTransition doorsCloseHorizontalWithDuration:0.4]];
}],
]]];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self touchesMoved:touches withEvent:event];
}
-(void)touchesMoved: (NSSet *) touches withEvent:(UIEvent *)event
{
[_player runAction:[SKAction moveTo:[[touches anyObject] locationInNode:self] duration:.01]];
}
-(void)update:(CFTimeInterval)currentTime
{
CGPoint playerPos = _player.position;
for(SKNode *enemyNode in _enemies)
{
CGPoint enemyPos = enemyNode.position;
/* Uniform speed: */
CGVector diff = TCVectorMinus(playerPos, enemyPos);
CGVector normalized = TCVectorUnit(diff);
CGVector force = TCVectorMultiply(normalized, 4);
[enemyNode.physicsBody applyForce:force];
}
_player.physicsBody.velocity = CGVectorMake (0, 0);
}
-(void)didBeginContact:(SKPhysicsContact *)contact
{
if(_dead)
return;
[self dieFrom:contact.bodyB.node];
contact.bodyB.node.physicsBody = nil;
}
#end
It seems to me you did not initialize physicsBody before setting its properties.
After creating a player or enemy you should first initialize a body to use. Otherwise it will be nil indicating that the node does not participate in the physics simulation at all. And all property setting will be useless.
This should do for you, dont forget to move that line for the enemy as well!
_player = [SKSpriteNode spriteNodeWithImageNamed:#"Player.png"];
_player.position = CGPointMake(size.width/2, size.height/2);
_player.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:10];
_player.physicsBody.dynamic = YES;
_player.physicsBody.mass = 0.2;