在 Sprite Kit 中拖动一个对象与另一个对象碰撞时不会发生弹跳
No bouncing occurs when dragging an object to collide with another object in Sprite Kit
Here 是我遇到的问题的视频。正如您在视频中看到的那样,我移动了一个灰色的球,试图与一个红色的球碰撞。当两个物体碰撞时没有弹跳发生,红球只是移动。我试过调整红球的密度,比如让红球的密度为 0.00001。碰撞行为没有区别。
如何更改碰撞行为以便出现弹跳?
以下是灰球的属性:
func propertiesGrayBall() {
gray = SKShapeNode(circleOfRadius: frame.width / 10 )
gray.physicsBody = SKPhysicsBody(circleOfRadius: frame.width / 10 )
gray.physicsBody?.affectedByGravity = false
gray.physicsBody?.dynamic = true
gray.physicsBody?.allowsRotation = false
gray.physicsBody?.restitution = 1
}
红球的属性如下:
func propertiesRedBall {
let redBall = SKShapeNode(circleOfRadius: self.size.width / 20
redBall.physicsBody = SKPhysicsBody(self.size.width / 20)
redBall.physicsBody?.affectedByGravity = false
redBall.physicsBody?.dynamic = true
redBall.physicsBody?.density = redBall.physicsBody!.density * 0.000001
redBall.physicsBody?.allowsRotation = false
redBall.physicsBody?.restitution = 1
}
这是我移动灰色球的方法。
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
if fingerIsOnGrayBall {
let touch = touches.first
var position = touch!.locationInView(self.view)
position = self.convertPointFromView(position)
grayBall.position = position
}
}
主要修改
球原本有附件。我删除了它们以简化问题。这就是为什么注释可能与代码不一致的原因。
如果您通过直接或使用 SKAction
设置其位置来移动节点(带有物理体),则该节点将不会成为物理模拟的一部分。相反,您应该通过应用 force/impulse 或设置其速度来移动节点。这是一个如何做到这一点的例子:
首先,定义一个变量来存储触摸的位置
class GameScene: SKScene {
var point:CGPoint?
然后,从您的代码中删除以下语句
redBall.physicsBody?.density = redBall.physicsBody!.density * 0.000001
最后,添加以下触摸处理程序
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
for touch in touches {
let location = touch.locationInNode(self)
let node = nodeAtPoint(location)
if (node.name == "RedBall") {
point = location
}
}
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
for touch in touches {
let location = touch.locationInNode(self)
if point != nil {
point = location
}
}
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
point = nil
}
override func update(currentTime: CFTimeInterval) {
if let location = point {
let dx = location.x - redBall.position.x
let dy = location.y - redBall.position.y
let vector = CGVector(dx: dx*100, dy: dy*100)
redBall.physicsBody?.velocity = vector
}
}
Here 是我遇到的问题的视频。正如您在视频中看到的那样,我移动了一个灰色的球,试图与一个红色的球碰撞。当两个物体碰撞时没有弹跳发生,红球只是移动。我试过调整红球的密度,比如让红球的密度为 0.00001。碰撞行为没有区别。
如何更改碰撞行为以便出现弹跳?
以下是灰球的属性:
func propertiesGrayBall() {
gray = SKShapeNode(circleOfRadius: frame.width / 10 )
gray.physicsBody = SKPhysicsBody(circleOfRadius: frame.width / 10 )
gray.physicsBody?.affectedByGravity = false
gray.physicsBody?.dynamic = true
gray.physicsBody?.allowsRotation = false
gray.physicsBody?.restitution = 1
}
红球的属性如下:
func propertiesRedBall {
let redBall = SKShapeNode(circleOfRadius: self.size.width / 20
redBall.physicsBody = SKPhysicsBody(self.size.width / 20)
redBall.physicsBody?.affectedByGravity = false
redBall.physicsBody?.dynamic = true
redBall.physicsBody?.density = redBall.physicsBody!.density * 0.000001
redBall.physicsBody?.allowsRotation = false
redBall.physicsBody?.restitution = 1
}
这是我移动灰色球的方法。
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
if fingerIsOnGrayBall {
let touch = touches.first
var position = touch!.locationInView(self.view)
position = self.convertPointFromView(position)
grayBall.position = position
}
}
主要修改 球原本有附件。我删除了它们以简化问题。这就是为什么注释可能与代码不一致的原因。
如果您通过直接或使用 SKAction
设置其位置来移动节点(带有物理体),则该节点将不会成为物理模拟的一部分。相反,您应该通过应用 force/impulse 或设置其速度来移动节点。这是一个如何做到这一点的例子:
首先,定义一个变量来存储触摸的位置
class GameScene: SKScene {
var point:CGPoint?
然后,从您的代码中删除以下语句
redBall.physicsBody?.density = redBall.physicsBody!.density * 0.000001
最后,添加以下触摸处理程序
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
for touch in touches {
let location = touch.locationInNode(self)
let node = nodeAtPoint(location)
if (node.name == "RedBall") {
point = location
}
}
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
for touch in touches {
let location = touch.locationInNode(self)
if point != nil {
point = location
}
}
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
point = nil
}
override func update(currentTime: CFTimeInterval) {
if let location = point {
let dx = location.x - redBall.position.x
let dy = location.y - redBall.position.y
let vector = CGVector(dx: dx*100, dy: dy*100)
redBall.physicsBody?.velocity = vector
}
}