遊星歯車というのがかっこ良かったので、iPhoneアプリのサンプルコードを描いてみました。
動かすとこんな感じです
サンプルコード
#import “ViewController.h”
#import <SpriteKit/SpriteKit.h>
@interface GearScene : SKScene
@end
typedef enum : int8_t {
CollideTypeTeeth = 0x1 << 1,
CollideTypeGear = 0x1 << 2,
CollideTypeBase = 0x1 << 3,
CollideTypeNone = 0x1 << 4,
} CollideType;
@implementation GearScene
– (void)didMoveToView:(SKView *)view
{
[self createBaseBody];
[self createGear];
}
– (void)createBaseBody
{
SKSpriteNode *base = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:self.frame.size];
base.name = @”base”;
base.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
[self addChild:base];
base.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:base.size];
base.physicsBody.categoryBitMask = CollideTypeBase;
base.physicsBody.collisionBitMask = CollideTypeBase;
base.physicsBody.dynamic = NO;
}
– (void)createGear
{
CGPoint o = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
// sun gear
UIBezierPath *sunpath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-50, –50, 100, 100)];
SKShapeNode *sun = [SKShapeNode node];
sun.name = @”sun”;
sun.position = o;
sun.path = sunpath.CGPath;
[self addChild:sun];
sun.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:50];
sun.physicsBody.categoryBitMask = CollideTypeGear;
sun.physicsBody.collisionBitMask = CollideTypeGear | CollideTypeTeeth;
sun.physicsBody.restitution = 0;
[self createTeeth:sun radius:53 number:20];
// planet
NSMutableArray *planets = [NSMutableArray array];
for (int i=0; i<3; i++) {
float angle = 2.0 * M_PI / 3.0 * i;
float x = 75 * cos(angle) + o.x;
float y = 75 * sin(angle) + o.y;
float r = 16;
UIBezierPath *planetpath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-r, -r, r*2.0, r*2.0)];
SKShapeNode *planet = [SKShapeNode node];
planet.position = CGPointMake(x, y);
planet.path = planetpath.CGPath;
[self addChild:planet];
planet.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:r];
planet.physicsBody.categoryBitMask = CollideTypeGear;
planet.physicsBody.collisionBitMask = CollideTypeGear | CollideTypeTeeth;
planet.physicsBody.restitution = 0;
[self createTeeth:planet radius:r+3 number:8];
[planets addObject:planet];
}
// outer gear
UIBezierPath *outerpath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-100, –100, 200, 200)];
SKShapeNode *outer = [SKShapeNode node];
outer.position = o;
outer.path = outerpath.CGPath;
[self addChild:outer];
outer.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:100];
outer.physicsBody.categoryBitMask = CollideTypeNone;
outer.physicsBody.collisionBitMask = CollideTypeNone;
outer.physicsBody.restitution = 0;
[self createTeeth:outer radius:97 number:40];
SKNode *base = [self childNodeWithName:@”base”];
NSArray *gears = @[sun, planets[0], planets[1], planets[2], outer];
for (SKNode *node in gears) {
SKPhysicsJointPin *pin = [SKPhysicsJointPin jointWithBodyA:node.physicsBody bodyB:base.physicsBody anchor:node.position];
[self.physicsWorld addJoint:pin];
}
}
– (void)createTeeth:(SKNode*)gear radius:(float)r number:(int)number
{
for (int i=0; i<number; i++) {
float angle = 2.0 * M_PI / number * i;
float x = cos(angle) * r + gear.position.x;
float y = sin(angle) * r + gear.position.y;
SKSpriteNode *node = [SKSpriteNode spriteNodeWithColor:[SKColor whiteColor] size:CGSizeMake(4, 8)];
node.position = CGPointMake(x, y);
node.zRotation = angle + M_PI / 2.0;
[self addChild:node];
node.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:node.size];
node.physicsBody.categoryBitMask = CollideTypeTeeth;
node.physicsBody.collisionBitMask = CollideTypeGear | CollideTypeTeeth;
SKPhysicsJointFixed *fixed = [SKPhysicsJointFixed jointWithBodyA:gear.physicsBody bodyB:node.physicsBody anchor:node.position];
[self.physicsWorld addJoint:fixed];
}
}
– (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
SKNode *sun = [self childNodeWithName:@”sun”];
[sun.physicsBody applyTorque:0.1];
}
@end
@interface ViewController ()
@end
@implementation ViewController
– (void)viewDidLoad
{
[super viewDidLoad];
SKView *spriteView = [[SKView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:spriteView];
SKScene *scene = [[GearScene alloc] initWithSize:spriteView.frame.size];
[spriteView presentScene:scene];
}
@end