首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >意外physicsBody在SpriteKit场景中的应用

意外physicsBody在SpriteKit场景中的应用
EN

Stack Overflow用户
提问于 2017-01-03 14:50:03
回答 3查看 603关注 0票数 7

我正在用SKPhysicsJointSpring实现一个质量弹簧系统(许多小的物理体和SpriteKit实例一起使用)。一些粒子在穿过场景中心时会被卡住。

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

这里有一个简单的方法可以看出我说的是什么:

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

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

有人知道怎么摆脱它吗?

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

GameViewController.viewDidLoad()中,我替换了以下内容:

代码语言:javascript
复制
// Load the SKScene from 'GameScene.sks'
if let scene = SKScene(fileNamed: "GameScene") {
    view.presentScene(scene)
}

在这方面:

代码语言:javascript
复制
let scene = GameScene(size: view.frame.size)
scene.anchorPoint = CGPoint(x: 0.5, y: 0.5)
view.presentScene(scene)

但这并没有解决问题。

EN

回答 3

Stack Overflow用户

发布于 2017-01-03 20:58:31

无论如何,我决定做一个答复,因为评论不合适,因为我想分享的信息很多。很遗憾,我的回答没有回答这个问题,但它提供了一些关于这个不明的,显然能够飞行(物理体)物体的有用信息:)

这就是如何抓取它的代码(并修改它?):

代码语言:javascript
复制
 //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)")
}

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

不过,就像我在评论中说的,我不知道它为什么在那里,它代表着什么,它的目的是什么。

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

假设有三个SKSpriteNode对象同时相交(例如A、联系人B和A联系人C同时)。SpriteKit只能同时处理一个联系人。当A和B接触时,你要从父母那里移除A,然后,A和C之间也有一个接触,所以didBegin:(_ contact)会被调用两次。如果在第一次didBegin(_ contact)调用中将A从其父调用中移除,那么在下一次didBegin(_ contact)调用中,bodyA.node将为零(bodyA是雪碧A的物理体),但它的物理体将保持可见状态,直到引擎完成所需的操作。这是因为节点树和物理世界是分开的。

票数 3
EN

Stack Overflow用户

发布于 2017-01-03 17:24:09

关于"hello world“xCode游戏模板,它似乎与GameScene节点相关联。通过一些代码,我找到了以下内容:

代码语言:javascript
复制
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)")
        }
    }
}

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

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

票数 2
EN

Stack Overflow用户

发布于 2018-03-21 01:00:01

我也有过类似的问题。我有一个游戏,两个精灵节点连接在一起(SKPhysicsJointFixed.joint),在SKEditor创建的场景周围移动。根据我的设计,这对节点将影响第三个精灵节点,并顺利地离开第三个精灵节点,除非冲击位于场景的中心。对于场景的中心影响,节点对将压缩在一起,而从第三个精灵节点,呈现出一个糟糕的图形图像。

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

顺便说一下,加载时categoryBitMask是0。

代码语言:javascript
复制
        //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
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41446160

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档