iOS/iPhone/iPad/watchOS/tvOS/MacOSX/Android プログラミング, Objective-C, Cocoa, Swiftなど
『Sprite Kit Programming Guide』を参考に物理シミュレートを組み込んでみた。
宇宙船に物理的な実態を与えてみよう。
@implementation SpaceshipScene
...
- (SKSpriteNode *)newSpaceship
{
/* 宇宙船を生成 */
SKSpriteNode *hull = [[SKSpriteNode alloc] initWithColor:[SKColor grayColor] size:CGSizeMake(64,32)];
/* 宇宙船にライトをつける */
SKSpriteNode *light1 = [self newLight];
light1.position = CGPointMake(-28.0, 6.0);
[hull addChild:light1];
/* 宇宙船にライトをつける */
SKSpriteNode *light2 = [self newLight];
light2.position = CGPointMake(28.0, 6.0);
[hull addChild:light2];
/* 宇宙船に実体を与える */
hull.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:hull.size];
/* 宇宙船に重力の影響が与えられないようにする */
hull.physicsBody.dynamic = NO;
/* 宇宙船を動かす */
SKAction *hover = [SKAction sequence:@[
[SKAction waitForDuration:1.0],
[SKAction moveByX:100 y:50.0 duration:1.0],
[SKAction waitForDuration:1.0],
[SKAction moveByX:-100.0 y:-50 duration:1.0]]];
[hull runAction: [SKAction repeatActionForever:hover]];
return hull;
}
...
@end
ランダムに岩石を生成して、それを落としてみよう。
static inline CGFloat skRandf(void)
{
return rand() / (CGFloat) RAND_MAX;
}
static inline CGFloat skRand(CGFloat low, CGFloat high)
{
return skRandf() * (high - low) + low;
}
...
@implementation SpaceshipScene
...
- (void)createSceneContents
{
self.backgroundColor = [SKColor blackColor];
self.scaleMode = SKSceneScaleModeAspectFit;
/* 宇宙船を配置 */
SKSpriteNode *spaceship = [self newSpaceship];
spaceship.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame) - 150);
[self addChild:spaceship];
/* 岩石を作り出す */
SKAction *makeRocks = [SKAction sequence: @[
[SKAction performSelector:@selector(addRock) onTarget:self],
[SKAction waitForDuration:0.10 withRange:0.15]
]];
[self runAction: [SKAction repeatActionForever:makeRocks]];
}
...
- (void)addRock
{
/* 岩石を作り出す */
SKSpriteNode *rock = [[SKSpriteNode alloc] initWithColor:[SKColor brownColor] size:CGSizeMake(8,8)];
rock.position = CGPointMake(skRand(0, self.size.width), self.size.height-50);
rock.name = @"rock";
rock.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:rock.size];
rock.physicsBody.usesPreciseCollisionDetection = YES; /* 衝突判定を正確に */
[self addChild:rock];
}
...
@end
下に落ちて見えなくなった岩石を削除する。
@implementation SpaceshipScene
...
-(void)didSimulatePhysics
{
/* 物理シミュレート後の実行 */
[self enumerateChildNodesWithName:@"rock" usingBlock:^(SKNode *node, BOOL *stop) {
/* 見えなくなった岩石を削除 */
if (node.position.y < 0)
[node removeFromParent];
}];
}
...
@end