Musuh Menerima Banyak Kerusakan - Swift, Xcode 8.2.1

Saya sedang dalam proses membuat permainan bergaya penyerbu luar angkasa, dan ingin membuat musuh harus dipukul tiga kali sebelum meledak.

Tutorial yang saya gunakan hanya menunjukkan cara membuat musuh meledak hanya dengan satu pukulan. Ini menggunakan fungsi yang disebut didBegin(_ contact: SKPhysicsContact)

https://www.youtube.com/watch?v=F0kcw6eryJs&t=617s

Sekarang, fungsi ini, dari pemahaman saya, mengevaluasi setiap kejadian kontak, menetapkan dua peran berbeda pada dua benda, dan kemudian memutuskan apa yang harus dilakukan dengan masing-masing benda. Saya berasumsi jika musuh menerima tiga serangan, variabel yang berisi sisa kesehatan mereka akan digunakan. Kemudian, dengan setiap kejadian kontak, variabelnya akan berkurang satu, hingga jika nilainya nol, musuhnya tersingkir.

Namun, ada masalah besar dalam hal ini. KarenadidBegin(_ contact: SKPhysicsContact) hanya mengevaluasi satu contoh kontak, ia tidak memiliki pengetahuan tentang contoh kontak sebelumnya. Intinya, ketika musuh terkena serangan, tidak ada cara untuk mengetahui apakah musuh tersebut pernah terkena serangan sebelumnya, belum terkena serangan sama sekali, atau sudah terlalu sering terkena serangan. Jika hanya ada satu musuh, maka saya dapat menggunakan satu variabel untuk memantau kesehatannya. Namun hal ini tidak terjadi, karena ada banyak musuh di layar sekaligus, dan setiap kali terjadi kontak, tidak ada cara untuk mengetahui apakah serangan sebelumnya mengenai musuh ini, atau musuh lainnya.

Jika ada satu musuh di layar, itu sederhana karena setiap kali terjadi kontak, pasti ada satu musuh tersebut. Namun jika ada beberapa entitas di layar, maka tidak ada cara untuk mengetahui musuh mana yang diterapkan oleh suatu kontak.

Saya percaya ini akan memerlukan semacam identifikasi untuk setiap contoh musuh, meskipun saya tidak yakin bagaimana melakukan hal ini. Bagi kalian yang membaca, saya ucapkan banyak terima kasih sudah mampir, dan saya sangat berterima kasih jika kalian bisa membantu.


person cTem    schedule 06.06.2018    source sumber


Jawaban (2)


Tidak perlu menyimpan kamus terpisah untuk melacak status sprite

Setiap SKNode memiliki userData, dan Anda dapat melacak kehidupan musuh dengannya

Contoh:

let invader = SKSpriteNode(imageNamed:"invader")
invader.userData = ["health":3]

...


func didBeginContact(...)
{
...
  //when a contact happens
    contact.body_.node.userData["health"] -= 1
...
}

Nah yang perlu diingat, 1 peluru bisa mengenai 1 musuh sebanyak dua kali. Anda tidak ingin memicu 2 korban jiwa di sini, jadi Anda memerlukan variabel sementara (yang juga dapat Anda simpan di data pengguna) yang memungkinkan Anda mengetahui apakah peluru tertentu telah melakukan kontak dengan penyerang.

person Knight0fDragon    schedule 06.06.2018
comment
Terima kasih banyak untuk ini! Saya bertanya-tanya, di func didBeginContact apa format yang tepat untuk mengurangi variabel kesehatan? Saat Anda merujuk ke body_, maksud Anda bodyA atau bodyB, atau haruskah saya menguji keduanya, karena dikatakan SKPhysicsContact tidak memiliki badan anggota. selain itu, saat mencoba menguranginya, muncul kesalahan Binary operator '-=' cannot be applied to operands of type 'Any?' and 'Int'. Ini membingungkan, karena sepertinya tipe Int bisa dioperasikan. Sekali lagi, terima kasih banyak atas bantuan Anda. - person cTem; 07.06.2018
comment
Body_ adalah tubuh apa pun penyerang Anda. Kategori ini akan memberi tahu Anda hal itu. - person Knight0fDragon; 07.06.2018

Anda benar sekali, entah bagaimana Anda perlu melacak musuh dan kesehatan mereka sendiri. Mungkin ada banyak cara untuk melakukannya, tetapi berikut ini salah satu cara untuk mencapai tujuan Anda:

Gunakan kamus musuh dengan kesehatan mereka. Setiap musuh akan diberikan semacam id untuk mengidentifikasi mereka. Kesehatan dapat direpresentasikan sebagai Int. Kamus ini juga dapat digunakan untuk mengetahui dengan mudah berapa jumlah musuh yang masih ada.

var enemyHealth = [String:Int]()

Node memiliki properti nama yang dapat Anda tetapkan nilai string apa pun. Ini adalah bagaimana Anda dapat mengidentifikasi node Anda. Saat membuat musuh, Anda akan membuat id (misalnya membuat nomor acak), menetapkan nama node sebagai id dan menambahkan musuh ke kamus enemyHealth dengan nilai kesehatan default.

let enemyNode = SKSpriteNode(color: UIColor.white, size: CGSize.zero)
let enemyId = "\(arc4random())"
enemyNode.name = enemyId
enemyHealth[enemyId] = 10
...

Di didBegin(_ contact: SKPhysicsContact) Anda dapat mengakses node yang terlibat dalam tabrakan menggunakan parameter kontak dari fungsi (contact.bodyA.node atau contact.bodyB.node). Dengan membandingkan nama node dengan kunci di enemyHealth, Anda dapat mengetahui badan tabrakan mana yang menjadi musuh dan kesehatan apa yang dimilikinya.

let enemy:SKSpriteNode

if enemyHealth.keys.contains(contact.bodyA.node?.name ?? "") {
    enemy = contact.bodyA.node as! SKSpriteNode

} else if enemyHealth.keys.contains(contact.bodyB.node?.name ?? "") {
    enemy = contact.bodyB.node as! SKSpriteNode
} else {
    return  //none of the collision partners are an enemy
}

let health = enemyHealth[enemy.name!]!
...

Sekarang Anda dapat melakukan apapun yang Anda inginkan dengan musuh. Ketika musuh terbunuh/dihilangkan maka hapus juga dari kamus enemyHealth.

person Christoph    schedule 06.06.2018