Враг, наносящий множественный урон - Swift, Xcode 8.2.1 - PullRequest
0 голосов
/ 06 июня 2018

Я нахожусь в процессе создания игры в стиле космических захватчиков и хотел бы сделать так, чтобы противник был трижды поражен, прежде чем взорваться.

Учебное пособие, которое я использую, показывает только, какзаставить врагов взрываться только после одного удара.В ней используется функция с именем didBegin(_ contact: SKPhysicsContact)

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

Теперь эта функция, насколько я понимаю, оценивает каждый случай контакта, назначает двум телам две разные роли, а затем решает, чтоделать с каждым телом.Я предполагаю, что противник получит три удара, будет использоваться переменная, содержащая оставшееся у него здоровье.Затем, с каждым случаем контакта переменная будет уменьшаться на единицу, пока, если она не станет равной нулю, враг будет удален.

Однако в этом есть серьезная проблема.Поскольку didBegin(_ contact: SKPhysicsContact) оценивает только один экземпляр контакта, он не знает о других предыдущих случаях контакта.По сути, когда враг получает удар, нет никакого способа узнать, был ли враг поражен ранее, не был ли он поражен вообще или был поражен слишком много раз.Если бы был только один враг, то я мог бы использовать одну переменную, чтобы отслеживать его здоровье.Однако это не так, поскольку на экране одновременно несколько врагов, и каждый раз, когда происходит контакт, невозможно узнать, был ли предыдущий удар по этому врагу или другому врагу.

Если на экране присутствует один враг, это просто, потому что при каждом контакте это должен быть один враг.Но если на экране есть несколько объектов, то нет никакого способа узнать, к какому врагу относится контакт.

Я считаю, что для этого потребуется определенная идентификация для каждого экземпляра врага, хотя я не уверенкак это сделатьДля тех из вас, кто читает, я очень благодарен за то, что зашел, и я очень благодарен, если вы можете помочь.

Ответы [ 2 ]

0 голосов
/ 06 июня 2018

Нет необходимости хранить отдельные словари для отслеживания состояний спрайта

Каждый SKNode имеет userData, и вы можете отслеживать жизнь врагов с ним

Пример:

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

...


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

Теперь имейте в виду, одна пуля может поразить 1 врага два раза.Вы не хотите вызывать 2 потери жизни здесь, поэтому вам понадобится временная переменная (которую вы также можете сохранить в userData), которая позволит вам узнать, контактировала ли конкретная пуля с захватчиком.

0 голосов
/ 06 июня 2018

Вы абсолютно правы, вам как-то нужно самостоятельно отслеживать своих врагов и их здоровье.Вероятно, есть множество способов сделать это, но вот один из способов достижения того, к чему вы стремитесь:

Используйте словарь врагов со своим здоровьем.Каждому врагу будет предоставлен какой-то идентификатор для их идентификации.Здоровье может быть представлено как Int.Этот словарь также может быть использован для определения количества врагов.

var enemyHealth = [String:Int]()

Узлы имеют свойство name, для которого можно установить любое строковое значение.Так вы сможете идентифицировать свои узлы.При создании врага вы создадите идентификатор (например, генерируете случайное число), установите имя узла в качестве идентификатора и добавите врага в словарь enemyHealth со значением здоровья по умолчанию.

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

В didBegin(_ contact: SKPhysicsContact) вы можете получить доступ к вовлеченным узлам в столкновении, используя параметр контакта функции (contact.bodyA.node или contact.bodyB.node).Сравнивая имена узлов с ключами в enemyHealth, вы можете выяснить, какое тело столкновения было врагом и какое у него здоровье.

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!]!
...

Теперь вы можете делать с врагом все, что захотите,Когда враг убит / удален, удалите его из словаря enemyHealth.

...