Building a rotating mill for your game with SKPhysics and SKPhysicsJointPin. Here is the class code for a simple physical mill like in this video
The class can be called like this
1 |
[WWMill addMill:game pos:CGPointMake(220, 200) speed:1 rotateDirection:@"right"]; |
The „game“-argument should be your SKScene object where the mill would be added. The „pos“-argument sets the position of the whole thing. „speed“ is the duration that is needed for on full rotation. The „rotateDirection“-argument can be „right“ or „left“
The physic bodies are arranged with four bodies connected with a SKPinJoint in the middle.
This is the complete class code to generate this mills:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
+(void) addMill:(SKScene*)game pos:(CGPoint)pos speed:(float)speed rotateDirection:(NSString*)rotateDirection { SKSpriteNode* mill = [SKSpriteNode spriteNodeWithImageNamed:@"dummypixel_transparent.png"]; mill.position = pos; mill.name = @"mill"; int angle; if ([rotateDirection isEqualToString:@"left"]) { angle = 360; } else { angle = -360; } SKAction* rotate = [SKAction rotateByAngle:angle / 180.0f * M_PI duration:speed]; SKAction* repeat = [SKAction repeatActionForever:rotate]; SKSpriteNode* anchor = [SKSpriteNode spriteNodeWithImageNamed:@"dummypixel_transparent.png"]; anchor.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:anchor.size]; anchor.physicsBody.affectedByGravity = false; anchor.physicsBody.mass = 999999999999999999; SKSpriteNode* bar_1 = [SKSpriteNode spriteNodeWithImageNamed:@"dummypixel_transparent.png"]; bar_1.position = anchor.position; bar_1.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(10, 150)]; bar_1.physicsBody.affectedByGravity = false; bar_1.physicsBody.mass = 0; bar_1.physicsBody.friction = 0; SKSpriteNode* bar_2 = [SKSpriteNode spriteNodeWithImageNamed:@"dummypixel_transparent.png"]; bar_2.position = anchor.position; bar_2.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(10, 150)]; bar_2.physicsBody.affectedByGravity = false; bar_2.physicsBody.mass = 0; bar_2.physicsBody.friction = 0; bar_2.zRotation = 90 / 180.0f * M_PI; [mill addChild:anchor]; [mill addChild:bar_1]; [mill addChild:bar_2]; [game addChild:mill]; SKSpriteNode* wing = [SKSpriteNode spriteNodeWithImageNamed:@"millwing.png"]; [wing setScale:0.17]; [bar_1 addChild:wing]; [bar_2 addChild:wing.copy]; SKPhysicsJointPin* joint_1 = [SKPhysicsJointPin jointWithBodyA:bar_1.physicsBody bodyB: anchor.physicsBody anchor:mill.position]; [game.physicsWorld addJoint:joint_1]; SKPhysicsJointPin* joint_2 = [SKPhysicsJointPin jointWithBodyA:bar_2.physicsBody bodyB: anchor.physicsBody anchor:mill.position]; [game.physicsWorld addJoint:joint_2]; SKSpriteNode* gear_0 = [SKSpriteNode spriteNodeWithImageNamed:@"gear_0.png"]; anchor.alpha = 1; gear_0.zPosition = 2; [gear_0 setScale:0.1]; [anchor addChild:gear_0]; SKSpriteNode* gear_1 = [SKSpriteNode spriteNodeWithImageNamed:@"gear_1.png"]; anchor.alpha = 1; gear_1.zPosition = 2; [gear_1 setScale:0.1]; [anchor addChild:gear_1]; if(speed >= 0) { [bar_1 runAction:repeat withKey:@"mill_rotate"]; [bar_2 runAction:repeat withKey:@"mill_rotate"]; [gear_0 runAction:repeat withKey:@"mill_rotate"]; [gear_1 runAction:repeat withKey:@"mill_rotate"]; SKAction* splash = [SKAction runBlock:^{ SKEmitterNode *waterSplash = [WWWater loadWaterSplash]; waterSplash.position = CGPointMake(anchor.position.x-15, anchor.position.y-40); [game addChild:waterSplash]; [waterSplash runAction:[SKAction sequence:@[[SKAction waitForDuration:0.6], [SKAction runBlock:^ { waterSplash.yAcceleration = -500; }], [SKAction fadeAlphaTo:0 duration:1] ]] completion:^{ [waterSplash removeFromParent]; }]; }]; SKAction* wait = [SKAction waitForDuration:3 withRange:5]; SKAction* seq = [SKAction sequence:@[wait, splash]]; SKAction* repeatSplash = [SKAction repeatActionForever:seq]; [anchor runAction:repeatSplash withKey:@"mill_rotate"]; } } |
Thanks a lot! Really appreciated!