iPhoneめざせマリオ

今回は、wii U買った記念(子供がこんなに喜ぶなんて、マリオってすごい。)です。大好きなマリオみたいなゲーム作れるか、チャレンジ。まずは、はじめの一歩、ジャンプでハタをとると点数を加算するような感じでiPhoneのサンプルコードを描いてみます。

今回使った画像はこれ


サンプルを動かしてみた動画

サンプルコード

#import “ViewController.h”

#import <SpriteKit/SpriteKit.h>

typedef enum int8_t {

    Ready = 1,

    Runnning = 2,

    Jump = 3,

} GameState;

@interface RunScene : SKScene <SKPhysicsContactDelegate>

@property BOOL contentCreated;

@property int gameState;

@end

@implementation RunScene

– (void)didMoveToView:(SKView *)view

{

    if (!self.contentCreated) {

        [self createSceneContents];

        self.contentCreated = YES;

        self.physicsWorld.contactDelegate = self;

    }

}

– (void)createSceneContents

{

    self.gameState = Ready;

    self.backgroundColor = [UIColor colorWithRed:0.6 green:0.8 blue:1.0 alpha:1.0];

    [self createRoad];

    [self createRunner];

    [self createFlag];

    [self createScore];

}

– (void)createRoad

{

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

    road.position = CGPointMake(CGRectGetMidX(self.frame), 5);

    [self addChild:road];

    

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

    road.physicsBody.dynamic = NO;

    road.physicsBody.categoryBitMask = 0x1 << 1;

}

– (void)createRunner

{

    SKSpriteNode *runner = [SKSpriteNode spriteNodeWithImageNamed:@”runner_run02″];

    runner.name = @”runner”;

    runner.position = CGPointMake(CGRectGetMidX(self.frame), runner.size.height * 0.5 + 10);

    [self addChild:runner];

    

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

    runner.physicsBody.allowsRotation = NO;

    runner.physicsBody.categoryBitMask = 0x1 << 2;

    runner.physicsBody.collisionBitMask = 0x1 << 1;

}

– (void)createFlag

{

    float x = arc4random() % (int)(self.frame.size.width * 0.7) + self.frame.size.width * 0.15;

    float y = arc4random() % 50 + CGRectGetMidY(self.frame);

    

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

    flag.position = CGPointMake(x, y);

    [self addChild:flag];

    

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

    flag.physicsBody.dynamic = NO;

    flag.physicsBody.categoryBitMask = 0x1 << 3;

    flag.physicsBody.contactTestBitMask = 0x1 << 2;

}

– (void)createScore

{

    SKLabelNode *score = [SKLabelNode node];

    score.name = @”score”;

    score.text = @”0000″;

    score.position = CGPointMake(50, CGRectGetMaxY(self.frame) – 50);

    [self addChild:score];

}

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

{

    SKSpriteNode *runner = (SKSpriteNode*)[self childNodeWithName:@”runner”];

    

    if (self.gameState == Ready) {

        self.gameState = Runnning;

        

        SKTexture *runA = [SKTexture textureWithImageNamed:@”runner_run03″];

        SKTexture *runB = [SKTexture textureWithImageNamed:@”runner_run01″];

        SKTexture *runC = [SKTexture textureWithImageNamed:@”runner_run02″];

        SKAction *running = [SKAction animateWithTextures:@[runA, runB, runC] timePerFrame:0.2];

        

        [runner runAction:[SKAction repeatActionForever:running] withKey:@”running”];

    } else if (self.gameState == Runnning) {

        self.gameState = Jump;

        [runner removeAllActions];

        

        runner.texture = [SKTexture textureWithImageNamed:@”ruuner_jump”];

        [runner.physicsBody applyImpulse:CGVectorMake(10, 80)];

    }

}

– (void)update:(NSTimeInterval)currentTime

{

    SKSpriteNode *runner = (SKSpriteNode*)[self childNodeWithName:@”runner”];

    if (self.gameState == Runnning) {

        runner.physicsBody.velocity = CGVectorMake(120, 0);

    } else if (self.gameState == Jump && runner.position.y < 40 && runner.physicsBody.velocity.dy < 0) {

        self.gameState = Ready;

        runner.texture = [SKTexture textureWithImageNamed:@”runner_run02″];

    }

}

– (void)didSimulatePhysics

{

    SKSpriteNode *runner = (SKSpriteNode*)[self childNodeWithName:@”runner”];

    if (runner.position.x > CGRectGetMaxX(self.frame)) {

        runner.position = CGPointMake(-25, runner.position.y);

    }

}

– (void)didBeginContact:(SKPhysicsContact *)contact

{

    SKNode *flag;

    if (contact.bodyA.categoryBitMask == 0x1 << 3) {

        flag = contact.bodyA.node;

    } else {

        flag = contact.bodyB.node;

    }

    

    if (flag) {

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

        

        SKAction *zoom = [SKAction scaleTo:1.5 duration:0.5];

        SKAction *fade = [SKAction fadeAlphaTo:0 duration:1.0];

        SKAction *move = [SKAction moveTo:score.position duration:0.5];

        [flag runAction:[SKAction group:@[zoom, fade, move]] completion:^{

            [flag removeFromParent];

            [self createFlag];

        }];

        score.text = [NSString stringWithFormat:@”%04d”, [score.text intValue] + 1];

    }

}

@end

@interface ViewController ()

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

}

– (void)viewDidAppear:(BOOL)animated

{

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

    [self.view addSubview:spriteView];

    

    SKScene *scene = [[RunScene alloc] initWithSize:spriteView.frame.size];

    [spriteView presentScene:scene];

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end