
ホームの停止線ぴったりに電車を停車させられるかな。という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 * 13 – 20, 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