我有一个SKSpriteNode
球,它已经被赋予了所有的SKPhysicsBody
属性,可以在所有方向上移动。现在我想让它变为单向
(只能向它之前没有移动过的方向移动,并且不回到之前移动过的路径中)。目前我对解决这个问题有以下想法:
- 通过创建一个
fieldBitMask
,将迭代的路径上的球反弹,以防止其返回。 - 从
touchesBegan/ touchesMoved
方法中对球施加某种力/脉冲
,使其不会回去。 - 在
update
方法中处理。 - 从Stack Overflow得到的代码实现,感谢贡献者! :)
以下是支持性代码片段,以更好地理解问题:
//getting current touch position by using UIEvent methods
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else {return}
let location = touch.location(in: self)
lastTouchPoint = location
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else {return}
let location = touch.location(in: self)
lastTouchPoint = location
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
lastTouchPoint = nil
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
lastTouchPoint = nil
}
//ball created
func createPlayer(){
player = SKSpriteNode(imageNamed: "player")
player.position = CGPoint(x: 220, y: 420)
player.zPosition = 1
//physics for ball
player.physicsBody = SKPhysicsBody(circleOfRadius: player.size.width / 2)
player.physicsBody?.allowsRotation = false
player.physicsBody?.linearDamping = 0.5
player.physicsBody?.categoryBitMask = collisionTypes.player.rawValue
player.physicsBody?.contactTestBitMask = collisionTypes.finish.rawValue
player.physicsBody?.collisionBitMask = collisionTypes.wall.rawValue
addChild(player)
}
//unwarp the optional property, calclulate the postion between player touch and current ball position
override func update(_ currentTime: TimeInterval) {
guard isGameOver == false else { return }
if let lastTouchPosition = lastTouchPoint {
//this usually gives a large value (related to screen size of the device) so /100 to normalize it
let diff = CGPoint(x: lastTouchPosition.x - player.position.x, y: lastTouchPosition.y - player.position.y)
physicsWorld.gravity = CGVector(dx: diff.x/100, dy: diff.y/100)
}
}