名作マリオに学びたい、その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