iPhoneアヒル

アヒルの子供をみつけて、ぞろぞろ親子で歩いて遊ぶiPhoneゲームのサンプルコードを描いてみます。


今回の画像

※アヒル画像は「iPhone脱出ゲームクトゥルフルーム」の作者さんから頂きました。ありがとうございます。

サンプルを動画で確認

サンプルコード

#import “ViewController.h”

#import <SpriteKit/SpriteKit.h>

@interface DuckScene : SKScene <SKPhysicsContactDelegate>

@property BOOL contentCreated;

@property CGPoint touched;

@property (nonatomic, weak) SKNode *lastConnect;

@end

static const uint32_t duckCategory = 0x1 << 1;

static const uint32_t duckChildCategory = 0x2 << 2;

@implementation DuckScene

– (void)didMoveToView:(SKView *)view

{

    self.backgroundColor = [UIColor greenColor];

    self.physicsWorld.gravity = CGVectorMake(0, 0);

    self.physicsWorld.contactDelegate = self;

    [self createDuck];

    [self createChildren];

}

– (void)createDuck

{

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

    duck.name = @”duck”;

    duck.size = CGSizeMake(60, 60);

    duck.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));

    [self addChild:duck];

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

    duck.physicsBody.categoryBitMask = duckCategory;

    duck.physicsBody.collisionBitMask = duckChildCategory;

    self.lastConnect = duck;

}

– (void)createChildren

{

    CGPoint points[] = {CGPointMake(50, 100), CGPointMake(150, 280), CGPointMake(280, 50)};

    for (int i=0; i<3; i++) {

        [self createChild:points[i]];

    }

}

– (void)createChild:(CGPoint)p

{

    SKSpriteNode *duckChild = [SKSpriteNode spriteNodeWithImageNamed:@”duckChild1″];

    duckChild.name = @”duckChild”;

    duckChild.size = CGSizeMake(40, 40);

    duckChild.position = p;

    [self addChild:duckChild];

    

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

    duckChild.physicsBody.categoryBitMask = duckChildCategory;

    duckChild.physicsBody.contactTestBitMask = duckCategory;

    duckChild.physicsBody.linearDamping = 1.0;

}

– (void)didBeginContact:(SKPhysicsContact *)contact

{

    SKSpriteNode *duckChildNode;

    if (contact.bodyA.categoryBitMask == duckChildCategory) {

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

    } else if (contact.bodyB.categoryBitMask == duckChildCategory){

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

    }

    

    if (duckChildNode) {

        duckChildNode.texture = [SKTexture textureWithImageNamed:@”duckChild0″];

        duckChildNode.physicsBody.categoryBitMask = 0x0;

        duckChildNode.physicsBody.collisionBitMask = duckChildCategory | duckCategory;

        SKPhysicsJointLimit *joint = [SKPhysicsJointLimit jointWithBodyA:self.lastConnect.physicsBody bodyB:duckChildNode.physicsBody anchorA:self.lastConnect.position anchorB:duckChildNode.position];

        joint.maxLength = 50;

        [self.physicsWorld addJoint:joint];

        

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

        [duckChildNode runAction:move completion:^{

            [duckChildNode runAction:[SKAction repeatActionForever:[self walkAction]]];

        }];

        

        self.lastConnect = duckChildNode;

    }

}

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

{

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

    self.touched = p;

}

– (void)update:(NSTimeInterval)currentTime

{

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

    if (!CGPointEqualToPoint(self.touched, CGPointZero)

        && !CGRectContainsPoint(duck.frame, self.touched)) {

        

        float dx = self.touched.x – duck.position.x;

        float dy = self.touched.y – duck.position.y;

        float val = hypotf(dx, dy);

        if (val > 0) {

            duck.physicsBody.velocity = CGVectorMake(50 * dx/val, 50 * dy/val);

        }

        

        if (![duck hasActions]) {

            [duck runAction:[SKAction repeatActionForever:[self walkAction]] withKey:@”walk”];

        }

        

    } else {

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

        [duck removeActionForKey:@”walk”];

        SKAction *rotate = [SKAction rotateToAngle:0 duration:0.5];

        [duck runAction:rotate];

    }

}

– (void)didSimulatePhysics

{

    [self enumerateChildNodesWithName:@”//*” usingBlock:^(SKNode *node, BOOL *stop) {

        if (node.physicsBody.velocity.dx < 0) {

            node.xScale = 1.0;

        } else {

            node.xScale = –1.0;

        }

    }];

}

– (SKAction*)walkAction

{

    SKAction *rotateA = [SKAction rotateToAngle:0.2 duration:0.5];

    SKAction *rotateB = [SKAction rotateToAngle:-0.2 duration:0.5];

    SKAction *walk = [SKAction sequence:@[rotateA, rotateB]];

    return walk;

}

@end

@interface ViewController ()

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    SKView *spriteView = [[SKView alloc] initWithFrame:CGRectMake(0,0, 568, 320)];

    [self.view addSubview:spriteView];

    

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

    [spriteView presentScene:scene];

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end