7

私はまだ iOS で SpriteKit の学習に取り組んでおり、多くの読書と実験を行っています。座標、フレーム、および子ノードに関して見つけた*他の何かに混乱しています。

次のコード スニペットを考えてみましょう。このコードでは、デバッグ目的で宇宙船のスプライトの周りに緑色のボックスを描画しようとしています。

func addSpaceship()
{
    let spaceship = SKSpriteNode.init(imageNamed: "rocketship.png")
    spaceship.name = "spaceship"

    // VERSION 1
    spaceship.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))

    let debugFrame = SKShapeNode(rect: spaceship.frame)

    debugFrame.strokeColor = SKColor.greenColor()
    spaceship.addChild(debugFrame)

    // VERSION 2
   //       spaceship.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))

    spaceship.setScale(0.50)


    self.addChild(spaceship)
}

上記の「VERSION 1」とマークされた行で宇宙船スプライトのセットを追加すると、次のようになります。

バージョン 1

これは明らかに間違っています。しかし、上記の「VERSION 1」とマークされた行をコメントアウト、代わりに「VERSION 2」とマークされた行を使用すると、必要なものが得られます。

バージョン 2

バージョン 1 とバージョン 2 とマークされた行の実際のコードは同じであることに注意してください: spaceship.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))

では、宇宙船のスプライトの位置を設定することが重要なのはなぜでしょうか?

私の考えでは、宇宙船スプライトの位置は、debugFrame の配置とは無関係です。なぜなら、debugFrame は宇宙船スプライトの子であり、その座標は宇宙船スプライトのフレームに対して相対的でなければならないからです。

ありがとうWM

※昨日の質問と少し関係があります。

iOS の SpriteKit で、テクスチャ付きのスプライトをスケーリングすると、正しくないフレームが生成されますか?

しかし、a) 私は今それを理解しています.b) これは十分に異なっているので、独自の質問に値します.

アップデート:

うーん - 以下のアイデアに感謝しますが、私はまだそれを理解していません.これが役立つかもしれません.

関連する位置とフレームを出力するようにコードを変更しました。

func addSpaceship()
{
    let spaceship = SKSpriteNode.init(imageNamed: "rocketship.png")
    spaceship.name = "spaceship"
    println("Spaceship0 Pos \(spaceship.position) Frame = \(spaceship.frame)")

    // VERSION 1 (WRONG)
    spaceship.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
    println("Spaceship1 Pos \(spaceship.position) Frame = \(spaceship.frame)")

    let debugFrame = SKShapeNode(rect: spaceship.frame)
    println("DEBUG Pos \(debugFrame.position) Frame = \(debugFrame.frame)")

    debugFrame.strokeColor = SKColor.greenColor()
    spaceship.addChild(debugFrame)

    // VERSION 2 (RIGHT)
//      spaceship.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
//      println("Spaceship2 Pos \(spaceship.position) Frame = \(spaceship.frame)")

    spaceship.setScale(0.50)


    self.addChild(spaceship)
}

次に、両方の方法で実行すると、これらの結果が得られました。バージョン 2 は理解できたので、そこから始めましょう。

「VERSION 2 (RIGHT)」コードで実行すると、次のようになりました。

Spaceship0 Pos (0.0,0.0) Frame = (-159.0,-300.0,318.0,600.0)
DEBUG Pos (0.0,0.0) Frame = (-159.5,-300.5,319.0,601.0)
Spaceship2 Pos (384.0,512.0) Frame = (225.0,212.0,318.0,600.0)

デフォルトでは、宇宙船ノードは画面の左下 (Spaceship0) の位置から開始します。そのフレームは、画面の左下に設定されているアンカー ポイント (中心) によっても表現されるため、フレーム四角形の原点には負の数が使用されます。

次に、デバッグ フレームが作成され、その位置はデフォルトで 0 に設定され、そのフレームは宇宙船と同じに設定されます。

コード (Spaceship2) は、宇宙船ノードをビューの座標 (384.0,512.0) 内の位置に移動し、そのフレームの原点は、古い原点に新しい位置を追加することによって移動されます (つまり、384 + -159 = 225)。

すべては順調です。

残念ながら、私はまだバージョン 1 を取得していません。

「VERSION 1 (WRONG)」コードで実行すると、

Spaceship0 Pos (0.0,0.0) Frame = (-159.0,-300.0,318.0,600.0)
Spaceship1 Pos (384.0,512.0) Frame = (225.0,212.0,318.0,600.0)
DEBUG Pos (0.0,0.0) Frame = (0.0,0.0,543.5,812.5)

上記のように、宇宙船ノードはデフォルトで、画面の左下 (Spaceship0) の位置で開始します。そのフレームは、画面の左下に設定されているアンカー ポイント (中心) によっても表現されるため、フレーム四角形の原点には負の数が使用されます。

次に、コード (Spaceship1) は宇宙船ノードをビューの座標 (384.0,512.0) 内の位置に移動し、そのフレームの原点は古い原点に新しい位置を追加することによって移動されます (つまり、384 + -159 = 225)。

次に、デフォルトで位置が 0、0 に設定されたデバッグ フレームが作成され、そのフレームは奇妙な幅 (543.5) と奇妙な高さ (812.5) に設定されます。私は spaceship.frame で debugFrame.frame を初期化しているので (デフォルトのイニシャライザがそうしていると思います)、新しい debugFrame.frame は宇宙船のフレームと同じであると期待しますが、そうではありません! デバッグ フレームの幅と高さの値は、実際の幅と高さを宇宙船ノード フレームの原点 (543.5 = 225 + 318.5) に加算したものと思われます。しかし、そうであれば、なぜ t のフレーム rect の原点はまだ 0, 0 であり、同じ追加 (225.0 + 0 = 225.0) ではないのですか???

理解できません。

4

3 に答える 3

1

あなたの「わからない」への対応です。コードは問題ありませんが、論理的な問題があります。「フレーム」は、親座標に対して相対的にカウントされます。宇宙船の親とデバッグ ウィンドウの親がコードで異なることに注意してください。

問題を解決するには、次の 2 つの方法があります。

  1. デバッグ ウィンドウにゼロ オフセットを追加し、宇宙船を親として使用します。これの利点は、デバッグ ウィンドウが移動し、宇宙船に合わせてスケーリングされることです。 let rectDebug = CGRectMake( 0, 0, spaceship.frame.size.width, spaceship.frame.size.height) let debugFrame = SKShapeNode(rect:rectDebug) spaceship.addChild(debugFrame)
  2. 宇宙船の「フレーム」座標を含むデバッグ ウィンドウを、宇宙船の親 (「自己」) に追加します。これの欠点は、宇宙船にアタッチされないため、コード内でデバッグ ウィンドウを自分で移動、スケーリングする必要があることです。 let debugFrame = SKShapeNode(rect:spaceship.frame) self.addChild(debugFrame)

どちらのソリューションも広く使用されています。あなたのケースであなたにとってより良いものを選ぶべきです。他に 3 つの問題が発生する可能性があります。

1. コードにコード エラーがある可能性があります。xcode の構文チェックを行わずに、これらを Web ウィンドウに直接入力しました。

2.2 つのオブジェクトのアンカー ポイントが異なる可能性があります。そのため、これにはコードのアライメントが必要になる場合があります。

3. オブジェクトの zPosition も考慮する必要があるため、これらのオブジェクトは他のオブジェクトの下に隠れません。

解決しようとしている問題に応じて、おそらく showPhysics が役立ちます。

    skView.showsFPS = YES;
    skView.showsNodeCount = YES;
    skView.showsPhysics = YES;
于 2015-07-15T08:17:15.490 に答える
0

これは、あなたが言及した他の質問とほぼ同じ問題です。とframeを含むプロパティです。どちらも祖先ノードのスケーリングの対象となります。https://developer.apple.com/library/ios/documentation/GraphicsAnimation/Conceptual/SpriteKit_PG/Nodes/Nodes.html#//apple_ref/doc/uidの「ノードはそのプロパティの多くをその子孫に適用する」セクションを読んでください。 /TP40013043-CH3-SW13positionsize

繰り返しますが、ノードにスケーリングを適用したり、階層を完全に構築する前にノードを移動したりしないでください。ただし、特別な効果や奇妙な効果が必要な場合を除きます。

于 2014-12-31T08:31:20.897 に答える