Рассчитать угол линии SKShapeNode на SpriteKit - PullRequest
0 голосов
/ 12 января 2020

Я хочу построить игру Brick. У меня есть мяч, который нужно стрелять в направлении линии рисования.

Вот как я стреляю в мяч:

 let ang = angle(between: balls.first!.position, ending: CGPoint(x: guideLine.frame.maxX, y: guideLine.frame.maxY))
    let force = CGVector(dx:cos(ang) * gameSpeed, dy:sin(ang) * gameSpeed)
    for i in 0..<balls.count {
        DispatchQueue.main.asyncAfter(deadline: .now() + Double(i) * 0.1) {
            if !balls.isEmpty {
                balls[i].physicsBody!.applyImpulse(force)
            }
        }
    }

Вот моя функция «угла», которая конвертирует две позиции под углом:

func angle(between starting: CGPoint, ending: CGPoint) -> CGFloat {
    let center = CGPoint(x: ending.x - starting.x, y: ending.y - starting.y)
    let radians = atan2(center.y, center.x)
    let degrees = GLKMathRadiansToDegrees(Float(radians))
    return degrees > 0 ? CGFloat(degrees) : CGFloat(degrees + degrees)
}

Как вы видите, я получаю начальную точку линии, где находится шарик, и получаю конец линии от линии maxX и maxY ... Я хотя не уверен, что это правильный путь ...

Результат очень странный! Мяч идет в любом направлении, в котором он хочет, каждый раз по-разному (иногда рядом с моими линиями, а иногда очень далеко), я не могу понять это.

Вот скриншоты:

enter image description here enter image description here

1 Ответ

2 голосов
/ 13 января 2020

Вы вычисляете угол в градусах, затем передаете его в sin и cos, которые ожидают радианы. Это, вероятно, ваша основная проблема.

Что касается других вещей, неясно, какова цель всего этого degrees > 0. Кроме того, в SpriteKit, вероятно, лучше придерживаться различных SKAction s для таких вещей, как запуск содержимого после задержки, а не для добавления DispatchQueue содержимого. Последний не будет правильно взаимодействовать со средствами SpriteKit для приостановки, изменения скорости узла и т. Д. c.

let ang = angle(between: balls.first!.position, ending: CGPoint(x: guideLine.frame.maxX, y: guideLine.frame.maxY))
let actions = [SKAction]()
let force = CGVector(dx:cos(ang) * gameSpeed, dy:sin(ang) * gameSpeed)
let wait = SKAction.wait(forDuration:0.1)   
for ball in balls {
    let action = SKAction.run{
        ball.physicsBody!.applyImpulse(force)
    }
    actions.append(wait)
    actions.append(action)
}
run(SKAction.sequence(actions))  

func angle(between starting: CGPoint, ending: CGPoint) -> CGFloat {
    let relativeToStart = CGPoint(x: ending.x - starting.x, y: ending.y - starting.y)
    let radians = atan2(relativeToStart.y, relativeToStart.x)
    //let degrees = GLKMathRadiansToDegrees(Float(radians))
    return radians > 0 ? (radians : (.pi * 2) + radians)
}
...