SpriteKitの使い方を解説します。
SpriteKit 入門 ④で敵を表示して衝突判定を実装することができました。今回は、一度に発射する弾の数を増やしてみようと思います。
(環境:Xcode12.4 Swift5.3)
repeatShoots
メソッドの修正
前回はMySceneクラスのプロパティとして弾用のSKShapeNodeを用意していました。しかし特にクラスのプロパティとして宣言しておく必要もなかったため、これを削除しておきましょう。
次に、repeatShoots
メソッドを修正していきます。前回は一つだけSKShapeNodeのインスタンスを作成してself.addChild(shoot)
で画面に表示させていましたが、この処理をfor文を使って繰り返し実行するように変更します。また、弾の発射方向も少しずつずらすようにしましょう。以下にコードを示します。
MyScene.swift
//自機から発射する弾
func repeatShoots(){
for i in -1...1{
let shoot:SKShapeNode = SKShapeNode.init(rectOf: CGSize.init(width: 30, height: 30), cornerRadius: 3)
shoot.name = "shoot"
shoot.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 30, height: 30))
shoot.physicsBody?.affectedByGravity = false
shoot.physicsBody?.categoryBitMask = 0b0001
shoot.physicsBody?.collisionBitMask = 0b0000
shoot.physicsBody?.contactTestBitMask = 0b0001
shoot.position = image.position
shoot.fillColor = SKColor.red
shoot.lineWidth = 3
shoot.strokeColor = SKColor.white
shoot.run(SKAction.repeatForever(SKAction.rotate(byAngle: CGFloat(Double.pi), duration: 1)))
let p:CGFloat = CGFloat(i*100)
let vector1: CGVector = CGVector(dx: p, dy: self.size.height)
shoot.run(SKAction.sequence([SKAction.move(by: vector1, duration: 3),SKAction.removeFromParent()]))
self.addChild(shoot)
}
}
衝突判定の修正
発射する弾を増やすことはできましたが、このままだと発射した瞬間の弾同士での衝突が発生してしまいます。弾同士の衝突は無視したいので、if文の条件をそうなるように修正していきます。(※現時点では敵同士での衝突は考慮していません。)
MyScene.swift
func didBegin(_ contact: SKPhysicsContact) {
let t1 = contact.bodyA.categoryBitMask == self.enemy?.physicsBody!.categoryBitMask
let t2 = contact.bodyB.categoryBitMask == self.enemy?.physicsBody!.categoryBitMask
let notEmpty = contact.bodyA.node != nil && contact.bodyB.node != nil
if (t1 || t2) && notEmpty{
if contact.bodyA.node!.name == "shoot" && contact.bodyB.node!.name != "shoot" {
self.removeChildren(in: [contact.bodyA.node!,contact.bodyB.node!])
}else if contact.bodyB.node?.name == "shoot" && contact.bodyA.node!.name != "shoot" {
self.removeChildren(in: [contact.bodyA.node!,contact.bodyB.node!])
}
}
}