意外的物理体现在SpriteKit场景中

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了意外的物理体现在SpriteKit场景中相关的知识,希望对你有一定的参考价值。

我正在用SpriteKit实现一个质量弹簧系统(许多小物理机构与SKPhysicsJointSpring实例连接在一起)。一些粒子在穿过场景中心时会被钩住。

在场景中间似乎有一个小而静止的身体,我不知道它为什么会存在。

这是一个简单的方法来看看我在说什么:

  1. 在XCode 8中,使用“Game”模板创建一个全新的项目。
  2. GameViewController.viewDidLoad(),添加view.showsPhysics = true

如果你运行项目,你应该在中间看到一个小点,这是错误的主体:

enter image description here

谁知道如何摆脱它?

编辑:我试图手动创建场景对象:

GameViewController.viewDidLoad(),我取代了这个:

// Load the SKScene from 'GameScene.sks'
if let scene = SKScene(fileNamed: "GameScene") {
    view.presentScene(scene)
}

有了这个:

let scene = GameScene(size: view.frame.size)
scene.anchorPoint = CGPoint(x: 0.5, y: 0.5)
view.presentScene(scene)

但这并没有解决它。

答案

关于“hello world”xCode游戏模板,它似乎与physicsBody节点相关的一点点GameScene。有些代码我发现了这个:

class GameScene: SKScene {

    private var label : SKLabelNode?
    private var spinnyNode : SKShapeNode?

    override func didMove(to view: SKView) {
        ... 
        // End part of this function:
        if let b = physicsWorld.body(in: (label?.frame)!) {
            if let node = b.node {
                print("Type of this node: (type(of:node))")
                print("Frame of this node: (node.frame))")
            }
            print("Area covered by this node physicsBody: (b.area)")
        }
    }
}

enter image description here

使用最后一个大括号的断点,你可以看到两个实体(可能是一个实体数组),其中一个是左侧的physicsBody debugArea(带索引1的数组),在我的代码中具有与我的身体b相同的十六进制地址: 0x79794f90,一个面积为4.444的小矩形体

Printing description of ((PKPhysicsBody *)0x79794f90):
<SKPhysicsBody> type:<Rectangle> representedObject:[<SKScene> name:'(null)' frame:{{-375, -667}, {750, 1334}} anchor:{0.5, 0.5}]
(lldb) 

enter image description here

另一答案

无论如何,我决定回答是因为我希望分享很多信息,因此评论不合适。可悲的是,我的回答并没有回答这个问题,但它提供了一些关于这个身份不明的有用信息,显然能够飞行(物理身体)对象:)

所以这是代码如何抓住它(并修改它???):

 //you can use self.frame here...I just copied Alessandro's code
 self.physicsWorld.enumerateBodies(in:(label?.frame)!) { body, stop in

    if let node = body.node {

        print("Type of this node: (type(of:node))")    
        print("Frame of this node: (node.frame))")

    }else{

       print("This body's node property is nil")

        body.affectedByGravity = true
        body.isDynamic = true

        body.applyImpulse(CGVector(dx: 0.003, dy: 0.0003))

    }
     print("Area covered by this node physicsBody: (body.area)")
}

因此,如果你在else语句中放置一个断点,你可以完全扫描这个物理体并得到它的所有信息,比如它的node属性设置为nil或者它的isDynamic属性设置为false。但你可以改变它,就像在我的代码中一样,将isDynamics设置为true。这使它可以移动。因此,如果你对它施加一些力,它就会移动。

不过,正如我在评论中所说,我不知道为什么它存在,它代表什么或它的目的是什么。

此外,对于那些想知道一个物理体如何可能没有与之相关的节点(body.node等于nil)但在showsPhysics设置为true时屏幕上仍然可见的人,有一个合理的解释。物理世界与节点树分开。所以我们可以从节点树中删除一个精灵,但这并不意味着它的物理体将被立即删除。物理引擎可能还没有完成模拟......所以你可能想知道,这会怎么样?

假设你有三个SKSpriteNode物体同时相交(比如说A触点B和A触点C同时)。 SpriteKit可以只处理一个联系人。并说当你与B联系时你是从父母那里删除A.然后,A和C之间也有联系,所以didBegin:(_ contact)将被调用两次。如果你在第一次didBegin(_ contact)调用中从其父项中删除A,在下一个didBegin(_ contact)调用中,bodyA.node将为nil(bodyA是精灵A的物理主体),但它的物理主体将保持可见,直到引擎完成所需的操作。这是因为节点树和物理世界是分开的。

另一答案

我遇到了类似的问题。我有一个游戏,两个精灵节点连接在一起(SKPhysicsJointFixed.joint)在SKEditor创建的场景中移动。根据我的设计,这个节点对会影响第三个精灵节点,并且在撞击位于场景中心时,可以平稳地从第三个精灵节点推进。对于场景影响的中心,节点对将一起压缩,同时被推离第三个精灵节点,呈现不良的图形图像。

经过大量时间调试我的代码,我找到了这篇文章。感谢解释和代码。我无法回答“为什么”这个问题,但是对于“粒子在穿越场景中心时会被钩住”的问题我的建议解决方案是清除collisionBitMask而不是移动身体。

加载时BTW categoryBitMask为0。

        //moves the problem offscreen unless it hits another node
                    //body.affectedByGravity = true
                    //body.isDynamic = true
                    //body.applyImpulse(CGVector(dx: 0.003, dy: 0.0003))
        //
        // collisionBitMask loads with 4294967295 = default value to collide with all categories
        //
                    body.collisionBitMask = 0

以上是关于意外的物理体现在SpriteKit场景中的主要内容,如果未能解决你的问题,请参考以下文章

SpriteKit可摧毁物理场景的进一步完善

SPRITEKIT游戏框架之关于PHYSICS物理引擎属性

单视图应用程序中的 SpriteKit 场景?

使用 SpriteKit 场景编辑器设计复杂对象

Flask 编写http接口api及接口自动化测试

SpriteKit 动画意外停止