如何使用collisionBitMask?斯威夫特/ SpriteKit

据我所知,物理机构的认值是在彼此碰撞时将其碰撞BitMask设置为相等数字.

然而,我有一个巨大的问题,完成似乎应该是非常简单的,因为碰撞我相信的Bitmasks.

let RedBallCategory  : UInt32 = 0x1 << 1
    let GreenBallCategory: UInt32 = 0x1 << 2
    let RedBarCategory : UInt32 = 0x1 << 3
    let GreenBarCategory : UInt32 = 0x1 << 4
    let WallCategory : UInt32 = 0x1 << 5


      greenBall.physicsBody?.categoryBitMask = GreenBallCategory
       greenBall.physicsBody?.contactTestBitMask = RedBarCategory
        greenBall.physicsBody?.collisionBitMask = GreenHealthCategory

 redBall.physicsBody?.categoryBitMask = RedBallCategory
        redBall.physicsBody?.contactTestBitMask = GreenBarCategory
       redBall.physicsBody?.collisionBitMask = RedHealthCategory

   let borderBody = SKPhysicsBody(edgeLoopFromrect: self.frame)
    self.physicsBody = borderBody
    self.physicsBody?.friction = 0
    borderBody.contactTestBitMask = RedBallCategory | GreenBallCategory
   borderBody.categoryBitMask = WallCategory

所以这里有我的2个球和我的边界的身体.我可以获得我想要的碰撞检测,但是当我添加边框体的类别位掩码时,它允许球通过和关闭屏幕,我不想要的.

我也想让球弹起来,但只有当我发表一个球的类别BitMasks时,他们反弹.否则他们会相互通过.

这对我来说完全没有意义,因为这些项目中的每一个都有不同的碰撞掩码.我也有时候将所有的数字设置为等于5将允许所有的东西通过对方,但是然后将它设置为6将允许所有的东西相互碰撞.

碰撞位掩码的工作原理是什么?是否有正确的方式来管理很多交叉的碰撞规则?

您无法获得所需的行为,因为您尚未正确设置类别,联系人和碰撞位掩码.以下是一个如何设置此工作的示例:
greenBall.physicsBody?.categoryBitMask = GreenBallCategory //Category is GreenBall
greenBall.physicsBody?.contactTestBitMask = RedBarCategory | WallCategory //Contact will be detected when GreenBall make a contact with RedBar or a Wall (assuming that redBar's masks are already properly set)
greenBall.physicsBody?.collisionBitMask = GreenBallCategory | RedBallCategory | WallCategory //Collision will occur when GreenBall hits GreenBall,RedBall or hits a Wall

redBall.physicsBody?.categoryBitMask = RedBallCategory //Category is RedBall
redBall.physicsBody?.contactTestBitMask = GreenBarCategory | GreenBallCategory | WallCategory //Contact will be detected when RedBall make a contact with GreenBar,GreenBall or a Wall
redBall.physicsBody?.collisionBitMask = RedBallCategory | GreenBallCategory | WallCategory //Collision will occur when RedBall meets RedBall,GreenBall or hits a Wall

let borderBody = SKPhysicsBody(edgeLoopFromrect: self.frame)
self.physicsBody = borderBody
self.physicsBody?.friction = 0
borderBody.contactTestBitMask = RedBallCategory | GreenBallCategory //Contact will be detected when red or green ball hit the wall
borderBody.categoryBitMask = WallCategory
borderBody.collisionBitMask = RedBallCategory | GreenBallCategory // Collisions between RedBall GreenBall and a Wall will be detected

我建议您阅读约categoryBitMask的文档,这是一个面具,用于定义物理主体所属的类别:

Every physics body in a scene can be assigned to up to 32 different
categories,each corresponding to a bit in the bit mask. You define
the mask values used in your game. In conjunction with the
collisionBitMask and contactTestBitMask properties,you define which
physics bodies interact with each other and when your game is notified
of these interactions.

contactTestBitMask一个面具,用于定义哪些类别的物体与当前物理体引起交集通知.

When two bodies share the same space,each body’s category mask is
tested against the other body’s contact mask by performing a logical
AND operation. If either comparison results in a nonzero value,an
SKPhysicsContact object is created and passed to the physics world’s
delegate. For best performance,only set bits in the contacts mask for
interactions you are interested in.

collisionBitmask一个面具,用于定义哪些类别的物理物体可以与这个物理体碰撞.

When two physics bodies contact each other,a collision may occur.
This body’s collision mask is compared to the other body’s category
mask by performing a logical AND operation. If the result is a nonzero
value,this body is affected by the collision. Each body independently
chooses whether it wants to be affected by the other body. For
example,you might use this to avoid collision calculations that would
make negligible changes to a body’s veLocity.

所以基本上,要设置所有这些,你应该问你自己的东西:

好吧,我有一个绿色的球,一个红色的球,和墙上的对象现场.在哪些机构我想要碰撞发生,或当我想要注册联系人?我想要一个绿色和一个红色的球相互碰撞并碰撞墙壁.不是问题我将首先正确设置类别,然后我将设置这样的碰撞位掩码:

greenBall.collisionBitMask = GreenBallCategory | RedBallCategory | WallCategory; //greenBall will collide with greenBall,redBall and a wall
redBall.collisionBitMask = GreenBallCategory | RedBallCategory | WallCategory

wall.collisionBitMask = GreenBall | RedBall

现在,我想检测一些联系人发生的时间(inBeginContact:method)…但是我不想收到所有可能的联系人的通知,而是要通知球之间的联系(球和墙之间的联系将被忽略).所以让我们设置contactTestBitMasks来实现这一点:

greenBall.contactTestBitMask = GreenBallCategory | RedBallCategory;
redBall.contactTestBitMask = GreenBallCategory | RedBallCategory;

就是这样重要的是当您不使用联系人检测时,不应设置contactTestBitMask.这是因为性能原因.如果您不需要碰撞检测,并且您只对检测到联系人感兴趣,可以设置collisionBitMask = 0.

重要:

确保您已设置物理世界的联系人委托以使用didBeginContact和didEndContact方法

self.physicsWorld.contactDelegate = self; //where self is a current scene

希望这有帮助.

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...