36

SKNodeメソッドがどのように機能しconvertPoint:fromNode:ているかについて少し混乱しconvertPoint:ToNode:ています。ドキュメントを見てきましたが、それらが何をしているのかは明らかではありません。たとえば、これ (下の図を参照) を使用して行った小さなテストですconvertPoint:fromNode:。黒い領域はSKScene背景、青い領域は のSKSpriteNodeSKScene、赤い領域はSKSpriteNode青いスプライトの別の親です。両方のスプライトのアンカー ポイントは、小さな緑色の点で示されています。私がやりたかったのは、次のコードを使用して、赤いスプライトのシーン位置を取得することでした。

CGPoint positionInScene = [self convertPoint:[self position] 
                                    fromNode:[self redSprite]];

これからの結果は

positionInScene = [105, 205]

これは、シーン空間の赤い四角の原点になるので、私が期待したものです。私が混乱しているのは、引数です。私が推測できることから:

[SKNode_A convertPoint: CGPoint_B toNode: SKScene_C]
  • SKNode_A = 変換先のノード座標空間 ...
  • CGPoint_B = 変換するポイント ([自己位置] が上にある理由がわからない)
  • SKNode_C = 変換元のノード座標空間 ...

これを最初に試した[self convertPoint:[redSprite position] fromNode:redSprite]のは、赤いスプライトの原点をシーンに変換したかったからです。頭を丸くするのは少し不格好に思えます。誰かがこれとその友人の両方に少し光と論理を投げかけることができれば、convertPoint:toNode:それは非常に高く評価されます.

ここに画像の説明を入力

4

4 に答える 4

50

- (CGPoint)convertPoint:(CGPoint)point fromNode:(SKNode *)node

これは基本的に、別のノードの座標系で表されたを呼び出し元 (自己) の座標系に変換するということです。重要なのは、これを機能させるには、ポイントをノードの座標系で表現する必要があるということです。スプライトの位置をポイントとして使用している場合は、スプライトの親ノードを最後の引数として渡す必要があります。

例:シーンの座標系で赤い四角の位置を取得するには:

CGPoint positionInScene = [self convertPoint:[redSprite position]
                                    fromNode:[self blueSprite]];

blueSprite の座標系の[5, 5] -->シーンの座標系の[105, 205]

あなたの例:

CGPoint positionInScene = [self convertPoint:[self position] 
                                    fromNode:[self redSprite]];

redSprite の座標系の[0, 0] -->シーンの座標系の[105, 205]

[self position] が [0, 0] で、redSprite の座標系を使用したため、コードから同じ結果が得られました。親スプライトの座標系である、redSprite の位置が表現された座標系を提供する必要がありました。この場合、それは blueSprite です。

- (CGPoint)convertPoint:(CGPoint)point toNode:(SKNode *)node

この方法は、最初の方法とは正反対です。呼び出し元の座標系の点を別のノードの座標系に変換します。このメソッドの鍵は、指定された点が呼び出し元の座標系で表現されなければならないということです。

例:シーンが[125, 225]でタッチを受け取り、その場所に新しいスプライトを追加したいとします。これはたまたま redSprite のバウンディング ボックス内にあります。したがって、新しいスプライトを redSprite の子として追加するには、redSprite の座標系でタッチの位置を取得する必要があります。それを取得するには:

CGPoint positionInRedSprite = [self convertPoint:touchLocation 
                                          toNode:[self redSprite]];

シーンの座標系で[125, 225] --> redSprite の座標系で[20, 20]

于 2014-02-24T06:43:48.793 に答える
1

kevin. の優れた回答を読んだ後、私は SKNode にいくつかの拡張機能を作成することができました。これらは優れた例であり、ツールの便利なセットでもあります。

extension SKNode {

var frameInScene:CGRect {
    get {
        if let scene = self.scene {
            if let parent = self.parent {
                let rectOriginInScene = scene.convertPoint(self.frame.origin, fromNode: parent)
                return CGRect(origin: rectOriginInScene, size: self.frame.size)
            }
        }
        println("Just the normal frame, not the scene frame!!!")
        return frame
    }
}

var positionInScene:CGPoint {
    get {
        if let scene = self.scene {
            if let parent = self.parent {
                return scene.convertPoint(self.position, fromNode: parent)
            }
        }
        println("Just the normal position, not the scene position!!!")
        return position
    }
}
}

おそらくすべてを削除できると思いますがself.、コードがより混乱するように感じました。また、ノードがどのシーンまたは親ノードにも属していない場合の対処法がよくわからないので、通常のフレームと位置を返し、 a を使用しprintln()て警告を出しました。

誰かがこのコードに変更/追加を行っている場合は、特に質問への回答に役立つ場合は、ぜひ聞いてください。

于 2015-08-26T17:19:51.873 に答える
0

これが遅い応答であることはわかっていますが、通常、ノードの親をノードの位置の座標系として使用したいと考えています。したがって、この拡張機能は非常に便利であることがわかりました。

extension SCNNode {
    func convertPosition(node:SCNNode) -> SCNVector3 {
        return self.convertPosition(node.position, fromNode:node.parentNode)
    }
}

たとえば、これを呼び出す代わりに:

let position = scene.rootNode.convertPosition(node.position, fromNode: node.parentNode)

これを呼び出すだけです:

let position = scene.rootNode.convertPosition(node)
于 2016-08-11T19:26:35.500 に答える
0

簡単にするために: ノード B とノード A の位置を比較する場合 (互いの距離を見つけようとする)

var BInSameCoordinateSys = NodeA.parent!.convertPoint(NodeB.position, fromNode: NodeB.parent!)

場所を視覚化するのに役立たない場合は、場所にスプライトを追加してトラブルシューティングします。

let childToSeeLocation = SKShapeNode(CircleWithRadius:50)
childToSeeLocation.fillColor = UIColor.redColor
ParentofA.addChild(childToSeeLocation)
于 2015-08-16T22:26:12.967 に答える