首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SKPhysicsBody优化

SKPhysicsBody优化
EN

Stack Overflow用户
提问于 2015-07-01 19:32:04
回答 2查看 117关注 0票数 1

我有一个2D侧滚游戏。现在,为了跳跃,玩家必须着地。因此,我有一个布尔值isOnGround,当玩家与瓷砖对象碰撞时设置为YES,当玩家跳跃时设置为no。这会产生对didBeginContact方法的大量调用,从而使游戏变慢。

首先,我如何通过对地板上的瓷砖使用一个大的物理体来优化这一点(例如,将多个相邻的瓷砖聚集到一个物理体中)?

其次,这是否有效?有没有更好的方法来检测游戏是否在地面上?我目前的方法打开了很多bug,比如跳墙。如果玩家与墙相撞,isOnGround将变为YES并允许玩家跳跃。

EN

回答 2

Stack Overflow用户

发布于 2015-07-01 20:32:13

didBeginContact被调用了无数次,这绝对不会降低你的游戏速度。如果您有性能问题,我怀疑问题可能出在其他地方。你是在设备上测试还是在模拟器上测试?

如果您正在使用平铺应用程序创建游戏地图,则可以使用对象层在地图中创建单个对象,您的代码稍后可以将其转换为物理实体。

使用物理和碰撞可能是最简单的方法,你可以确定你的球员的状态与地面接触。要解决墙的问题,只需使墙接触到与地面不同的类别。这将防止isOnGround被设置为YES。

票数 1
EN

Stack Overflow用户

发布于 2015-07-02 01:32:45

您可以使用物理引擎来检测何时启用了跳转(这就是我在游戏中经常做的事情)。然而,我也注意到使用物理引擎来检测单元何时在表面上的开销很大,这是因为在sprite套件中,无论出于什么原因,接触检测都是昂贵的,即使碰撞已经启用。甚至文档注释也是如此:

为获得最佳性能,请仅为您感兴趣的交互设置联系人掩码中的位。

所以我为我的游戏找到了一个更好的解决方案(它有25+同步单元,都需要表面检测)。而不是通过物理引擎,我只是做了我自己的表面计算和缓存的结果,每次游戏更新。如下所示:

代码语言:javascript
复制
final class func getSurfaceID(nodePosition: CGPoint) -> SurfaceID {
    //Loop through surface rects and see if position is inside.
}

我最终做的是通过检查我的单元的底点是否在任何表面框架内来处理我自己的表面检测。如果您的框架是轴对齐的(您的矩形没有旋转),您可以执行更快的检查,以查看点是否在框架内。

这是关卡设计方面的更多工作,因为你将需要从你的瓦片动态地构建一个表面框架数组,或者在你的世界中手动放置表面框架(这就是我所做的)。

进行此更改后,用于表面检测的cpu时间从20%以上减少到0.1%。它还允许我检查曲面上是否有任意点,而不是需要创建一个物理体(这是不必要的开销)。但是,如果您需要使用接触检测,则此解决方案显然不适用于您。

现在关于你关于从较小的物体创建一个大的物理体的观点。可以使用容器节点对相邻的地砖进行分组,并重新创建适合分组的节点的物理体。根据节点的分组方式和回收瓦片的方式,这可能会变得很复杂。一个更好的解决方案是创建大的物理实体,只覆盖你的瓷砖。这将减少整个物理体的数量,以及探测的数量。如果与surface frames解决方案结合使用,您可以真正减少开销。

我不确定你的游戏是如何设计的,以及它的要求是什么。我只是给你一些可能的解决方案,我在我的游戏中开发表面检测时看过了。如果你还没有,你应该明确地在仪器中分析你的游戏,看看接触检测是否真的是你开销的来源。如果你的游戏没有太多的联系人,我怀疑这就是开销的来源。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31160098

复制
相关文章

相似问题

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