
X軸Y軸の2つの軸をギアで動かすiPhoneアプリのサンプルコードを描いてみます。
@import SpriteKit;
#import “ViewController.h”
@interface GearScene : SKScene
@property (nonatomic) BOOL moveV;
@property (nonatomic) BOOL moveH;
@end
@implementation GearScene
– (void)didMoveToView:(SKView *)view
{
self.backgroundColor = [SKColor yellowColor];
self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:CGRectMake(-300, 0, CGRectGetMaxX(self.frame) + 600, CGRectGetMaxY(self.frame))];
[self createVerticalGear];
[self createHorizontalGear];
}
– (void)createVerticalGear
{
NSMutableArray *bodies = [NSMutableArray array];
SKSpriteNode *bar = [SKSpriteNode spriteNodeWithColor:[SKColor darkGrayColor] size:CGSizeMake(20, 300)];
bar.name = @”vBar”;
bar.position = CGPointMake(76.5, CGRectGetMidX(self.frame) + 20);
[self addChild:bar];
[bodies addObject:[SKPhysicsBody bodyWithRectangleOfSize:bar.size center:bar.position]];
for (int i=0; i<15; i++) {
SKSpriteNode *t = [SKSpriteNode spriteNodeWithColor:[SKColor darkGrayColor] size:CGSizeMake(30, 5)];
t.position = CGPointMake(0, i * 20 – 7.5 * 20);
[bar addChild:t];
[bodies addObject:[SKPhysicsBody bodyWithRectangleOfSize:t.size center:t.position]];
}
bar.physicsBody = [SKPhysicsBody bodyWithBodies:bodies];
bar.physicsBody.categoryBitMask = 0x1 << 1;
bar.physicsBody.collisionBitMask = 0x1 << 1 | 0x1 << 5;
bar.physicsBody.linearDamping = 1.0;
SKPhysicsJointSliding *sl = [SKPhysicsJointSliding jointWithBodyA:bar.physicsBody bodyB:self.physicsBody anchor:bar.position axis:CGVectorMake(0, 1)];
sl.shouldEnableLimits = YES;
sl.upperDistanceLimit = 100;
sl.lowerDistanceLimit = –100;
[self.physicsWorld addJoint:sl];
SKNode *gear = [self createGear:bar.physicsBody.categoryBitMask];
gear.position = CGPointMake(40, 160);
gear.name = @”gearV”;
SKPhysicsJointPin *pin = [SKPhysicsJointPin jointWithBodyA:gear.physicsBody bodyB:self.physicsBody anchor:gear.position];
pin.frictionTorque = 0.8;
[self.physicsWorld addJoint:pin];
}
– (void)createHorizontalGear
{
SKNode *vBar = [self childNodeWithName:@”vBar”];
NSMutableArray *bodies = [NSMutableArray array];
SKSpriteNode *bar = [SKSpriteNode spriteNodeWithColor:[SKColor darkGrayColor] size:CGSizeMake(300, 20)];
bar.name = @”hBar”;
bar.position = CGPointMake(0, CGRectGetMaxY(vBar.frame) – 50);
[self addChild:bar];
[bodies addObject:[SKPhysicsBody bodyWithRectangleOfSize:bar.size center:bar.position]];
for (int i=0; i<15; i++) {
SKSpriteNode *t = [SKSpriteNode spriteNodeWithColor:[SKColor darkGrayColor] size:CGSizeMake(5, 30)];
t.position = CGPointMake(i * 20 – 7.5 * 20, 0);
[bar addChild:t];
[bodies addObject:[SKPhysicsBody bodyWithRectangleOfSize:t.size center:t.position]];
}
bar.physicsBody = [SKPhysicsBody bodyWithBodies:bodies];
bar.physicsBody.affectedByGravity = NO;
bar.physicsBody.categoryBitMask = 0x1 << 2;
bar.physicsBody.collisionBitMask = 0x1 << 2 | 0x1 << 5;
bar.physicsBody.allowsRotation = NO;
bar.physicsBody.linearDamping = 1.0;
SKNode *gear = [self createGear:bar.physicsBody.categoryBitMask];
gear.position = CGPointMake(40, CGRectGetMaxY(vBar.frame) + 135);
gear.name = @”gearH”;
SKPhysicsJointPin *pin = [SKPhysicsJointPin jointWithBodyA:gear.physicsBody bodyB:self.physicsBody anchor:gear.position];
pin.frictionTorque = 0.8;
[self.physicsWorld addJoint:pin];
}
– (SKNode *)createGear:(uint32_t)mask
{
SKNode *gear = [SKNode node];
[self addChild:gear];
gear.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:15];
for (int i=0; i<4; i++) {
SKSpriteNode *t = [SKSpriteNode spriteNodeWithColor:[SKColor darkGrayColor] size:CGSizeMake(48, 5)];
t.position = gear.position;
t.zRotation = i * M_PI / 4.0;
t.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:t.size];
t.physicsBody.categoryBitMask = 0x1 << 5;
t.physicsBody.collisionBitMask = mask;
[self addChild:t];
SKPhysicsJointFixed *f = [SKPhysicsJointFixed jointWithBodyA:gear.physicsBody bodyB:t.physicsBody anchor:t.position];
[self.physicsWorld addJoint:f];
}
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointZero radius:15 startAngle:0 endAngle:2.0*M_PI clockwise:NO];
SKShapeNode *circle = [SKShapeNode node];
circle.fillColor = [SKColor lightGrayColor];
circle.lineWidth = 5;
circle.strokeColor = [SKColor darkGrayColor];
circle.path = path.CGPath;
[gear addChild:circle];
return gear;
}
– (void)update:(NSTimeInterval)currentTime
{
SKNode *barV = [self childNodeWithName:@”vBar”];
SKNode *barH = [self childNodeWithName:@”hBar”];
barH.position = CGPointMake(barH.position.x, CGRectGetMaxY(barV.frame));
if (self.moveV) {
SKNode *gearV = [self childNodeWithName:@”gearV”];
[gearV.physicsBody applyTorque:2.5];
} else if (self.moveH) {
SKNode *gearH = [self childNodeWithName:@”gearH”];
[gearH.physicsBody applyTorque:1];
}
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint p = [[touches anyObject] locationInNode:self];
SKNode *gearV = [self childNodeWithName:@”gearV”];
SKNode *gearH = [self childNodeWithName:@”gearH”];
if ([gearV containsPoint:p]) {
self.moveV = YES;
} else if ([gearH containsPoint:p]) {
self.moveH = YES;
}
}
– (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
self.moveV = NO;
self.moveH = NO;
}
@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:CGSizeMake(320, 568)];
[spriteView presentScene:scene];
}
– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end