Swift-Setting a physics body velocity by angle

2019-06-03 22:55发布

问题:

I was wondering if it was at all possible to make an SKNode move forward in a particular direction, but with only one factor. I'm aware of both applying an impulse and setting the velocity of a physics body, but they're both determined by two factors; dx and dy. I also know of rotating to an angle with SKActions. But is it possible to make an object simply "move forward" once it has been set on an angle? Or set its velocity with just one factor?

Thanks in advance.

回答1:

Sure I think what you're talking about is something like this:

Now let's say you have an SKSpriteNode that is called player who eventually has a physicsBody setup.

var player: SKSpriteNode!

You can just set the dx property of their velocity, so lets say you wanted to move them horizontally towards the location where the user tapped on the right hand side of the screen. If you then detect the position of the touch with touchesBegan(_:)

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard let touch = touches.first else { return }
    // Replace with name of node to detect touch
    let touchLocation = touch.location(in: <NAME_OF_NODE_PROPERTY>)

    // Verify it's in front of the player and not behind
    if (touchLocation.x - playerPosition.x) > 0 {
        movePlayerVertically(toward: touchLocation)
    }
}

func movePlayerVertically(toward location: CGPoint) {

    let dx:CGFloat = location.x - player.position.x
    player.physicsBody!.velocity.dx = dx

}

EDIT: -

Since you said you just want to be able to move your player horizontally without knowing the destination, you could do something like this, this is just moving the player forward on the x-axis by 50pts every second, and will repeat it forever. Obviously you would want to tweak it to your liking.

let move = SKAction.moveBy(x: 50, y: 0, duration: 1)
let repeatAction = SKAction.repeatForever(move)
player.run(repeatAction)


回答2:

Yes, is the answer to your question.

What I think you're looking for = THRUST... right?

What you want is for the "ship" to be able to rotate in any direction, and the thrust to be applied correctly, out of the "arse" of the ship, moving it forward, in ship terms.

This is absolutely possible, but does require a little "dummy" trick.

But I'm confusing you.

The local space of a SKPhysicsBody is relative to its parent. I presume.

And there's the speculative part. I'm guessing. I haven't tried this.

But... most physicsBodys are the child of an SKNode that's parented to the scene.

If you parent your ship to a dummy node for the purposes of rotation, and then rotate the dummy node, you should be able to make your spaceship fly in circles without ever changing the thrust vector, by simply rotating the dummy node.

Theoretically.

Something like this horrible pseudo code might help to start... maybe.

let dummy = SKNode()
let ship = SKSPriteNode()
dummy.addchild(ship)

ship.Physicsbody(add how you want here...)
ship.PhysicsBody.applyForce (vector that's only X, for example)

rotate dummy with action over time...