繁体   English   中英

如何使用 Swift 5 在 SpriteKit 中以某个角度应用脉冲?

[英]How do I applyImpulse at a certain angle in SpriteKit using Swift 5?

我试图在一个 iOS 游戏中向 touchEnded 方法的方向扔一个球。 我已经搜索了许多线程,但有些线程很旧,而对于其他线程,我无法弄清楚问题所在。

我正在尝试做的事情如下:

1- 添加一个球作为 SKShapeNode - 将受影响的重力设置为 false。

2- 在 touchesEnded - 我得到了位置 CGPoint(不知何故我得到了 y position 反转 - 我更正了)。

3- 我使用 atan() 计算角轴承。

4- 我根据角度的 sin() 和 cos() 计算 CGVector dx 和 dy 脉冲。

5- 我根据上面的 CGVector 对球应用Impulse。

我的问题是球没有完全按照 touchesEnded 方向射出。 如果 touchesEnded 方向在球的垂直下方,那么它可以工作。 离垂直越远,偏差越大。

为了帮助解决问题并将问题可视化,我添加了一条线并在球应该遵循的方向结束蓝色球。 理想情况下,红球应该与蓝球相撞。 但是,我得到的真正方向是添加的绿球。 理想情况下,绿球应该在线上。

我试图完全像这里所做的那样做,但我没有得到结果: SpriteKit 物理 applyImpulse in direction

感谢你的帮助。 '''

import SpriteKit

class GameScene: SKScene {
    var sprite = SKShapeNode()
    var radius: CGFloat = 10
    var ballSpawnPosition: CGPoint = CGPoint(x: 0, y: 0)
    override func didMove(to view: SKView) {

        self.physicsBody = SKPhysicsBody(edgeLoopFrom: self.frame)
        ballSpawnPosition = CGPoint(x: frame.midX, y: frame.maxY - 50)

        spawnBall()
    }

    func spawnBall() {

        sprite = SKShapeNode(circleOfRadius: radius)
        sprite.physicsBody = SKPhysicsBody(circleOfRadius: radius)
        sprite.physicsBody?.collisionBitMask = 0x1
        sprite.fillColor = .red
        sprite.position = ballSpawnPosition
        addChild(sprite)
        sprite.physicsBody?.affectedByGravity = false
    }


    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let touch = touches.first {
            let position = touch.location(in: view)
            let blueTestTouchPointBall = SKShapeNode(circleOfRadius: radius)
            blueTestTouchPointBall.physicsBody = SKPhysicsBody(circleOfRadius: radius)
            blueTestTouchPointBall.physicsBody?.categoryBitMask = 0x1
            blueTestTouchPointBall.fillColor = .blue
            let y = frame.size.height - position.y
            blueTestTouchPointBall.position = CGPoint(x: position.x, y: y)
            blueTestTouchPointBall.physicsBody?.affectedByGravity = false
            addChild(blueTestTouchPointBall)

            var path = CGMutablePath()
            path.move(to: ballSpawnPosition)
            path.addLine(to: CGPoint(x: position.x, y: y))
            path.closeSubpath()

            let line = SKShapeNode()
            line.path = path
            line.strokeColor = .white
            line.lineWidth = 2
            addChild(line)
        }
    }


    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {

        if let touch = touches.first { //should not work if dragged.
            let position = touch.location(in: view)
            let dx = position.x - ballSpawnPosition.x
            let dy = frame.size.height - abs( position.y - ballSpawnPosition.y)
            let ang = atan(abs(dx)/abs(dy))
            //let tang = sqrt(dx*dx + dy*dy)
            let impulse: CGFloat = 15.0
            let x_impulse = impulse * sin(ang) * dx/abs(dx)
            let y_impulse = -1.0 * impulse * cos(ang)
//            let x_impulse = impulse * dx/abs(dx) * dx/tang
//            let y_impulse = impulse * -1 * dy/tang
            sprite.physicsBody?.applyImpulse(CGVector(dx: x_impulse , dy: y_impulse ))


            let greenTestBall = SKShapeNode(circleOfRadius: radius/2)
            greenTestBall.fillColor = .green
            greenTestBall.position = CGPoint(x: ballSpawnPosition.x + 300 * sin(ang) * dx/abs(dx), y: ballSpawnPosition.y - 300 * cos(ang) )
            addChild(greenTestBall)

        }

    }

}

'''

您正在不同坐标系中混合点。 应该使用UITouchlocation(in:)方法并传入SKNodeUITouch的位置转换为球所在的节点(通常是场景,但也可以是另一个节点)。 有关 SpriteKit 中坐标转换的更多信息,请参见此处 由于球是场景的孩子,所以改变

let position = touch.location(in: view)

let position = touch.location(in: self) // i.e. the `GameScene`

假设您使用球生成 position 作为参考点并且相对于垂直方向取角度,则还需要调整角度计算。 改变

let dy = frame.size.height - abs(position.y - ballSpawnPosition.y)

let dy = abs(position.y - ballSpawnPosition.y)

更改上述内容会创建我相信您正在寻找的内容。 请注意,动量是相加的:在球向左移动时向右施加冲量不一定会导致球开始向左移动(除非冲量足够大)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM