[iOS 7] SpriteKitで衝突したときにパーティクルを発生させてみる | アドカレ2013 : SP #9

2013.12.09

今回はSpriteKitで、タップしたポイントにブロックを配置して落下させ、他のブロックや地面に接触したときに星のパーティクルを発生させてみます。

実装

まず、パーティクルを作成します。
今回使用する星の画像は画像はこちら。真っ白なので見えにくいですが。。

star.png

ios7-spritekit-particle-contact-star-001

星の画像をプロジェクトに取り込んだら、次にsksファイルを作成してパーティクルの細かい設定をします。

Star.sks

ios7-spritekit-particle-contact-star-002


パーティクルの素材ができたので、コーディングします。

MyScene.m

#import "MyScene.h"

const uint32_t GROUND = 0x1 << 1; const uint32_t BLOCK = 0x1 << 2; @interface MyScene () @end

@implementation MyScene

-(id)initWithSize:(CGSize)size { if (self = [super initWithSize:size]) { // physicsWorldのデリゲートにselfを設定します。 self.physicsWorld.contactDelegate = self;

[self addGround]; } return self; }

-(void)addGround { // 地面を配置します。 SKSpriteNode *ground = [SKSpriteNode spriteNodeWithColor:[UIColor blueColor] size:CGSizeMake(200.0f,50.0f)]; ground.name = @"ground"; ground.position = CGPointMake(CGRectGetMidX(self.frame), 100.0f); ground.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:ground.size]; ground.physicsBody.dynamic = NO; ground.physicsBody.categoryBitMask = GROUND; ground.physicsBody.contactTestBitMask = BLOCK; [self addChild:ground]; }

- (void)addBlock:(CGPoint)location { // ブロックを配置します。 SKSpriteNode *block = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(50.0f, 50.0f)]; block.name = @"block"; block.position = location; block.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:block.size]; block.physicsBody.categoryBitMask = BLOCK; block.physicsBody.contactTestBitMask = GROUND | BLOCK; [self addChild:block]; }

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { // タッチしたポイントにブロックを発生させます。 CGPoint location = [touches.anyObject locationInNode:self]; [self addBlock:location]; }

#pragma mark - physics -(void)didSimulatePhysics { // ブロックが画面外に落ちたら削除します。 [self enumerateChildNodesWithName:@"block" usingBlock:^(SKNode *node, BOOL *stop) { if (node.position.y < 0){ [node removeFromParent]; } }]; } #pragma mark - contact - (void)didBeginContact:(SKPhysicsContact *)contact { // コンタクトしたポイントに星を表示します。 [self showStar:contact.contactPoint]; } - (void)showStar:(CGPoint)location { // 星を表示します。 SKEmitterNode *emitter = [NSKeyedUnarchiver unarchiveObjectWithFile: [[NSBundle mainBundle] pathForResource:@"Star" ofType:@"sks"]]; emitter.position = location; [self addChild:emitter]; // 1秒後に削除します。 SKAction *seq = [SKAction sequence:@[[SKAction waitForDuration:1.0f], [SKAction removeFromParent]]]; [emitter runAction:seq]; } @end [/c]

あまり長いコードではないので細かい説明は省きますが、コンタクト処理周りの手順は以下です。

  1. physicsBodyのcategoryBitMaskとcontactTestBitMaskを設定します。(L3〜4, L31〜32, L44〜45)
  2. SKPhysicsContactDelegateを設定します。(L6, L15)
  3. didBeginContact:contactメソッドを実装します。(L68〜L72)

動作確認

ios7-spritekit-particle-contact-star-003

コンタクトしたポイントに星が発生しました。
でも、ミニゲームっぽくなるにはまだまだ先が長そうです。

今回はここまで。
ではでは。