iPhone電車と停止線

ホームの停止線ぴったりに電車を停車させられるかな。というiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

#import <SpriteKit/SpriteKit.h>

@interface TrainScene : SKScene

@property BOOL brake;

@end

@implementation TrainScene

– (void)didMoveToView:(SKView *)view

{

    self.backgroundColor = [SKColor colorWithRed:0.9 green:0.9 blue:1.0 alpha:1.0];

    [self createPlathome];

    [self createTrain];

    [self createYellowLine];

    [self createMeter];

    

    self.brake = YES;

}

– (void)createPlathome

{

    SKSpriteNode *plathome = [SKSpriteNode spriteNodeWithColor:[SKColor lightGrayColor] size:CGSizeMake(CGRectGetMaxX(self.frame), 50)];

    plathome.position = CGPointMake(CGRectGetMidX(self.frame), 25);

    [self addChild:plathome];

    

    plathome.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:plathome.size];

    plathome.physicsBody.friction = 0.1;

    plathome.physicsBody.dynamic = NO;

    

    SKSpriteNode *stopLine = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(5, 30)];

    stopLine.name = @”stopLine”;

    stopLine.position = CGPointMake(CGRectGetMaxX(self.frame) – 55, 40);

    stopLine.zPosition = 2;

    [self addChild:stopLine];

}

– (void)createTrain

{

    SKNode *train = [SKNode node];

    train.name = @”train”;

    train.position = CGPointMake(30, 60);

    [self addChild:train];

    

    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(-25, –2, 50, 6) cornerRadius:2];

    SKShapeNode *roof = [SKShapeNode node];

    roof.path = path.CGPath;

    roof.position = CGPointMake(0, 10);

    roof.lineWidth = 0;

    roof.fillColor = [SKColor grayColor];

    [train addChild:roof];

    

    SKSpriteNode *body = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(50, 20)];

    [train addChild:body];

    

    for (int i=0; i<4; i++) {

        SKSpriteNode *w = [SKSpriteNode spriteNodeWithColor:[SKColor whiteColor] size:CGSizeMake(4, 4)];

        w.position = CGPointMake(i * 1320, 0);

        [train addChild:w];

    }

    

    train.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:body.size];

    train.physicsBody.friction = 0;

}

– (void)createYellowLine

{

    for (int i=0; i<20; i++) {

        SKSpriteNode *y = [SKSpriteNode spriteNodeWithColor:[SKColor yellowColor] size:CGSizeMake(10, 10)];

        y.position = CGPointMake(i * 23 + 20, 35 + (arc4random() % 10) * 0.3);

        [self addChild:y];

    }

}

– (void)createMeter

{

    SKLabelNode *meter = [SKLabelNode node];

    meter.name = @”meter”;

    meter.text = @”—“;

    meter.fontColor = [SKColor blackColor];

    meter.fontSize = 80;

    meter.position = CGPointMake(300, 200);

    [self addChild:meter];

    

    SKShapeNode *guideLine = [SKShapeNode node];

    guideLine.name = @”guideLine”;

    guideLine.lineWidth = 2;

    guideLine.strokeColor = [[SKColor blackColor] colorWithAlphaComponent:0.5];

    [self addChild:guideLine];

}

– (void)didSimulatePhysics

{

    SKLabelNode *meter = (SKLabelNode *)[self childNodeWithName:@”meter”];

    SKShapeNode *guideLine = (SKShapeNode *)[self childNodeWithName:@”guideLine”];

    SKNode *train = [self childNodeWithName:@”train”];

    SKNode *stopLine = [self childNodeWithName:@”stopLine”];

    

    float d =  stopLine.position.x – train.position.x;

    meter.text = [NSString stringWithFormat:@”%d”, (int)d];

    

    UIBezierPath *path = [UIBezierPath bezierPath];

    [path moveToPoint:train.position];

    [path addLineToPoint:meter.position];

    [path addLineToPoint:stopLine.position];

    // SKShapeNode dash path

    CGFloat pattern[2]; pattern[0]=2; pattern[1]=10;

    CGPathRef pathDash = CGPathCreateCopyByDashingPath(path.CGPath, NULL, 2, pattern, 2);

    guideLine.path = pathDash;

    if (train.position.x > CGRectGetMaxX(self.frame)) {

        [train removeFromParent];

        [self createTrain];

        self.brake = YES;

    }

}

– (void)update:(NSTimeInterval)currentTime

{

    SKNode *train = [self childNodeWithName:@”train”];

    if (!self.brake) {

        train.physicsBody.friction = 0;

        [train.physicsBody applyForce:CGVectorMake(10, 0)];

    } else {

        train.physicsBody.friction = 0.1;

    }

}

– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

    self.brake = !self.brake;

}

@end

@interface ViewController ()

@end

@implementation ViewController

– (void)viewDidAppear:(BOOL)animated

{

    SKView *spriteView = [[SKView alloc] initWithFrame:self.view.bounds];

    [self.view addSubview:spriteView];

    SKScene *scene = [[TrainScene alloc] initWithSize:spriteView.frame.size];

    [spriteView presentScene:scene];

}

@end