我用SpriteKit实现了一个质量弹簧系统(许多小型物理机构与SKPhysicsJointSpring实例连接在一起)。一些粒子在穿过场景中心时会被钩住。
在场景中间似乎有一个小而静止的身体,我不知道它为什么会在那里。
这里有一个简单的方法可以看到我在谈论的内容:
GameViewController.viewDidLoad()
中,添加view.showsPhysics = true
如果你运行项目,你应该在中间看到一个小点,这是错误的身体:
任何人都知道如何摆脱它?
编辑:我尝试手动创建场景对象:
在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)
但是没有解决它。
答案 0 :(得分:2)
关于“ 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)")
}
}
}
使用最后一个大括号的断点,你可以看到两个实体(可能是一个实体数组),其中一个是左边的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)
答案 1 :(得分:2)
无论如何,我决定回答是因为我想分享很多信息,因此评论不合适。可悲的是,我的回答并没有回答这个问题,但是它提供了一些关于这个身份不明的,有明显能够飞行(物理身体)对象的有用信息:)
所以这是代码如何抓取它(并修改它):
//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
),但在{{1 }}设置为showsPhysics
,有一个合理的解释。物理世界与节点树分开。所以我们可以从节点树中删除一个精灵,但这并不意味着它的物理体将被立即删除。物理引擎可能还没有完成模拟......所以你可能想知道,这会怎么样?
假设你有三个同时交叉的true
个物体(比如A个联系人B和A联系人C同时)。 SKSpriteNode
只能处理一个联系人。并且说当你与B联系时你从父母那里删除A.然后,A和C之间也有联系,所以SpriteKit
将被调用两次。如果您在第一个didBegin:(_ contact)
来电中从其父级中移除A,则在下一个didBegin(_ contact)
来电中,didBegin(_ contact)
将为零(bodyA.node
是精灵A的物理主体),但它的物理机构将保持可见,直到发动机完成所需的任务。这是因为节点树和物理世界是分开的。
答案 2 :(得分:1)
我有类似的问题。我有一个游戏,两个精灵节点连接在一起(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