微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么为我的SKSpriteNode启用physicBody会导致异常?

如何解决为什么为我的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
}

p.s。请忽略显示灰色条的第一个屏幕。我刚刚改变了颜色。

enter image description here

解决方法

在没有看到更完整的代码示例的情况下,很难确定为什么在第二个屏幕快照中启用了动态功能后,红色矩形精灵会向下移动。

关于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 举报,一经查实,本站将立刻删除。