[iOS 7] SpriteKitで衝突したときにパーティクルを発生させてみる | アドカレ2013 : SP #9
今回はSpriteKitで、タップしたポイントにブロックを配置して落下させ、他のブロックや地面に接触したときに星のパーティクルを発生させてみます。
実装
まず、パーティクルを作成します。
今回使用する星の画像は画像はこちら。真っ白なので見えにくいですが。。
star.png
星の画像をプロジェクトに取り込んだら、次にsksファイルを作成してパーティクルの細かい設定をします。
Star.sks
パーティクルの素材ができたので、コーディングします。
MyScene.m
#import "MyScene.h"
const uint32_t GROUND = 0x1 << 1;
const uint32_t BLOCK = 0x1 << 2;
@interface MyScene ()
@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]
あまり長いコードではないので細かい説明は省きますが、コンタクト処理周りの手順は以下です。
- physicsBodyのcategoryBitMaskとcontactTestBitMaskを設定します。(L3〜4, L31〜32, L44〜45)
- SKPhysicsContactDelegateを設定します。(L6, L15)
- didBeginContact:contactメソッドを実装します。(L68〜L72)
動作確認
コンタクトしたポイントに星が発生しました。
でも、ミニゲームっぽくなるにはまだまだ先が長そうです。
今回はここまで。
ではでは。