アヒルの子供をみつけて、ぞろぞろ親子で歩いて遊ぶ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