为什么 didBeginContact 被多次调用? [英] Why are didBeginContact called multiple times?

查看:35
本文介绍了为什么 didBeginContact 被多次调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在一个使用 Sprite Kit 以及 Sprite Kit 内置物理引擎中的接触检测的 iOS 游戏中,我会在英雄每次与敌人接触时减少 1 的生命.这是通过 didBeginContact 方法完成的.然而,这个方法似乎不是只在接触开始时调用一次,而是只要英雄和敌人重叠就会持续调用:当我在该方法中设置断点时,我可以看到,它是完全相同的作为 contact.bodyAcontact.bodyB 存在的物理体实例.结果是,即使英雄只通过了一个敌人,他也会失去多条生命.

In an iOS game that uses Sprite Kit along with the contact detection in Sprite Kit's build-in physics engine, I decrease the Hero's number lives by one each time he gets in contact with an enemy. This is done from the didBeginContact method. However, it seems like that method is not just called once, when the contact begins, but called continuously as long as the Hero and the enemy overlaps: when I set a breakpoint in that method, I can see, that it is the exact same physics body instances that exist as contact.bodyA and contact.bodyB. The result is, that the Hero will lose multiple lives, even though he only passes one single enemy.

如果英雄稍后再次遇到相同的敌人,他应该再减去一个活体,因此我不能只维护一个seenEnemies哈希集来处理上述问题.

If the Hero meets the same enemy again later, he should get one more live subtracted, and therefore I cannot just maintain a seenEnemies hash set to deal with the problem above.

现在的问题是:你如何确保每个英雄/敌人接触只减去一个生命?

The question is now: how would you make sure that only one live is subtracted for each Hero/enemy contact?

推荐答案

我遇到了同样的问题(单个敌人被摧毁时分数会增加多次,并且单个伤害实例会损失多个生命点.)Apple 论坛认为这是[SKPhysicsBody bodyWithTexture:size:] 中的一个错误,但我不认为是这种情况,因为它也发生在其他构造函数中.

I had the same problem (score increasing multiple times for a single enemy destroyed and multiple life points being lost for a single instance of damage.) A user on the Apple forums thinks that it's a bug in [SKPhysicsBody bodyWithTexture:size:] but I don't believe that's the case, because it was happening with other constructors too.

首先,categoryBitMaskcontactTestBitMask 显然非常重要.看看 Apple 的 SpriteKit 物理碰撞示例代码:

First off, the categoryBitMask and contactTestBitMask are very important, obviously. Take a look at Apple's SpriteKit Physics Collisions sample code:

//联系人往往是双重调度问题;您想要的效果基于接触中两个实体的类型.通过检查每个的类型,以蛮力的方式对此进行采样.一个更复杂的例子可能是使用对象的方法来执行类型检查.

// Contacts are often a double dispatch problem; the effect you want is based on the type of both bodies in the contact. This sample this in a brute force way, by checking the types of each. A more complicated example might use methods on objects to perform the type checking.

//联系人可以按任意顺序出现,因此通常您需要检查互相反对.在这个例子中,类别类型是有序的,所以如果它们乱序,代码会交换两个主体.这允许代码只测试一次碰撞.

// The contacts can appear in either order, and so normally you'd need to check each against the other. In this example, the category types are well ordered, so the code swaps the two bodies if they are out of order. This allows the code to only test collisions once.

我为解决它所做的是在处理每个条件后设置一个标志.就我而言,我正在测试 bodyA.node.parentdidBeginContact 中是否为零,因为我在导弹/敌人上调用了 removeFromParent()节点来销毁它们.

What I did to solve it was setting a flag after handling each condition. In my case, I was testing whether bodyA.node.parent was nil in didBeginContact, because I called removeFromParent() on the missile/enemy nodes to destroy them.

我认为您应该期望该事件多次触发,并且您的代码必须确保它只被处理一次.

I think you should expect the event to fire multiple times and your code in there has to make sure it's processed only once.

这篇关于为什么 didBeginContact 被多次调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆