I'm really confused on why I am getting an EXC_BAD_ACCESS (code=1, address=0x1c) at [world addJoint:pinJoin];.
JointTest.m
#import "JointTest.h"
@implementation JointTest
-(SKNode *)initWithWorld:(SKPhysicsWorld *)pWorld{
if(self = [super init]){
world = pWorld;
[self attachBodies];
}
return self;
}
-(void)attachBodies{
SKSpriteNode * spriteA = [[SKSpriteNode alloc]initWithImageNamed:@"rocket"];
SKSpriteNode * spriteB = [[SKSpriteNode alloc]initWithImageNamed:@"rocket"];
SKPhysicsBody * bodyA = [SKPhysicsBody bodyWithRectangleOfSize:spriteA.size];
SKPhysicsBody * bodyB = [SKPhysicsBody bodyWithRectangleOfSize:spriteB.size];
spriteA.position = CGPointMake(150, 300);
spriteB.position = CGPointMake(150, 300 + spriteB.size.height/2);
[self addChild:spriteA];
[self addChild:spriteB];
bodyA.dynamic = NO;
spriteA.physicsBody = bodyA;
spriteB.physicsBody = bodyB;
SKPhysicsJointPin * pinJoin = [SKPhysicsJointPin jointWithBodyA:spriteA.physicsBody bodyB:spriteB.physicsBody anchor:spriteA.position];
[world addJoint:pinJoin];
}
@end
JointTest.h
#import <SpriteKit/SpriteKit.h>
@interface JointTest : SKNode{
SKPhysicsWorld * world;
}
-(SKNode *)initWithWorld:(SKPhysicsWorld *)pWorld;
@end
In the SKScene
JointTest * test = [[JointTest alloc]initWithWorld:self.physicsWorld];
[self addChild:test];
What confuses me is moving the code in the attachBodies method into the scene and calling the the addJoint method with the scene's physicsWorld works great. For instance:
SKSpriteNode * spriteA = [[SKSpriteNode alloc]initWithImageNamed:@"rocket"];
SKSpriteNode * spriteB = [[SKSpriteNode alloc]initWithImageNamed:@"rocket"];
SKPhysicsBody * bodyA = [SKPhysicsBody bodyWithRectangleOfSize:spriteA.size];
SKPhysicsBody * bodyB = [SKPhysicsBody bodyWithRectangleOfSize:spriteB.size];
spriteA.position = CGPointMake(150, 300);
spriteB.position = CGPointMake(150, 300 + spriteB.size.height/2);
[self addChild:spriteA];
[self addChild:spriteB];
bodyA.dynamic = NO;
spriteA.physicsBody = bodyA;
spriteB.physicsBody = bodyB;
SKPhysicsJointPin * pinJoin = [SKPhysicsJointPin jointWithBodyA:spriteA.physicsBody bodyB:spriteB.physicsBody anchor:spriteA.position];
[self.physicsWorld addJoint:pinJoin];
I've been pulling my hair out for a few hours over this so if anyone has an idea I would greatly appreciate it. Thanks!
Passing in the physics world on init is not good design. Instead create the instance of the class normally, then send the attachBodies
message to it from wherever you created the JointTest instance. Then you can access the physics world through self.scene.physicsWorld
rather than having to pass the world around and keeping an extraneous reference to it.
Instead of this:
JointTest * test = [[JointTest alloc]initWithWorld:self.physicsWorld];
[self addChild:test];
Do this:
JointTest * test = [JointTest node];
[self addChild:test];
[test attachBodies];
Note that attachBodies
is sent after addChild
because before addChild
the JointTest's scene
property will still be nil.
I bet this will also solve your problem, though this is a guess:
You create JointTest and immediately add two sprites with joints to it, but at this point the JointTest instance isn't added to the node graph yet (via addChild). Thus the JointTest and its two child nodes are simply not yet "registered" with the physics world to begin with, which may lead to the crash.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With