「作ろうジャンプゲーム その1」の続きです。簡単なゴールとして、赤いはたを一番上の段に置いて、それをゲットするまでにかかった時間がわかるように、画面右上にタイマーを付けてみます。
動作イメージ
XcodeからiOS7 iPhone Simulatorで動かすとこんな感じになります。
サンプルコード
#import “ViewController.h”
#import <SpriteKit/SpriteKit.h>
@interface JumpGameScene : SKScene <SKPhysicsContactDelegate>
@property BOOL contentCreated;
@property float startTime;
@end
typedef enum : uint8_t {
ColliderTypeBlock = 1,
ColliderTypePlayer = 2,
ColliderTypeGoal = 3,
} GameObjectType;
@implementation JumpGameScene
– (void)didMoveToView:(SKView *)view
{
if (!self.contentCreated) {
[self createSceneContents];
self.contentCreated = YES;
self.backgroundColor = [SKColor greenColor];
self.physicsWorld.contactDelegate = self;
}
}
– (void)createSceneContents
{
[self createBlocks];
[self createPlayer];
[self createTimer];
[self createGoalFlag];
}
– (void)createTimer
{
SKLabelNode *timeLabel = [SKLabelNode labelNodeWithFontNamed:@”Courier New”];
timeLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeLeft;
timeLabel.name = @”time”;
timeLabel.text = [NSString stringWithFormat:@”Time:%04d”, 0];
timeLabel.position = CGPointMake(CGRectGetMaxX(self.frame) – 180, CGRectGetMaxY(self.frame) – 40);
[self addChild:timeLabel];
}
– (void)createGoalFlag
{
SKSpriteNode *flag = [SKSpriteNode spriteNodeWithImageNamed:@”flag”];
flag.name = @”flag”;
flag.position = CGPointMake(150, CGRectGetMaxY(self.frame) – 10);
flag.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:flag.size];
flag.physicsBody.categoryBitMask = ColliderTypeGoal;
flag.physicsBody.contactTestBitMask = ColliderTypePlayer;
[self addChild:flag];
}
– (void)createBlocks
{
// bottom
for (int i=0; i<13; i++) {
float x = i * 40;
float y = 20;
[self createBlockWithPoint:CGPointMake(x, y)];
}
// 2nd
for (int i=0; i<13; i++) {
if (i == 3 || i == 4 || i == 9 || i == 10) {
continue;
}
float x = i * 40;
float y = 120;
[self createBlockWithPoint:CGPointMake(x, y)];
}
// top
for (int i=0; i<13; i++) {
if (i == 7 || i == 8) {
continue;
}
float x = i * 40;
float y = 220;
[self createBlockWithPoint:CGPointMake(x, y)];
}
}
– (void)createBlockWithPoint:(CGPoint)p
{
SKTexture *blockTexture = [SKTexture textureWithImageNamed:@”block”];
SKSpriteNode *block = [SKSpriteNode spriteNodeWithTexture:blockTexture size:CGSizeMake(40, 40)];
block.position = p;
block.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:block.size];
block.physicsBody.dynamic = NO;
[self addChild:block];
block.physicsBody.categoryBitMask = ColliderTypeBlock;
}
– (void)createPlayer
{
SKSpriteNode *player = [SKSpriteNode spriteNodeWithTexture:nil size:CGSizeMake(50, 50)];
player.name = @”player”;
player.position = CGPointMake(50, 80);
player.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:player.size];
player.physicsBody.allowsRotation = NO;
player.physicsBody.linearDamping = 1.0;
[self addChild:player];
[self walk];
player.physicsBody.categoryBitMask = ColliderTypePlayer;
}
– (void)walk
{
SKNode *player = [self childNodeWithName:@”player”];
SKTexture *walkA = [SKTexture textureWithImageNamed:@”player-walkA.png”];
SKTexture *walkB = [SKTexture textureWithImageNamed:@”player-walkB.png”];
NSArray *frames = @[walkA, walkB];
SKAction *walk = [SKAction animateWithTextures:frames timePerFrame:0.2 resize:NO restore:NO];
[player runAction:[SKAction repeatActionForever:walk]];
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
SKNode *player = [self childNodeWithName:@”player”];
[player.physicsBody applyImpulse:CGVectorMake(0, 70)];
}
– (void)update:(NSTimeInterval)currentTime
{
// player move
SKNode *player = [self childNodeWithName:@”player”];
player.physicsBody.velocity = CGVectorMake(50, player.physicsBody.velocity.dy);
// time counter
if (self.startTime == 0) {
self.startTime = currentTime;
}
SKLabelNode *timeLabel = (SKLabelNode*)[self childNodeWithName:@”time”];
NSUInteger t = currentTime – self.startTime;
[timeLabel setText:[NSString stringWithFormat:@”Time:%04d”, t]];
}
– (void)didBeginContact:(SKPhysicsContact *)contact
{
SKNode *flag = [self childNodeWithName:@”flag”];
flag.physicsBody = nil;
SKAction *up = [SKAction moveBy:CGVectorMake(0, 20) duration:0.3];
SKAction *scale = [SKAction scaleBy:1.1 duration:0.3];
SKAction *fade = [SKAction fadeOutWithDuration:3.0];
[flag runAction:[SKAction group:@[up, scale, fade]]];
SKLabelNode *timeLabel = (SKLabelNode*)[self childNodeWithName:@”time”];
timeLabel.name = @”goaltime”;
NSUInteger t = [[timeLabel.text substringFromIndex:5] integerValue];
[timeLabel setText:[NSString stringWithFormat:@”Goal:%04d”, t]];
}
– (void)didSimulatePhysics
{
SKNode *player = [self childNodeWithName:@”player”];
if (player.position.x > CGRectGetMaxX(self.frame) + 40) {
player.position = CGPointMake(-40, player.position.y);
}
}
@end
@interface ViewController ()
@end
@implementation ViewController
– (void)viewDidLoad
{
[super viewDidLoad];
SKView *spriteView = [[SKView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetMaxY(self.view.frame), CGRectGetMaxX(self.view.frame))];
[self.view addSubview:spriteView];
SKScene *scene = [[JumpGameScene alloc] initWithSize:spriteView.frame.size];
[spriteView presentScene:scene];
}
– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end