gpt4 book ai didi

swift - 了解 SpriteKit CollisionBitMask

转载 作者:行者123 更新时间:2023-11-28 09:35:31 24 4
gpt4 key购买 nike

我正在学习使用 SpriteKit 并且正在学习碰撞教程。我正在努力理解以下代码:

struct PhysicsCategory {
static let None : UInt32 = 0
static let All : UInt32 = UInt32.max
static let Monster : UInt32 = 0b1 // 1
static let Projectile: UInt32 = 0b10 // 2
}

为什么我们分配这些称为 bitMaps 的东西以及它们稍后在下面的代码中如何工作?:

func didBegin(_ contact: SKPhysicsContact) {

// 1
var firstBody: SKPhysicsBody
var secondBody: SKPhysicsBody
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
firstBody = contact.bodyA
secondBody = contact.bodyB
} else {
firstBody = contact.bodyB
secondBody = contact.bodyA
}

// 2
if ((firstBody.categoryBitMask & PhysicsCategory.Monster != 0) &&
(secondBody.categoryBitMask & PhysicsCategory.Projectile != 0)) {
if let monster = firstBody.node as? SKSpriteNode, let
projectile = secondBody.node as? SKSpriteNode {
projectileDidCollideWithMonster(projectile: projectile, monster: monster)

谢谢!

最佳答案

位掩码是用于描述二进制格式的项目的标志

假设您有 8 种方式来描述某事。 (在 Spritekit 中你有 32 个)

我们可以将这 8 个东西放入一个字节中,因为 8 位在一个字节中,使我们能够节省空间并更快地执行操作。

这里是8个描述的例子

Attackable 1 << 0  
Ranged 1 << 1
Undead 1 << 2
Magic 1 << 3
Regenerate 1 << 4
Burning 1 << 5
Frozen 1 << 6
Poison 1 << 7

现在我有一个弓箭手,想对他进行分类。我想说他是一个远程的生活友好单位

我会使用 categoryBitmask 来分类他:

archer.categoryBitmask = 范围

这将用 1 个字节表示为

00000010
||||||||_ Attackable
|||||||_ Ranged
||||||_ Undead
|||||_ Magic
||||_ Regenerate
|||_ Burning
||_ Frozen
|_ Poison

现在假设他的箭是火箭,我会这样分类:

arrow.categoryBitmask = 燃烧

00100000
||||||||_ Attackable
|||||||_ Ranged
||||||_ Undead
|||||_ Magic
||||_ Regenerate
|||_ Burning
||_ Frozen
|_ Poison

最后,我们有一个可以被击中并随时间再生的僵尸

zombie.categoryBitmask = 可攻击 + 亡灵 + 再生

00010101
||||||||_ Attackable
|||||||_ Ranged
||||||_ Undead
|||||_ Magic
||||_ Regenerate
|||_ Burning
||_ Frozen
|_ Poison

现在我希望我的箭只击中Attackable Sprite (在本例中为僵尸)

我会设置 contactTestBitmask 来告诉箭头他可以击中什么

arrow.contactTestBitmask = Attackable 00000001

现在我们需要检查箭头何时击中僵尸,这就是 didBeginContact 的用武之地

didBeginContact 将做的是检查移动项目的 contactTestBitmask 到它通过使用 AND 操作找到的 categoryBitmask一场比赛

在我们的例子中

arrow.contactTestBitmask =  00000001
zombie.categoryMask = 00010101 AND
--------
00000001

因为我们的值 > 0,所以联系成功。

这意味着 didBegins 被解雇了。

现在我们在 didBegins 中,我们需要确定哪个物理体是我们的箭头,哪个物理体是我们的僵尸

这就是下一条声明的用武之地

func didBegin(_ contact: SKPhysicsContact) {

// 1
var firstBody: SKPhysicsBody
var secondBody: SKPhysicsBody
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
firstBody = contact.bodyA
secondBody = contact.bodyB
} else {
firstBody = contact.bodyB
secondBody = contact.bodyA
}

由于 arrow = 00100000 和 zombie = 00010101,我们知道 zombie 的值比 arrow 低,所以在这种情况下,zombie 是 < arrow.

我们将 firstBody 分配给僵尸,将 secondBody 分配给箭头

现在我们需要提供一个条件。

我们想说,如果一个不死生物被可燃物体击中,就做点什么。

所以在代码中这将是

if (firstBody & Undead > 0) && (secondBody & Burning > 0)
{
//burn zombie
}

但如果箭是冰箭呢?我们不想讨论那个 if 语句。

现在我们可以添加第二个条件来卡住僵尸。

if (firstBody & Undead > 0) && (secondBody & Frozen > 0)
{
//freeze zombie
}

这些 if 的作用是确保 body 开启了某些功能,然后执行一些 Action 来响应它们。

要了解有关位掩码工作原理的更多信息,我会研究如何制作真值表。这基本上就是归根结底的原因。我们只是创建一些真值表,并试图确定一个陈述是否为真,如果为真,则执行一个操作。

关于swift - 了解 SpriteKit CollisionBitMask,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46494701/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com