iPhoneジャンプゲーム その2

iPhoneジャンプゲーム その2

「作ろうジャンプゲーム その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