如何解决为什么为我的SKSpriteNode启用physicBody会导致异常?
我已经改变了这个问题很多,所以我将其移至新线程: How can I set a physicsbody to be properly centered?
我只是从SKPhysicsBody开始,我确实有view.showsPhysics = true
下面是在代码中创建一个简单的红色边框的代码,它显示得很好,而且准确地位于我希望的位置。
但是,当我取消注释将physicsBody
应用于边界的两条线时,它会意外地移动,甚至view.showsPhysics = true
中的物理调试线也与边界线不同步。
下面是代码,我想要的是左侧提供的屏幕截图。右侧的屏幕截图显示了将PhysicalBody应用于SKSpriteNode时会发生什么情况。
很明显,我的应用不正确,但是我无法弄清楚。
func createBorder () -> SKSpriteNode
{
let mBorder = MyBorder(color: .red,size: CGSize(
width: myGlobalVars.widthPoints,height: myGlobalVars.heightPoints * 0.01 ))
mBorder.isHidden = true
mBorder.anchorPoint = CGPoint(x: 0,y: 0)
mBorder.position = CGPoint(x: 0,y: myGlobalVars.heightPoints * 0.2)
// mBorder.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: myGlobalVars.widthPoints,height: myGlobalVars.heightPoints * 0.01))
// mBorder.physicsBody!.affectedByGravity = false
mBorder.zPosition = theZ.theBoarder
mBorder.isHidden = false
myGlobalVars.gameScene!.addChild(mBorder)
return mBorder
}
解决方法
在没有看到更完整的代码示例的情况下,很难确定为什么在第二个屏幕快照中启用了动态功能后,红色矩形精灵会向下移动。
关于SpriteKit动态调试可视化效果看起来不对,这是因为您正在更改Sprites的anchorPoint
属性。此属性定义节点的 origin 点,例如节点应居中的点(默认为CGPoint(x: 0.5,y: 0.5)
)。
如果您查看SKPhysicsBody(rectangleOf:)
方法的文档,则会发现默认情况下会在原点创建物理形状:
创建一个以拥有节点的原点为中心的矩形物理物体。
如果要将精灵的anchorPoint
保持为零,则需要手动指定物理形状的中心点。在本例中,假设您要查找的边框矩形尺寸为 600x10 。您将需要使用SKPhysicsBody(rectangleOf:center:)
方法来偏移物理身体中心:
let borderSize = CGSize(width: 600,height: 10)
mBorder.physicsBody = SKPhysicsBody(rectangleOf: borderSize,center: CGPoint(x: borderSize.width / 2,y: borderSize.height / 2))
,
从您共享的代码来看,您可能需要设置一些物理模拟的更多细节。无论如何,如果可以使用print
语句检查物理接触以更好地了解模拟中正在发生和未发生的情况,则可能会帮助您调试代码。这是我在自己的游戏中处理物理学的方式。希望这个例子会有所帮助。
import SpriteKit
class GameScene: SKScene,SKPhysicsContactDelegate {
}
我在声明SKPhysicsContactDelegate
类时设置了GameScene
。
override func didMove(to view: SKView) {
self.physicsWorld.contactDelegate = self
self.balloon.physicsBody = SKPhysicsBody(circleOfRadius: 1.0)
self.balloon.physicsBody?.categoryBitMask = 0
self.balloon.physicsBody?.contactTestBitMask = 0
self.balloon.physicsBody?.collisionBitMask = 0
}
在该类中,在didMove(to:)
方法中,将contactDelegate
的{{1}}设置为physicsWorld
,它引用了self
。然后,为场景中其他地方创建的气球对象创建GameScene
。我看到您已经在注释掉的代码部分中进行了此操作。我还设置了类别,联系人和冲突位掩码,以便以后可以检查它们。
physicsBody
在func didBegin(_ contact: SKPhysicsContact) {
if contact.bodyA.categoryBitMask == 0 {
print("Balloon was contacted.")
} else {
print("No balloons hit.")
}
}
方法中,当引擎在每个帧中调用此方法时,我都会检查物理接触,并对物理模拟中出现的某些接触做出响应。在这里,我选择检查didBegin(_:)
中是否有接触的对象,如果对象的位掩码为categoryBitMask
,那么我正在记录一条0
语句,以便我知道气球是被某物击中。但是我可以轻松地采取其他措施。
如果您想了解有关检查物理接触和碰撞的更多信息,请参考以下一些好资源:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。