Giz*_*zGo 0 xcode sprite-kit swift
我正在学习使用SpriteKit,我正在学习colllisions教程.我正在努力理解以下代码:
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
}
Run Code Online (Sandbox Code Playgroud)
为什么我们要分配这些被调用的东西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)
Run Code Online (Sandbox Code Playgroud)
谢谢!
BitMasks是用于描述二进制格式的项目的标志
所以想象你有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
Run Code Online (Sandbox Code Playgroud)
现在我有一个射手,想要归类他.我想说他是一个生活友好的单位
我会用它categoryBitmask来分类他:
archer.categoryBitmask = Ranged
这将以1字节表示为
00000010
||||||||_ Attackable
|||||||_ Ranged
||||||_ Undead
|||||_ Magic
||||_ Regenerate
|||_ Burning
||_ Frozen
|_ Poison
Run Code Online (Sandbox Code Playgroud)
现在让我们说他的箭是火箭,我会把它归类为:
arrow.categoryBitmask = Burning
00100000
||||||||_ Attackable
|||||||_ Ranged
||||||_ Undead
|||||_ Magic
||||_ Regenerate
|||_ Burning
||_ Frozen
|_ Poison
Run Code Online (Sandbox Code Playgroud)
最后,我们有一个可以被击中并随着时间的推移再生的僵尸
zombie.categoryBitmask = Attackable + Undead + Regenerate
00010101
||||||||_ Attackable
|||||||_ Ranged
||||||_ Undead
|||||_ Magic
||||_ Regenerate
|||_ Burning
||_ Frozen
|_ Poison
Run Code Online (Sandbox Code Playgroud)
现在我希望我的箭头只能击中Attackable精灵(在这种情况下是僵尸)
我会设置contactTestBitmask告诉箭头他能击中什么
arrow.contactTestBitmask = Attackable 00000001
Run Code Online (Sandbox Code Playgroud)
现在我们需要检查箭头何时击中僵尸,这就是didBeginContact进入的地方
什么didBeginContact都行,就是检查contactTestBitmask运动项目的categoryBitmask,碰撞通过使用与操作,以找到一个匹配
在我们的例子中
arrow.contactTestBitmask = 00000001
zombie.categoryMask = 00010101 AND
--------
00000001
Run Code Online (Sandbox Code Playgroud)
由于我们的值> 0,因此联系成功.
这意味着doBegins被解雇了.
现在我们在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
}
Run Code Online (Sandbox Code Playgroud)
由于箭头= 00100000和zombie = 00010101,我们知道僵尸的值比箭头低,所以在这种情况下,僵尸是<箭头.
我们分配firstBody给僵尸和secondBody箭头
现在我们需要提供一个条件.
我们想说一个不死生物是否被可燃物体击中,做一些事情.
所以在代码中这将是
if (firstBody & Undead > 0) && (secondBody & Burning > 0)
{
//burn zombie
}
Run Code Online (Sandbox Code Playgroud)
但是如果箭头是冰箭呢?我们不想进入if声明.
那么现在我们可以添加第二个条件,让我们冻结僵尸.
if (firstBody & Undead > 0) && (secondBody & Frozen > 0)
{
//freeze zombie
}
Run Code Online (Sandbox Code Playgroud)
这些ifs正在做什么,是确保身体已打开某些功能,然后执行一些操作以响应它们.
要了解有关位掩码如何工作的更多信息,我将研究如何制作真值表.这基本上就是这个.我们只是创建一些真值表,并试图弄清楚一个陈述是否为真,如果是真,则执行一个动作.
| 归档时间: |
|
| 查看次数: |
632 次 |
| 最近记录: |