クレーン車がキャタピラ回しながら前進するというiPhoneアプリのサンプルコードを描いてみます。
使った画像
うごかすとこんな感じです
サンプルコード
#import “ViewController.h”
#import <SpriteKit/SpriteKit.h>
@interface CraneScene : SKScene
@property BOOL contentCreated;
@property BOOL move;
@end
@implementation CraneScene
– (void)didMoveToView:(SKView *)view
{
if (!self.contentCreated) {
[self createSceneContents];
self.contentCreated = YES;
}
}
– (void)createSceneContents
{
self.backgroundColor = [SKColor colorWithRed:0.9 green:0.9 blue:1.0 alpha:1.0];
[self createGround];
[self createCraneTruck];
[self createBox];
}
– (void)createGround
{
SKSpriteNode *ground = [SKSpriteNode spriteNodeWithColor:[SKColor brownColor] size:CGSizeMake(CGRectGetMaxX(self.frame), 60)];
ground.position = CGPointMake(CGRectGetMidX(self.frame), 30);
[self addChild:ground];
ground.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:ground.size];
ground.physicsBody.dynamic = NO;
}
– (void)createCraneTruck
{
SKSpriteNode *body = [SKSpriteNode spriteNodeWithImageNamed:@”truck”];
body.name = @”cranetruck”;
body.position = CGPointMake(CGRectGetMaxX(self.frame)-50, 85);
[self addChild:body];
body.zPosition = 10;
body.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:body.size];
body.physicsBody.density = 10.0;
body.physicsBody.allowsRotation = NO;
UIBezierPath *path = [UIBezierPath bezierPath];
float x = –25;
float y = –15;
[path moveToPoint:CGPointMake(x, y)];
[path addArcWithCenter:CGPointMake(x, y-10) radius:10 startAngle:M_PI/2.0 endAngle:-M_PI/2.0 clockwise:YES];
[path addLineToPoint:CGPointMake(x+50, y-20)];
[path addArcWithCenter:CGPointMake(x+50, y-10) radius:10 startAngle:-M_PI/2.0 endAngle:M_PI/2.0 clockwise:YES];
[path addLineToPoint:CGPointMake(x, y)];
SKShapeNode *line = [SKShapeNode node];
line.strokeColor = [SKColor brownColor];
line.path = path.CGPath;
[body addChild:line];
for (int i=0; i<20; i++) {
SKSpriteNode *plate = [SKSpriteNode spriteNodeWithColor:[SKColor blackColor] size:CGSizeMake(8, 6)];
plate.name = @”palte”;
plate.position = CGPointMake(x, y);
[body addChild:plate];
SKAction *waite = [SKAction waitForDuration:0.11 * i];
SKAction *turn = [SKAction followPath:path.CGPath asOffset:NO orientToPath:NO duration:2.0];
[plate runAction:[SKAction sequence:@[waite, [SKAction repeatActionForever:turn]]]];
}
SKSpriteNode *crane = [SKSpriteNode spriteNodeWithImageNamed:@”crane”];
crane.position = CGPointMake(body.position.x – 50, 140);
[self addChild:crane];
crane.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:crane.size];
SKPhysicsJointPin *pin = [SKPhysicsJointPin jointWithBodyA:body.physicsBody bodyB:crane.physicsBody anchor:CGPointMake(x, y)];
[self.physicsWorld addJoint:pin];
SKSpriteNode *hook = [self createHook:CGPointMake(CGRectGetMaxX(self.frame) – 120, 100)];
CGPoint top = CGPointMake(crane.frame.origin.x, crane.frame.origin.y + crane.frame.size.height);
CGPoint bottom = CGPointMake(top.x+10, top.y – 90);
SKPhysicsJointLimit *limit = [SKPhysicsJointLimit jointWithBodyA:crane.physicsBody bodyB:hook.physicsBody anchorA:top anchorB:bottom];
limit.maxLength = 100;
[self.physicsWorld addJoint:limit];
}
– (SKSpriteNode*)createHook:(CGPoint)p
{
SKSpriteNode *partA = [[SKSpriteNode alloc] initWithColor:[SKColor blackColor] size:CGSizeMake(30, 5)];
partA.position = CGPointMake(p.x–10, p.y–10);
[self addChild:partA];
SKSpriteNode *partC = [[SKSpriteNode alloc] initWithColor:[SKColor blackColor] size:CGSizeMake(5, 30)];
partC.position = p;
[self addChild:partC];
[@[partA, partC] enumerateObjectsUsingBlock:^(SKSpriteNode *part, NSUInteger idx, BOOL *stop) {
part.physicsBody.categoryBitMask = 0x1;
part.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:part.size];
part.physicsBody.collisionBitMask = 0x1;
}];
SKPhysicsJointFixed *ac = [SKPhysicsJointFixed jointWithBodyA:partA.physicsBody bodyB:partC.physicsBody anchor:CGPointMake(p.x–10, p.y–10)];
[self.physicsWorld addJoint:ac];
return partC;
}
– (void)createBox
{
for (int i=0; i<3; i++) {
SKSpriteNode *box = [SKSpriteNode spriteNodeWithColor:[SKColor greenColor] size:CGSizeMake(30, 30)];
box.position = CGPointMake(150 + 50 * i, 100);
[self addChild:box];
box.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:15];
box.physicsBody.density = 0.01;
box.physicsBody.linearDamping = 0.5;
box.physicsBody.friction = 0;
box.physicsBody.restitution = 0.8;
}
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
self.move = !self.move;
}
– (void)update:(NSTimeInterval)currentTime
{
if (self.move) {
SKNode *crane = [self childNodeWithName:@”cranetruck”];
crane.physicsBody.velocity = CGVectorMake(-50, 0);
}
}
@end
@interface ViewController ()
@end
@implementation ViewController
– (void)viewDidAppear:(BOOL)animated
{
SKView *spriteView = [[SKView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:spriteView];
SKScene *scene = [[CraneScene alloc] initWithSize:spriteView.frame.size];
[spriteView presentScene:scene];
}
@end