前回の火のショットがぶつかった際、火花を散らして消えるようにしてみた。
GameScene.swift
//SKPhysicsContactDelegateを追加
class GameScene: SKScene, SKPhysicsContactDelegate {
override func didMoveToView(view: SKView) {
//衝突イベントの為必ず必要
self.physicsWorld.contactDelegate = self
/* 無重力にする */
self.physicsWorld.gravity = CGVectorMake(0,0);
/* Setup your scene here */
let myLabel = SKLabelNode(fontNamed:"Chalkduster")
myLabel.text = "Hello, World!";
myLabel.fontSize = 65;
myLabel.position = CGPoint(x:CGRectGetMidX(self.frame), y:CGRectGetMidY(self.frame));
self.addChild(myLabel)
let sprite = SKSpriteNode(color: UIColor.orangeColor(), size: CGSizeMake(300, 300))
sprite.position = CGPoint(x:700, y:CGRectGetMidY(self.frame))
sprite.lightingBitMask = 1
//衝突イベントには必須
sprite.physicsBody = SKPhysicsBody(rectangleOfSize: sprite.size)
sprite.physicsBody?.categoryBitMask = 0x1 << 0
sprite.physicsBody?.contactTestBitMask = 0x1 << 1
sprite.physicsBody?.dynamic = false
self.addChild(sprite)
}
壁役のブロックを設定する。physicsBodyを設定してやる。
最初はphysicsBodyにサイズを設定し忘れてていつまで経ってもぶつからないから相当悩んだ・・・。なんでまたサイズの設定が要るんだよ・・・。まあ便利な事もあると思うけど
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
/* Called when a touch begins */
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
let firePath = NSBundle.mainBundle().pathForResource("MyParticle", ofType: "sks")
var fire = SKEmitterNode()
fire = NSKeyedUnarchiver.unarchiveObjectWithFile(firePath!) as SKEmitterNode
fire.particleSize = CGSize(width: 70, height: 70)
fire.position = location
//衝突イベントに必須
fire.physicsBody = SKPhysicsBody(rectangleOfSize: fire.particleSize)
fire.physicsBody?.contactTestBitMask = 0x1 << 0
fire.physicsBody?.categoryBitMask = 0x1 << 1
var line = CGPathCreateMutable()
CGPathMoveToPoint(line, nil, location.x, location.y)
CGPathAddLineToPoint(line, nil, location.x + 1000, location.y)
let follow = SKAction.moveByX(-1000, y: -350, duration: 3.5)
let follow2 = SKAction.moveByX(1500, y: 0, duration: 3.5)
fire.particleAction = follow
fire.runAction(follow2)
self.addChild(fire)
}
炎のショットも壁役と同じようにphysicsBodyを設定してやる。
//衝突時のイベント
func didBeginContact(contact: SKPhysicsContact) {
let firePath = NSBundle.mainBundle().pathForResource("Spark", ofType: "sks")
var fire = SKEmitterNode()
fire = NSKeyedUnarchiver.unarchiveObjectWithFile(firePath!) as SKEmitterNode
fire.position.x = contact.contactPoint.x
fire.position.y = contact.contactPoint.y + 30
fire.numParticlesToEmit = 80
self.addChild(fire)
//このメソッドを上書きすると衝突したイベントの衝突後の処理を書かねばならない
if(contact.bodyA.categoryBitMask > contact.bodyB.categoryBitMask){
contact.bodyA.node?.removeFromParent()
} else {
contact.bodyB.node?.removeFromParent()
}
}
衝突時に火花が飛ぶように演出するキモ。これを実行したいので、SKPhysicsContactDelegateプロトコルを実装した。ぶつかった後は炎は消すようにする。
ちなみに、壁役のブロックの設定で
sprite.physicsBody?.dynamic = false
の部分をコメントアウトすると、ショットとの衝突の勢いで壁が動いていきます。
ついでに火に重みをつけてやるとショットの勢いを演出出来ます。
fire.physicsBody?.mass = 20