#sprite-kit #collision #contacts #skphysicsbody
Вопрос:
Мы пытаемся создать зарядную станцию для игры, которую мы создаем, с полосой здоровья, которая увеличивается, когда игрок сталкивается с зарядным устройством. Для этого мы создали категорию для плеера, а также категорию для зарядного устройства. В нашей функции didBegin, которая активируется при столкновении, что видно ниже, здоровье(которое является глобальной переменной) увеличивается, а зарядка устанавливается в значение true. Чтобы убедиться, что здоровье не просто продолжает увеличиваться после того, как игрок перестанет сталкиваться с зарядным устройством, у нас есть функция didEnd, которая появляется только тогда, когда столкновения больше не происходит. Это устанавливает переменную зарядки в значение false. В нашей функции обновления у нас есть условные операторы для того, что должно произойти в нашем коде, если зарядка истинна или ложна. Когда это правда, здоровье немного увеличивается и не поднимается выше 1 или ниже нуля, чтобы держать его в рамках. Когда оно ложно, здоровье немного уменьшается, а также не поднимается выше 1 или ниже нуля, чтобы держать его в рамках. Проблема, с которой мы сталкиваемся, заключается в том, что при первом столкновении плеера с зарядным устройством переменная зарядки устанавливается в значение true, но как только она немного сдвинется, даже если она все еще сталкивается с зарядным устройством, переменная устанавливается в значение false, и она больше не заряжается. Есть ли что-то, чего нам не хватает/есть ли лучший способ настроить зарядную станцию?
let chargerCategory: UInt32 = 0b1000 //6 if charge is in contact with player, then increase
func didBegin(_ contact: SKPhysicsContact) {
var body1 = SKPhysicsBody()
var body2 = SKPhysicsBody()
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask{
body1 = contact.bodyA
body2 = contact.bodyB
}
else{
body1 = contact.bodyB
body2 = contact.bodyA
}
if body1.categoryBitMask == playerCategory amp;amp; body2.categoryBitMask == chargerCategory{
//if player hit charger
//health = 0.001
//HealthBar.xScale = health
print("CHARGING...", health)
charging = true
}
func didEnd(_ contact: SKPhysicsContact) {
var body1 = SKPhysicsBody()
var body2 = SKPhysicsBody()
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask{
body1 = contact.bodyA
body2 = contact.bodyB
}
else{
body1 = contact.bodyB
body2 = contact.bodyA
}
if body1.categoryBitMask == playerCategory amp;amp; body2.categoryBitMask == chargerCategory{
charging = false
}
}
override func update(_ currentTime: TimeInterval) {
if charging == false{
health -= 0.0001
HealthBar.xScale = health
if health < 0 {
health = 0
}
if health > 1.0{
health = 1.0
}
}
if charging == true{
health = 0.001
HealthBar.xScale = health
// print("CHARGING...", health)
if health < 0 {
health = 0
}
if health > 1.0{
health = 1.0
}
}
print(health)
print(charging)
}
Комментарии:
1. Вы использовали view.showsPhysics = true, чтобы увидеть сами физические тела? Затем вы можете определить, действительно ли это код столкновения или проблема в самих физических телах.
2. Да, я использовал это, чтобы увидеть сами физические тела. Физические тела — это не проблема.
3. ОК. Ваш код и логика, лежащая в его основе, кажутся разумными. Найдите «зарядка = ложь» в своем коде, есть ли где-нибудь еще, где устанавливается флаг?
4. Изначально он установлен в значение false, но это единственное другое место, где он установлен в значение false.
5. У вас есть много других категорий физического тела? Вы показываете только 1. Возможно, разверните свой код, покажите все категории физики. Каковы разрядные маски категорий/столкновений/контактов, установленные на проигрывателе и станции? Покажите, как вы устанавливаете физическое тело как игрока, так и станции.