私はいくつかのSpriteKitのことを考えています。私はかなりSpriteKit
に新しいですので、私の技術が悪いかもしれない、私は知らない。ここに私が取り組んでいることがあります:SpriteKit - enumerateChildNodeにより、 "配列が列挙されている間に配列が変更されました"というクラッシュが発生します。
基本的にシールド付きの宇宙船(2D、上から見た)です。いくつかの "シールドセグメント"(左、右、上、下、それぞれがSKShapeNode
です)があり、次に "phaser" node
が境界線からデバイスの中心まで描かれた線です(宇宙船はセンター)。フェイザーがシールドセグメントの1つに当たったときを検出したい。私はcollisionMasksを使ってこれを試しましたが、まったく動作しませんでした。だから私は自分自身の検出方法を試みた。
次に、フェーザーを描く私の方法は奇妙に思えるかもしれません。私はオンラインで検索しましたが、何も見つかりませんでした。ですから、私がフェイザーを描画する方法は、各フレームより少し長いパスを使って、常にphaser node
(直線)のパスを置き換えることです。
これを行い、また、クラッシュへのアプリの原因となる方法です。
incomingPhasers
は、現在、シーン内のすべてのPhaser
のオブジェクトを含む配列です。 Phaser
クラスには、主にというnode
とその他のメタ情報が含まれています。
位相器の進歩は、progress
の属性を少し増やすことによって行われます。最後のフレームが(この方法は、update(_:)
let vector
から呼び出されているように、ラインの描画に使用される変位ベクトルである。
private func advancePhasers(_ delta: TimeInterval) {
for phaser in incomingPhasers where !phaser.targetHit {
// advance progress of phaser
phaser.progress = min(phaser.progress + CGFloat(delta) * phaser.progressRate, 1)
let vector = phaser.origin.vector(toPoint: phaser.target, fraction: phaser.progress)
// create new path
let path = UIBezierPath()
path.move(to: phaser.origin)
path.addLine(to: phaser.origin + vector)
phaser.node.path = path.cgPath
// check collision
let phaserPoint = path.currentPoint
enumerateChildNodes(withName: "shieldSegment", using: { (node, stop) in
if let node = node as? ShieldSegmentNode {
if node.contains(phaserPoint) {
// collision
phaser.targetHit = true
}
}
})
}
}
enumerateChildNodes
Iは多くを追加するときにアプリケーションがクラッシュするので、デルタ時間差であります配列へのフェイザー:
* 'NSGenericException' キャッチされない例外によりにアプリを終了、理由:「*コレクション< __NSArrayM:0x17404c e40>を列挙しながら突然変異させた。 '
私はここで何ができるのか分かりません。シールドセグメントノードを循環させる必要がありますが、これはクラッシュし続けます。
これはスレッドの安全性と関係がありますか?それをスレッドセーフにする必要がありますか?もしそうなら、どうですか?
ありがとうございました!
これ以上の情報やコードが必要な場合は教えてください。私はここにすべてを投稿することはできません、あまりにも多くのコードです。
ええ、何?これらは単に読み込みであり、唯一の書き込み操作は 'phaser.targetHit = true'です。しかし、私がそれを取り除いても、それはクラッシュします。私は見つけようとします。編集:それが空である場合でも、それはクラッシュします。それは変です – Quantm
おそらく別のスレッドで別の場所に変異しているはずです –
ええと、 'enumerateChildNodes'を使う場所は2つあります。しかし、私は別のスレッドでそれらを呼び出すことはありません。それらはすべて 'update(_ :)'の中から呼び出されます。これはメインのキューにありませんか? – Quantm