我不知道如何问这个问题,但我的 SKScene 中有一个 SKSpriteNode。我希望它位于 y 轴的中间,但通过滑动(向上/向下)使其受到重力影响,直到它返回到 y 轴的中间。
设置示例:
1- SKSpriteNode 处于默认位置(在 x 轴上的位置并不重要,但在 y 轴的中间)
2-用户向上滑动
3- SKSpriteNode 受到 applyImpulse()
的影响+y 或 -y 方向
4- 重力在 -y 或 +y(分别)方向影响 SKSpriteNote
5- SKSpriteNode 移回到默认位置(由于重力)
我将如何执行此操作?
我尝试过的事情:
- RadialGravityField(未按我的预期执行)
- LinearGravityFieldWithVector(我有点失败了)
- 创建 2 个具有不同重力的矩形(失败得很惨)
- 检查 SKSpriteNode y 位置是否 < 或 > 于屏幕中间,具体取决于滑动是向上还是向下,如果是,则重置位置。签到didSimulatePhysics
。这不起作用,据我所知,它会重置位置,但是在调试时,即使在重置之后,SKSpriteNode 也不位于 y 轴的中间
如果您需要我的代码,请告诉我,但我正在寻找的只是一种执行此操作的方法
谢谢:)
编辑
这是我用来检查 Sprite 位置是否 < 或 > 于 y 轴中间的代码
override func didMoveToView(view: SKView) {
//set the players default position
playerDefaultPosition = CGPoint(x: self.size.width * 0.2, y: self.size.height / 2)
//background
backgroundColor = SKColor.whiteColor()
//world physics
self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
self.physicsWorld.gravity = CGVector(dx: 0, dy: 0)
//create player
playerNode.position = playerDefaultPosition
playerNode.physicsBody = SKPhysicsBody(rectangleOfSize: playerNode.size)
playerNode.physicsBody?.mass = 300
playerNode.physicsBody?.linearDamping = 0
addChild(playerNode)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
if let yTouch = touches.first?.locationInNode(self).y {
self.touches.append(yTouch)
startTime = NSDate()
}
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
if let yTouch = touches.first?.locationInNode(self).y {
self.touches.append(yTouch)
}
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
if let yTouch = touches.first?.locationInNode(self).y {
endTime = NSDate()
self.touches.append(yTouch)
if !self.touches.isEmpty {
let velocity = getVelocity(self.touches, startTime: startTime, endTime: endTime)
movePlayer(velocity)
}
}
func getVelocity(touchArray: [CGFloat], startTime: NSDate, endTime: NSDate) -> CGFloat {
var v: CGFloat = 0
if !touchArray.isEmpty {
//get velocity from v = d/t
let t = CGFloat(endTime.timeIntervalSinceDate(startTime))
let d = touchArray.last! - touchArray.first!
v = d / t
}
return v
}
func movePlayer(v: CGFloat) {
let vector = CGVector(dx: 0.0, dy: v * 30)
if vector.dy > 0 {
//player going in +y direction
swipedUp = true
self.physicsWorld.gravity = CGVector(dx: 0.0, dy: -10)
} else {
//player going in -y direction
swipedUp = false
self.physicsWorld.gravity = CGVector(dx: 0.0, dy: 10)
}
playerNode.physicsBody?.applyImpulse(vector)
}
override func didSimulatePhysics() {
if playerNode.position.y < (self.view?.frame.height)! / 2 - 1 && swipedUp || playerNode.position.y > (self.view?.frame.height)! / 2 + 1 && !swipedUp {
self.physicsWorld.gravity = CGVector(dx: 0, dy: 0)
playerNode.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 0))
print("gravity set to 0")
playerNode.position = playerDefaultPosition
}
}
经过更多调试后,似乎在设置 playerNode.position = playerDefaultPosition
后,下一帧的playerNode.position.y < (self.view?.frame.height)! / 2 - 1 && swipedUp
仍然如此
编辑2
查看documentation我实现了帧期间调用的每个函数并检查了位置 playerNode.position.y
在每个函数调用期间,当 SKScene 模拟物理时,似乎会发生一些事情,使玩家节点从其默认位置移动到另一个位置。
最佳答案
也许只检查节点的 y 位置,当节点的 y < frame.middleY (或 > )时关闭该节点的重力。滑动后重新打开。
关于ios - 将物理主体保留在 SKScene 的中间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32742525/