LoginSignup
20
16

More than 5 years have passed since last update.

UIViewの座標とSKNodeの座標の違い

Posted at

UIViewの座標とSKNodeの座標の違い

SpriteKitでゲームを作った際、UIKitと組み合わせてみた時に混乱したのでメモ

ビュー座標とシーン座標

MyPlayground.playground
import UIKit
import SpriteKit
import XCPlayground

let liveView = SKView(
    frame: CGRect(
        origin: CGPointZero,
        size: CGSize(width: 300, height: 300)
    )
)

XCPlaygroundPage.currentPage.liveView = liveView
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true

// 今回適応してみるCGRect
let rect = CGRect(
    origin: CGPoint(x: 40, y: 20),
    size: CGSize(width: 80, height: 40)
)

// SKSceneを作って、Nodeを入れる
let skScene = SKScene(size: liveView.frame.size)
liveView.presentScene(skScene)

let node = SKShapeNode(rect: rect)
node.fillColor = UIColor.blueColor()
skScene.addChild(node)

// 同じCGRectのUIViewを入れるとどうなるの?
let uiView = UIView(frame: rect)
uiView.backgroundColor = UIColor.redColor()
liveView.addSubview(uiView)

UIViewとSKNodeに同じRectを適応しても、
originの原点位置とxy軸の方向が異なっているのがわかる

Artboard 1.png

中心点

ちなみにそれぞれ中心点はframe.midX, frame.midYで分かる (get only)

MyPlayground.playground
CGPoint(x: uiView.frame.midX, y: uiView.frame.midY) // {x 80 y 40}
CGPoint(x: node.frame.midX, y: node.frame.midY) // {x 80 y 40}

SKNodeの場合は、positionを指定することで中心から描画することもできる

MyPlayground.playground
let center = CGPoint(x: liveView.frame.midX, y: liveView.frame.midY)
let node2 = SKShapeNode(rectOfSize: rect.size)
node2.position = center
node2.fillColor = UIColor.purpleColor()
skScene.addChild(node2)

Artboard 2.png

座標の変換

ビュー座標とシーン座標はお互い変換することができる

convertPointToView

MyPlayground.playground
// シーン座標からビュー座標へ変換
let convertToViewOrigin = skScene.convertPointToView(uiView.frame.origin)
convertToViewOrigin     // x 40 y 280

let node3 = SKShapeNode(
    rect: CGRect(
        origin: convertToViewOrigin,
        size: rect.size
    )
)
node3.fillColor = UIColor.brownColor()
skScene.addChild(node3)

これにより、UIViewとoriginは一緒の位置になる
が、sizeによる描画方向はそれぞれ異なっているのに注意

Artboard 3.png

convertPointFromView

MyPlayground.playground
// ビュー座標からシーン座標へ変換
let convertFromViewOrigin = skScene.convertPointFromView(node.frame.origin)
convertFromViewOrigin   // x 38.65 y 281.35

let uiView2 = UIView(frame:
    CGRect(
        origin: convertFromViewOrigin,
        size: rect.size
    )
)
uiView2.backgroundColor = UIColor.yellowColor()
liveView.addSubview(uiView2)

微妙に座標がズレて小数点が出ているのは、
SKNodeの枠線が入っている分も計算してくれるからのようだった

Artboard 4.png


そもそもSpriteKitとUIKitごちゃまぜでゲーム作るのって変なのかな。
全部SKNodeでやる方がいいのかな。よくわからない。

説明しやすいように「ビュー座標」と「シーン座標」と名づけてますが、
正式な呼び方なのかわかんないので、あんまり信用しないでください。。。

20
16
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
16