#ios #swift #xcode #sprite-kit #delegates
#iOS #swift #xcode #sprite-kit #делегаты
Вопрос:
Я работаю над простой игрой, похожей на аэрохоккей в SpriteKit, используя Swift. У меня проблема, из-за которой я создал отдельные файлы игроков, которые делегируют вектор силы / направления основной игровой сцене, который будет использоваться при столкновении игрока с мячом / шайбой.
Вот как я извлекаю вектор направления / силу в классе GameScene (основной файл):
func northForce(_ force: CGVector, fromNorthPlayer northPlayer: NorthPlayer)
{
northPlayerForceForCollision = force
print("frame in topForce:", frameCounter)
}
Я действительно хочу иметь возможность прямого доступа к «силе» от делегата в моей функции обнаружения столкновений, чтобы мне не приходилось тратить фрейм на сохранение его в качестве глобальной переменной. Могу ли я в любом случае получить доступ к force, не имея его в своей собственной функции?
Вот как я отправляю force из своего класса northPlayer:
//pass the vector to the scene (so it can apply an impulse to the puck)
delegate?.northForce(directionVector, fromNorthPlayer: self)
Больше контекста класса northPlayer:
class NorthPlayer: SKShapeNode
{
//delegate will refer to class which will act on player force
weak var delegate:NorthPlayerDelegate?
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?)
{
northTouchIsActive = true
var releventTouch:UITouch!
//convert set to known type
let touchSet = touches
//get array of touches so we can loop through them
let orderedTouches = Array(touchSet)
for touch in orderedTouches
{
//if we've not yet found a relevent touch
if releventTouch == nil
{
//look for a touch that is in the activeArea (Avoid touches by opponent)
if activeArea.contains(CGPoint(x: touch.location(in: parent!).x, y: touch.location(in: parent!).y - frame.height * 0.42))
{
isUserInteractionEnabled = true
releventTouch = touch
}
else
{
releventTouch = nil
}
}
}
if (releventTouch != nil)
{
//get touch position and relocate player
// let location = releventTouch!.location(in: parent!)
let location = CGPoint(x: releventTouch!.location(in: parent!).x, y: releventTouch!.location(in: parent!).y - frame.height * 0.42)
position = location
//find old location and use pythagoras to determine length between both points
// let oldLocation = releventTouch!.previousLocation(in: parent!)
let oldLocation = CGPoint(x: releventTouch!.previousLocation(in: parent!).x, y: releventTouch!.previousLocation(in: parent!).y - frame.height * 0.42)
let xOffset = location.x - oldLocation.x
let yOffset = location.y - oldLocation.y
let vectorLength = sqrt(xOffset * xOffset yOffset * yOffset)
//get eleapsed and use to calculate speed
if lastTouchTimeStamp != nil
{
let seconds = releventTouch.timestamp - lastTouchTimeStamp!
let velocity = 0.015 * Double(vectorLength) / seconds
//to calculate the vector, the velcity needs to be converted to a CGFloat
let velocityCGFloat = CGFloat(velocity)
//calculate the impulse
let directionVector = CGVector(dx: velocityCGFloat * xOffset / vectorLength, dy: velocityCGFloat * yOffset / vectorLength)
//pass the vector to the scene (so it can apply an impulse to the puck)
delegate?.northForce(directionVector, fromNorthPlayer: self)
delegate?.northTouchIsActive(northTouchIsActive, fromNorthPlayer: self)
}
//update latest touch time for next calculation
lastTouchTimeStamp = releventTouch.timestamp
}
}
Что я хочу иметь возможность сделать, это просто получить доступ к делегату в функции обнаружения контактов / столкновений, чтобы не было функции посредника, которая занимает дополнительный кадр для сохранения делегированной силы в переменной в основной игровой сцене. Я думаю, что это сделает игру более плавной и точной при воспроизведении на высоких скоростях, где дополнительное отставание кадра может иметь большое значение.
Комментарии:
1. Откуда берется «делегат»?
2. @ElTomato Я добавил еще несколько подробностей о своей реализации! 🙂
3. Я не могу сказать, что не так, потому что вы не показываете все соответствующие строки кода.
4. @ElTomato В коде нет ничего неправильного, мне просто интересно, могу ли я получить переменную force из northPlayer непосредственно в другой функции GameScene. Я хочу получить доступ к force внутри функции contact, а не с помощью функции northForce. В противном случае я считаю, что сила отключается на дополнительный кадр, когда она применяется в функции обнаружения столкновений.