iphoneクレーン前進

クレーン車がキャタピラ回しながら前進するという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.x50, 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.y90);

    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.x10, p.y10);

    [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.x10, p.y10)];

    [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