【问题标题】:SKPhysicsBody nodes with child physicsbodys (node "range" value) performanceSKPhysicsBody 节点与子物理体(节点“范围”值)性能
【发布时间】:2014-08-02 21:08:28
【问题描述】:

我有一个自上而下的策略游戏。我当前的物理模拟具有可以自行接触和碰撞的节点。问题是我正在尝试找到一个解决方案,使我的联系人可以比碰撞更远(更大的圆圈)。原因很合乎逻辑,我想知道一个节点何时在另一个节点的“范围”内。

例如,想象一个精灵,其“范围”圆圈距离实际精灵 20 像素。

我尝试让精灵上的物理体大于精灵框架,但是碰撞是基于“范围圈”而不是精灵。

我还尝试向精灵添加一个 SKShapeNode 圆并添加一个物理体。问题是当我这样做时,子节点仍然与另一个子节点范围圆的物理体发生碰撞。

更不用说我只有大约 20 个节点(以及它们自己的物理体和范围节点及其物理体)的性能很快就向南了。

我更愿意在物理模拟中保持联系,而不是临时解决方案。

有什么想法/提示吗?

  // Mover physics
self.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:(self.frame.size.width/2)];
self.physicsBody.collisionBitMask = self.player == kPlayer_Human ? CATEGORY_HUMAN_MOVER : CATEGORY_AI_MOVER;
self.physicsBody.categoryBitMask = self.player == kPlayer_Human ? CATEGORY_HUMAN_MOVER : CATEGORY_AI_MOVER;
self.physicsBody.contactTestBitMask = 0;

_rangeNode = [SKShapeNode node];
_rangeNode.name = @"rangeNode";
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddArc(path, NULL, 0,0, _range, 0, M_PI*2, YES);
_rangeNode.path = path;
_rangeNode.lineWidth = 1.0;
_rangeNode.fillColor = [SKColor clearColor];
_rangeNode.strokeColor = [SKColor whiteColor];
_rangeNode.hidden = YES;

[self addChild:_rangeNode];

_rangeNode.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:_range];
_rangeNode.physicsBody.dynamic = NO;
_rangeNode.physicsBody.categoryBitMask = self.player == kPlayer_Human ? CATEGORY_HUMAN_MOVER_RANGE : CATEGORY_AI_MOVER_RANGE;
_rangeNode.physicsBody.contactTestBitMask = self.player == kPlayer_Human ? CATEGORY_AI_MOVER | CATEGORY_AI_HERO | CATEGORY_AI_TOWER : CATEGORY_HUMAN_MOVER | CATEGORY_HUMAN_HERO | CATEGORY_HUMAN_TOWER;
_rangeNode.physicsBody.collisionBitMask = 0;

类别定义,全局设置:

static const uint32_t CATEGORY_HUMAN_MOVER = 0x1 << 0;
static const uint32_t CATEGORY_AI_MOVER = 0x1 << 1;
static const uint32_t CATEGORY_HUMAN_HERO = 0x1 << 2;
static const uint32_t CATEGORY_AI_HERO = 0x1 << 3;
static const uint32_t CATEGORY_HUMAN_TOWER = 0x1 << 4;
static const uint32_t CATEGORY_AI_TOWER = 0x1 << 5;
static const uint32_t CATEGORY_WALLS = 0x1 << 6;
static const uint32_t CATEGORY_HUMAN_MOVER_RANGE = 0x1 << 7;
static const uint32_t CATEGORY_AI_MOVER_RANGE = 0x1 << 8;

谢谢, E

【问题讨论】:

  • 禁用 SKShapeNode 圆的碰撞并设置为仅接触。
  • ^ 通过将范围圆的碰撞位掩码设置为零。
  • 绝对是一个很棒的提示。直到节点在某个点汇集之前,任何地方都不会发生碰撞。一旦他们这样做(为了让他们分开),他们只会相互碰撞。即使范围圈设置为位掩码 = 0,并且节点主体设置为与自身发生碰撞,范围圈也会“推动”节点周围。我在上面添加了我的代码来提供帮助。
  • 如果您发布定义各种类别的代码将会很有用。出于性能原因,您不应将填充和描边颜色设置为清除。而是将范围圆的 alpha 设置为 0。如果您想查看物理实体(出于调试目的),请将视图的 showPhysics 属性设置为 YES。
  • 感谢您提供有关清晰颜色的提示。我一定会执行。当同一团队中的节点开始池化(3 个以上节点)时,会对性能产生重大影响。每个进入范围圈池的影响越来越大,我不明白,因为他们应该只对敌方节点使用接触,而不是彼此。

标签: ios sprite-kit physics-engine skphysicsbody


【解决方案1】:

我不确定您的问题实际上是什么,但请注意,您的“移动”节点的 SKPhysicsBody 设置为节点本身大小的两倍。仅此一项可能就是为什么您的节点会奇怪地相互“推动”。

其他注意事项/疑虑:

您为隐藏节点设置描边和填充颜色是否有特殊原因?

为什么要为范围物理体创建任意大小的父节点?如果您有一个具有相同范围圆物理主体的“空”节点,性能可能会提高吗?

如果在敌人接触/碰撞多个节点时性能受到影响,请注意您的接触处理例程(didBeginContactdidEndContact)。那里似乎有任何可能对性能产生不利影响的东西吗?

【讨论】:

  • shapeNodeWithCircleOfRadius:radius 仅适用于尚未发布的 iOS 8.0。
  • 玩家可以查看单位范围。 didBeginContact 现在也是空的。宽度设置是故障排除期间的一个临时值。代码已更新以反映。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多