Получать данные делегата внутри другой функции в Swift?

#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. В противном случае я считаю, что сила отключается на дополнительный кадр, когда она применяется в функции обнаружения столкновений.