iPhone ポールジャンプ

名作マリオに学びたい、その2。今回のiPhoneアプリサンプルコードは、ポールに掴まったらハタが上がるという動きをやってみます。

今回使った画像


サンプルを動かすとこんな感じです

サンプルコード

#import “ViewController.h”

#import <SpriteKit/SpriteKit.h>

typedef enum : int8_t {

    PlayerStateReady = 1,

    PlayerStateTouchRun,

    PlayerStateRun,

    PlayerStateTouchJump,

    PlayerStateJump,

    PlayerStateHold,

} PlayerState;

typedef enum : int8_t {

    ColliderTypePlayer = 0x1 << 1,

    ColliderTypePole = 0x1 << 2,

    ColliderTypeOther = 0x1 << 3,

} ColliderType;

@protocol RestartProtocol <NSObject>

– (void)restart;

@end

@interface JumpScene : SKScene <SKPhysicsContactDelegate>

@property BOOL contentCreated;

@property int playerState;

@property id<RestartProtocol> restartdelegate;

@end

@implementation JumpScene

– (void)didMoveToView:(SKView *)view

{

    if (!self.contentCreated) {

        [self createSceneContents];

        self.contentCreated = YES;

    }

}

– (void)createSceneContents

{

    self.backgroundColor = [SKColor blackColor];

    self.physicsWorld.contactDelegate = self;

    

    [self createGround];

    [self createPlayer];

    [self createPoleAndFlag];

    

    [self createTitle];

}

– (void)createGround

{

    SKSpriteNode *ground = [SKSpriteNode spriteNodeWithColor:[SKColor brownColor] size:CGSizeMake(CGRectGetMaxX(self.frame), 10)];

    ground.position = CGPointMake(CGRectGetMidX(self.frame), 10);

    [self addChild:ground];

    

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

    ground.physicsBody.dynamic = NO;

    ground.physicsBody.categoryBitMask = ColliderTypeOther;

}

– (void)createPlayer

{

    self.playerState = PlayerStateReady;

    

    SKSpriteNode *player = [SKSpriteNode spriteNodeWithImageNamed:@”player”];

    player.name = @”player”;

    player.position = CGPointMake(50, 30);

    player.zPosition = 1;

    [self addChild:player];

    

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

    player.physicsBody.allowsRotation = NO;

    player.physicsBody.categoryBitMask = ColliderTypePlayer;

    player.physicsBody.collisionBitMask = ColliderTypeOther;

    player.physicsBody.contactTestBitMask = ColliderTypePole;

}

– (void)createPoleAndFlag

{

    SKSpriteNode *pole = [SKSpriteNode spriteNodeWithImageNamed:@”pole”];

    pole.name = @”pole”;

    pole.position = CGPointMake(CGRectGetMaxX(self.frame) – 50, CGRectGetMaxY(pole.frame) + 10);

    [self addChild:pole];

    

    pole.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(10, pole.frame.size.height)];

    pole.physicsBody.dynamic = NO;

    pole.physicsBody.categoryBitMask = ColliderTypePole;

    pole.physicsBody.collisionBitMask = ColliderTypeOther;

    

    SKSpriteNode *flag = [SKSpriteNode spriteNodeWithImageNamed:@”flag”];

    flag.name = @”flag”;

    flag.position = CGPointMake(pole.frame.origin.x + 30, 40);

    [self addChild:flag];

}

– (void)createTitle

{

    SKLabelNode *title = [SKLabelNode node];

    title.name = @”title”;

    title.text = @”Ready”;

    title.fontSize = 50;

    title.position = CGPointMake(CGRectGetMidX(self.frame), 200);

    [self addChild:title];

}

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

{

    if (self.playerState == PlayerStateReady) {

        self.playerState = PlayerStateTouchRun;

    }

    

    if (self.playerState == PlayerStateRun) {

        self.playerState = PlayerStateTouchJump;

    }

}

– (void)update:(NSTimeInterval)currentTime

{

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

    if (self.playerState == PlayerStateTouchRun) {

        self.playerState = PlayerStateRun;

        

        // start running

        [player removeAllActions];

        SKTexture *run01 = [SKTexture textureWithImageNamed:@”player_walk_01″];

        SKTexture *run02 = [SKTexture textureWithImageNamed:@”player_walk_02″];

        SKTexture *run03 = [SKTexture textureWithImageNamed:@”player_walk_03″];

        SKAction *run = [SKAction animateWithTextures:@[run01, run02, run03] timePerFrame:0.1 resize:NO restore:NO];

        [player runAction:[SKAction repeatActionForever:run]];

        

        // change title

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

        title.text = @”Go”;

    }

    

    if (self.playerState == PlayerStateRun) {

        player.physicsBody.velocity = CGVectorMake(150, 0);

    }

    if (self.playerState == PlayerStateTouchJump) {

        self.playerState = PlayerStateJump;

        [player removeAllActions];

        

        SKTexture *jumpTexture = [SKTexture textureWithImageNamed:@”player_jump”];

        SKAction *jump = [SKAction animateWithTextures:@[jumpTexture] timePerFrame:1 resize:NO restore:NO];

        [player runAction:jump];

        

        player.physicsBody.velocity = CGVectorMake(200, 500);

    }

}

– (void)didBeginContact:(SKPhysicsContact *)contact

{

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

    

    self.playerState = PlayerStateHold;

    SKTexture *holdTexture = [SKTexture textureWithImageNamed:@”player_hold”];

    SKAction *hold = [SKAction animateWithTextures:@[holdTexture] timePerFrame:1 resize:NO restore:NO];

    SKAction *move = [SKAction moveByX:10 y:0 duration:0];

    [player runAction:[SKAction group:@[hold, move]]];

    player.physicsBody.velocity = CGVectorMake(0, 0);

    

    self.physicsWorld.speed = 0.4;

    

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

    SKAction *up = [SKAction moveToY:150 duration:1.0];

    SKAction *waite = [SKAction waitForDuration:3.0];

    [flag runAction:[SKAction group:@[up, waite]] completion:^{

        [self.restartdelegate restart];

    }];

}

@end

@interface ViewController () <RestartProtocol>

@property (strong, nonatomic) SKView *spriteView;

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

}

– (void)viewDidAppear:(BOOL)animated

{

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

    [self.view addSubview:self.spriteView];

    

    JumpScene *scene = [[JumpScene alloc] initWithSize:self.spriteView.bounds.size];

    scene.restartdelegate = self;

    [self.spriteView presentScene:scene];

}

– (void)restart

{

    JumpScene *scene = [[JumpScene alloc] initWithSize:self.spriteView.bounds.size];

    scene.restartdelegate = self;

    [self.spriteView presentScene:scene transition:[SKTransition doorwayWithDuration:1.0]];

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end