Saya mencoba memahami hal konversi di SpriteKit tetapi meskipun telah membaca dokumentasi dan beberapa posting di SO sepertinya saya tidak bisa melakukannya dengan benar. Sejauh yang saya mengerti ada dua sistem koordinat yang bekerja secara independen satu sama lain, satu untuk scene dan satu untuk view, itulah sebabnya saya tidak bisa menggunakan hal-hal seperti UIScreen.main.bounds.maxX untuk menentukan sudut layar yang dapat dihubungkan dengan node. Apakah saya mendapatkan ini dengan benar?

Bagaimanapun, inilah upaya saya untuk mengonversi koordinat:

let mySquare = SKShapeNode(rectOf: CGSize(width: 50, height: 50))
mySquare.fillColor = SKColor.blue      
mySquare.lineWidth = 1

let myPoint = CGPoint(x: 200, y: 0)

let newPosition = mySquare.convert(myPoint, from: self)     
mySquare.position = newPosition

print(newPosition)  
self.addChild(mySquare)

print mengembalikan posisi yang sama persis seperti yang masuk, jadi jelas saya tidak melakukan ini dengan benar, tetapi saya telah mencoba sejumlah konstelasi yang berbeda tetapi dengan hampir tidak ada hasil; koordinatnya tetap sama. Saya juga sudah mencoba let myPoint = CGPoint(x: UIScreen.main.bounds.maxX, y: UIScreen.main.bounds.maxY) tetapi sama di sana; tidak ada konversi.

Apa yang saya lewatkan? Di kepala saya, saya membaca konversi di atas sebagai "convert myPoint dari sistem koordinat view dan menggunakannya untuk node mySquare.

0
screenMonkey MonkeyMan 2 Maret 2020, 11:41

1 menjawab

Jawaban Terbaik

Ada banyak sistem koordinat yang beredar, dan begitu banyak sumber kebingungan potensial:

  1. Koordinat pemandangan: itulah dunia gim Anda, dan apa yang biasanya Anda pikirkan saat membayangkan koordinat dan cara memposisikan sesuatu secara keseluruhan.
  2. Node: Node memiliki sistem koordinatnya sendiri. Setelah Anda mulai membangun hierarki, itu penting. Bayangkan, misalnya, joystick di layar yang memiliki latar belakang yang menunjukkan grafik arah gerakan dan "kenop" pusat yang dapat dimanipulasi oleh pemain. Anda mungkin mewakili joystick sebagai simpul dengan dua anak. Satu anak adalah sprite untuk latar belakang, dan yang lainnya adalah sprite untuk tombol. Sprite latar belakang secara alami akan berada di posisi (0,0), yang berarti pusat dari keseluruhan joystick. Kenop akan bergerak, dengan (0,0) berarti di tengah dan mungkin (0,100) berarti sedikit naik. Joystick keseluruhan mungkin duduk di (200.300) di tempat kejadian. Kemudian sprite latar belakang akan muncul di (200.300) dalam adegan dan kenop, saat naik, akan berada di (200.300)+(0,100) = (200.400) dalam adegan. convert(from:) dan convert(to:) adalah untuk mengonversi dalam hierarki simpul. Anda dapat menanyakan di mana letak kenop dalam koordinat keseluruhan adegan dengan knob.convert(.zero, to: scene) atau joystick.convert(knob.position, to: scene). Anda sangat jarang perlu melakukan konversi semacam itu.
  3. Koordinat tampilan: Tampilan adalah jendela di tempat kejadian, yaitu, apa yang sebenarnya ditampilkan. Jika Anda memiliki game layar penuh, tampilan pada dasarnya ditentukan oleh ukuran layar dalam poin. Bagaimana koordinat tampilan peta ke koordinat adegan menentukan bagian adegan mana yang benar-benar Anda lihat. Jika Anda perlu beralih antara koordinat tampilan dan koordinat pemandangan, Anda menggunakan metode convertPoint(fromView:) dan convertPoint(toView:) pemandangan.

Jika Anda tidak melakukan sesuatu yang istimewa dan memiliki ukuran pemandangan yang sama dengan ukuran tampilan, maka pemetaan tampilan pemandangan akan memiliki (0,0) pada pemandangan di sudut kiri bawah tampilan. Konvensi umum lainnya adalah memiliki (0,0) di adegan di tengah layar dengan menyetel anchorPoint adegan ke (0,5,0.5). Atau mungkin Anda telah merancang adegan sehingga dunia berukuran 2000x2000 dan akan ada penskalaan nontrivial dan kemungkinan letter-boxing atau cropping yang terlibat (tergantung pada pengaturan adegan scaleMode). Atau jika game Anda memiliki node kamera dan, misalnya, kamera diatur untuk mengikuti pemain di sekitar, maka pemetaan view-to-scene akan berubah saat pemain bergerak.

Dalam kode Anda, memanggil mySquare.convert(from:) bahkan tidak masuk akal karena kotak belum ditambahkan ke adegan pada saat Anda melakukan "konversi".

Bagaimanapun, jika Anda benar-benar ingin melakukan sesuatu seperti "letakkan kotak di sudut kiri atas layar", maka Anda dapat mengambil titik di bingkai tampilan dan mengubahnya menjadi koordinat pemandangan dan mengatur posisi kotak itu.

override func didMove(to view: SKView) {
  ...
  mySquare.position = convertPoint(fromView: CGPoint(x: view.frame.minX, y: view.frame.minY))
  addChild(mySquare)
  ...
}

Sunting: Saya akan mendorong Anda untuk berpikir sebagian besar dalam hal keseluruhan adegan, setelah beberapa pertimbangan awal tentang bagaimana permainan harus dipetakan ke perangkat dengan layar dengan ukuran dan rasio aspek yang berbeda. Setelah Anda memikirkan adegan, maka frame adegan (bukan bingkai tampilan) menjadi referensi paling alami saat Anda membayangkan "di tepi kiri" atau "di dekat kanan bawah".

2
bg2b 4 Maret 2020, 03:04