Why would the sprite kit physic be different on iOS 7.x vs iOS 8.x???
I have a simple spritekit scene... I have 2 static pins and in between I have sprites which are connected by a spring joint, dropping an object on this elastic rope would behave like a trampoline, everything was looking ok on iOS 7.x until I started testing on iOS 8.x. I've tested on similar devices, 2 iphones 5s and 2 ipod touch 5th gen with each 7 & 8, I'm getting the same fps, having the same number of nodes.
I have tried all kind of joint, factors, gravity, speed and every time I run this simple piece of code on different devices on 7.x I get a similar behavior, but if I run it on 8.x devices the 'elasticity' is different of the spring joint is different, stiffer on 7.x, the elastic will bend more on 8.x without anything on it but if you add several balls on it you can even see a greater effect on the 8.x devices. before I'm asked, here the skcene code
#define kFrequency 30.0f
#define kDamping 0.0f
#define kNodes 20
typedef NS_OPTIONS(uint32_t, CategoryMask)
{
CategoryMaskBall = 1 << 0,
CategoryMaskPin = 1 << 1,
CategoryMaskElastic = 1 << 2,
CategoryMaskBorder = 1 << 3
};
@implementation SimpleGameScene
-(void)didMoveToView:(SKView *)view {
self.backgroundColor = [SKColor blackColor];
self.physicsWorld.gravity = CGVectorMake(0.0, -4.9);
NSMutableArray *nodes=[NSMutableArray arrayWithCapacity:kNodes+2];
SKSpriteNode *pin = [self addPin:CGPointMake(self.size.width/2, self.size.height/4)];
[self addChild:pin];
[nodes addObject:pin];
for( int i = 1; i<=kNodes; i++) {
SKSpriteNode *elastic = [self addElastic:CGPointMake(self.size.width/2+i*(pin.size.width+1), self.size.height/4)];
[self addChild:elastic];
[nodes addObject:elastic];
}
SKSpriteNode *pin2 = [self addPin:CGPointMake(self.size.width/2+(kNodes+1)*(pin.size.width+1), self.size.height/4)];
[self addChild:pin2];
[nodes addObject:pin2];
for( int i = 1; i<=kNodes+1; i++) {
SKSpriteNode *nodeA = [nodes objectAtIndex:i-1];
SKSpriteNode *nodeB = [nodes objectAtIndex:i];
[self addSpringJointFrom:nodeA to:nodeB];
}
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
SKSpriteNode *ball = [self spawnBallAt:[touch locationInNode:self]];
[self addChild:ball];
}
}
-(SKSpriteNode*) spawnBallAt:(CGPoint)location
{
SKSpriteNode *ball = [SKSpriteNode spriteNodeWithTexture:[[SKTextureAtlas atlasNamed:@"game"] textureNamed:@"circle"]];
ball.position = CGPointMake( location.x, location.y);
ball.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:ball.size.width/2];
ball.physicsBody.dynamic = YES;
ball.physicsBody.affectedByGravity = YES;
ball.physicsBody.mass = 40.0f;
ball.physicsBody.categoryBitMask = CategoryMaskBall;
ball.physicsBody.collisionBitMask = CategoryMaskElastic ;
ball.physicsBody.contactTestBitMask = 0;
ball.name = @"ball";
return ball;
}
-(SKSpriteNode*) addPin:(CGPoint) location {
SKSpriteNode *pin = [SKSpriteNode spriteNodeWithTexture:[[SKTextureAtlas atlasNamed:@"game"] textureNamed:@"pin"]];
pin.position = location;
pin.zPosition = 1;
CGFloat offsetX = pin.size.width * pin.anchorPoint.x;
CGFloat offsetY = pin.size.height * pin.anchorPoint.y;
CGMutablePathRef path = CGPathCreateMutable();
CGFloat side = pin.size.width;
CGPathMoveToPoint(path, NULL, 0 - offsetX, side - offsetY);
CGPathAddLineToPoint(path, NULL, side - offsetX, side - offsetY);
CGPathAddLineToPoint(path, NULL, side - offsetX, 0 - offsetY);
CGPathAddLineToPoint(path, NULL, 0 - offsetX, 0 - offsetY);
CGPathCloseSubpath(path);
pin.physicsBody = [SKPhysicsBody bodyWithPolygonFromPath:path];
pin.physicsBody.affectedByGravity = NO;
pin.physicsBody.dynamic = NO;
pin.physicsBody.categoryBitMask = CategoryMaskPin;
pin.physicsBody.collisionBitMask = 0;
pin.physicsBody.contactTestBitMask = 0;
CGPathRelease(path);
return pin;
}
-(SKSpriteNode*) addElastic:(CGPoint) location
{
SKSpriteNode *elastic = [SKSpriteNode spriteNodeWithTexture:[[SKTextureAtlas atlasNamed:@"game"] textureNamed:@"elastic"]];
elastic.position = location;
elastic.zPosition = 1;
CGFloat offsetX = elastic.frame.size.width * elastic.anchorPoint.x;
CGFloat offsetY = elastic.frame.size.height * elastic.anchorPoint.y;
CGMutablePathRef path = CGPathCreateMutable();
CGFloat side = elastic.size.width;
CGPathMoveToPoint(path, NULL, 0 - offsetX, side - offsetY);
CGPathAddLineToPoint(path, NULL, side - offsetX, side - offsetY);
CGPathAddLineToPoint(path, NULL, side - offsetX, 0 - offsetY);
CGPathAddLineToPoint(path, NULL, 0 - offsetX, 0 - offsetY);
CGPathCloseSubpath(path);
elastic.physicsBody = [SKPhysicsBody bodyWithPolygonFromPath:path];
elastic.physicsBody.affectedByGravity = YES;
elastic.physicsBody.allowsRotation = NO;
elastic.physicsBody.dynamic = YES;
elastic.physicsBody.mass = 1.0f;
elastic.physicsBody.categoryBitMask = CategoryMaskElastic;
elastic.physicsBody.collisionBitMask = CategoryMaskBall;
elastic.physicsBody.contactTestBitMask = 0;
CGPathRelease(path);
return elastic;
}
- (void) addSpringJointFrom:(SKSpriteNode*) nodeA to:(SKSpriteNode*) nodeB {
SKPhysicsJointSpring *joint = [SKPhysicsJointSpring jointWithBodyA:nodeA.physicsBody bodyB:nodeB.physicsBody anchorA:nodeA.position anchorB:nodeB.position];
joint.frequency = kFrequency; //gives the joint some elasticity.
joint.damping = kDamping; // 0.0f Will remove damping to create the 'pendulum'
[self.physicsWorld addJoint:joint];
}
@end