iPhoneサンタとプレゼント

サンタが空から降ってくるプレゼントをあつめる。といった簡単なiPhoneゲームのサンプルコードを描いてみます。


今回使った画像


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

サンプルコード

#import “ViewController.h”

#import <SpriteKit/SpriteKit.h>

typedef enum : int8_t {

    MyCategoryTypeSanta = 0x1 << 1,

    MyCategoryTypePresent = 0x1 << 2,

    MyCategoryTypeOther = 0x1 << 3,

} CategoryType;

typedef enum : int {

    SantaStateStop = 0,

    SantaStateWalk = 1,

    SantaStatePick = 2,

} SantaState;

@interface SeekScene : SKScene <SKPhysicsContactDelegate>

@property BOOL contentCreated;

@property int status;

@property CGPoint touchPoint;

@property float presentLastTime;

@end

@implementation SeekScene

– (void)didMoveToView:(SKView *)view

{

    if (!self.contentCreated) {

        [self createSceneContents];

        self.physicsWorld.contactDelegate = self;

        self.contentCreated = YES;

    }

}

– (void)createSceneContents

{

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

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

    [self addChild:ground];

    

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

    ground.physicsBody.dynamic = NO;

    ground.physicsBody.categoryBitMask = MyCategoryTypeOther;

    

    [self createSanta];

}

– (void)createSanta

{

    self.status = SantaStateStop;

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

    santa.name = @”santa”;

    santa.position = CGPointMake(CGRectGetMidX(self.frame), 80) ;

    [self addChild:santa];

    

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

    santa.physicsBody.allowsRotation = NO;

    santa.physicsBody.categoryBitMask = MyCategoryTypeSanta;

    santa.physicsBody.contactTestBitMask = MyCategoryTypePresent;

}

– (void)update:(NSTimeInterval)currentTime

{

    if (self.presentLastTime == 0) {

        self.presentLastTime = currentTime;

    }

    

    float t = currentTime – self.presentLastTime;

    if (t > 4) {

        self.presentLastTime = 0;

        [self createPresent];

    }

    

    [self updateSanta];

}

– (void)createPresent

{

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

    present.position = CGPointMake(arc4random() % 300 + 100, CGRectGetMaxY(self.frame) – 50);

    [self addChild:present];

    

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

    present.physicsBody.categoryBitMask = MyCategoryTypePresent;

}

– (void)updateSanta

{

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

    if (self.status == SantaStateWalk) {

        float dx = self.touchPoint.x – santa.position.x;

        float vx = dx / fabs(dx);

        santa.physicsBody.velocity = CGVectorMake(vx * 50.0, 0);

        

        if (vx > 0 && santa.size.width > 0) {

            santa.size = CGSizeMake(santa.size.width * (-1.0), santa.size.height);

        } else if (vx <= 0 && santa.size.width < 0) {

            santa.size = CGSizeMake(santa.size.width * (-1.0), santa.size.height);

        }

        

        if (CGRectContainsPoint(santa.frame, self.touchPoint)) {

            self.status = SantaStateStop;

            [santa removeActionForKey:@”walk”];

            santa.texture = [SKTexture textureWithImageNamed:@”santa”];

        }

    }

}

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

{

    CGPoint p = [[touches anyObject] locationInNode:self];

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

    

    self.touchPoint = p;

    

    if (!CGRectContainsPoint(santa.frame, p) && self.status != SantaStateWalk) {

        self.status = SantaStateWalk;

        SKAction *walk = [SKAction animateWithTextures:@[[SKTexture textureWithImageNamed:@”santa_walk01″],[SKTexture textureWithImageNamed:@”santa_walk02″]] timePerFrame:0.5];

        [santa runAction:[SKAction repeatActionForever:walk] withKey:@”walk”];

    }

}

– (void)didBeginContact:(SKPhysicsContact *)contact

{

    SKNode *present;

    SKSpriteNode *santa;

    if (contact.bodyA.categoryBitMask == MyCategoryTypePresent

        && contact.bodyB.categoryBitMask == MyCategoryTypeSanta) {

        present = contact.bodyA.node;

        santa = (SKSpriteNode*)contact.bodyB.node;

    } else if (contact.bodyB.categoryBitMask == MyCategoryTypePresent

               && contact.bodyA.categoryBitMask == MyCategoryTypeSanta){

        present = contact.bodyB.node;

        santa = (SKSpriteNode*)contact.bodyA.node;

    }

    

    if (present && santa) {

        self.status = SantaStatePick;

        self.touchPoint = santa.position;

        [santa removeActionForKey:@”walk”];

        santa.texture = [SKTexture textureWithImageNamed:@”santa_pickup”];

        

        present.physicsBody.affectedByGravity = NO;

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

        

        SKAction *up = [SKAction moveByX:0 y:30 duration:0.2];

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

        [present runAction:[SKAction group:@[up, fade]] completion:^{

            self.status = SantaStateStop;

            santa.texture = [SKTexture textureWithImageNamed:@”santa”];

            [present removeFromParent];

        }];

    }

    

}

@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 = [[SeekScene alloc] initWithSize:spriteView.frame.size];

    [spriteView presentScene:scene];

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end