ダーヤス.com プレミアム

ダーヤス.comにようこそ。プレミアムな情報で、ワークライフバランスの充実を図りませんか。

【Swift】SpriteKitで大量にノードを表示させてたら重くなった時の対処法

   

SpriteKitで大量にノードを表示させてたら重くなった時の対処法

SpriteKitで大量にノードを表示させてたら重くなった時の対処法

とりあえずまたgameKitでアプリ作ろうと思って、SpriteKitでのプログラムを再開。
やっぱアニメーションの処理が本当に楽ですわ。

重力処理が一瞬でできるので、特に落ちモノ系なんかはこれ使うといろいろ幅が広がりそうな気がします。
ということで、上からボールというか風船みたいのが次々に降ってきて下の棒というか一応針なんですけど、そこに当たると割れて点数が入るというゲームを作ってみました。

で、ステージが進むごとに表示される風船数が増えていくのですが、当然ながらたくさん表示されると処理が重くなって昔のファミコンみたいにカクカクした感じになってしまう。
まあしょうがないかなと思っていたら、ステージが進んでまた画面にノード数が少なくなった時でもまだ重いまま。
あれこれおかしい、ノードの出現周期を減らしたほうがいいかな、とか一回考えて朝起きた時、「ああ、一回表示されたノードが画面下に落ちて見えなくなった時に、ノードを削除する処理を入れてなかったな」と思いました。

つまり画面から見えなくなってボールがなくなったと思っても、実際は画面外で延々と残っているわけで、ノードを次々に発生させていけば、増える一方。不要になったノードは消す処理が必要です。

というわけでこう言う処理を入れました。

let under = SKSpriteNode(color: UIColor(red: 1, green: 1, blue: 1, alpha: 0), size: CGSize(width: UIScreen.mainScreen().bounds.width, height: 10))

under.position = CGPoint(x: self.size.width*0.5, y: 20)
let physicsBodyUnder = SKPhysicsBody(rectangleOfSize: under.frame.size)
physicsBodyUnder.dynamic = false
physicsBodyUnder.contactTestBitMask = 3
under.physicsBody = physicsBodyUnder
under.name = "under"
self.addChild(under)

まずunderという名前で、見えないノードを作成。
これを画面の水平はばいっぱいにして、縦方向はまあ10ピクセルくらいの長方形。

ノード同士がぶつかった時の処理を書くメソッドの
func didBeginContact(contact: SKPhysicsContact) {}内に、風船と上記見えないunderがぶつかった時の処理を書く。

if nodeA!.name == "under" {
                    nodeB?.removeFromParent()

二つのノードがぶつかった時、ノードAの名前がunderだったらノードB(風船)を削除
コード書いている内になんとなくわかったのですが、ぶつかった時にどっちがノードAでどっちがノードBになるかって、座標が小さい方がノードがAになるような気がしてるんですが、間違いだろうか。。。?
今の所その理解でなんとなくあってるような気がするのですが。

これを入れたら処理が軽くなりました。

ちなみに、見えないノードの表示y座標を20にしてますが、どうせ見えないなら画面下の0にしてもいいのかなと思ってそうしてみたら、どうもそれだとぶつかる処理が行われない。
まあ重力が発生する場が画面サイズ内だけなので、ちょうどギリギリのところで両者がぶつからずに風船だけが画面端で残ってることになってるんだろうなあ。
というわけで、ちょっとだけ画面内に見えてるようにしてます。
alphaが0だから実質見えてないのですが、風船が何もないところで消えるような見た目になってしまうので、ちょっとカッコ悪いです。

 - アプリ開発