我仔细研究了苹果的SpriteKit和GameplayKit示例代码,并发现一个名为'DemoBots'的Swift项目。在这个项目中使用了一些非常有趣的概念,我希望将它们融入到我的项目中。我已经开始尝试将碰撞处理封装到一个处理类中,这与该示例代码处理碰撞的方式非常相似。
在这个项目中,我找到了一个名为
这个结构体被用于每次设置
在这个项目中,我找到了一个名为
RPColliderType
的结构体的以下代码:struct RPColliderType: OptionSetType, Hashable, CustomDebugStringConvertible {
// MARK: Static properties
/// A dictionary to specify which `ColliderType`s should be notified of contacts with other `ColliderType`s.
static var requestedContactNotifications = [RPColliderType: [RPColliderType]]()
/// A dictionary of which `ColliderType`s should collide with other `ColliderType`s.
static var definedCollisions = [RPColliderType: [RPColliderType]]()
// MARK: Properties
let rawValue: UInt32
// MARK: Options
static var Obstacle: RPColliderType { return self.init(rawValue: 1 << 0) }
static var PlayerBot: RPColliderType { return self.init(rawValue: 1 << 1) }
static var TaskBot: RPColliderType { return self.init(rawValue: 1 << 2) }
// MARK: Hashable
var hashValue: Int {
return Int(rawValue)
}
// MARK: SpriteKit Physics Convenience
/// A value that can be assigned to a 'SKPhysicsBody`'s `categoryMask` property.
var categoryMask: UInt32 {
return rawValue
}
/// A value that can be assigned to a 'SKPhysicsBody`'s `collisionMask` property.
var collisionMask: UInt32 {
// Combine all of the collision requests for this type using a bitwise or.
let mask = RPColliderType.definedCollisions[self]?.reduce(RPColliderType()) { initial, colliderType in
return initial.union(colliderType)
}
// Provide the rawValue of the resulting mask or 0 (so the object doesn't collide with anything).
return mask?.rawValue ?? 0
}
/// A value that can be assigned to a 'SKPhysicsBody`'s `contactMask` property.
var contactMask: UInt32 {
// Combine all of the contact requests for this type using a bitwise or.
let mask = RPColliderType.requestedContactNotifications[self]?.reduce(RPColliderType()) { initial, colliderType in
return initial.union(colliderType)
}
// Provide the rawValue of the resulting mask or 0 (so the object doesn't need contact callbacks).
return mask?.rawValue ?? 0
}
// MARK: ContactNotifiableType Convenience
/**
Returns `true` if the `ContactNotifiableType` associated with this `ColliderType` should be
notified of contact with the passed `ColliderType`.
*/
func notifyOnContactWithColliderType(colliderType: RPColliderType) -> Bool {
if let requestedContacts = RPColliderType.requestedContactNotifications[self] {
return requestedContacts.contains(colliderType)
}
return false
}
}
这个结构体被用于每次设置
.collisionBitmask
/ .contactBitmask
/ .categoryBitmask
属性的时候,比如这样:(我已经按照组件和实体设计指南实现了这个)class RPPhysicsComponent: GKComponent {
var physicsBody: SKPhysicsBody
init(physicsBody: SKPhysicsBody, colliderType: RPColliderType) {
self.physicsBody = physicsBody
self.physicsBody.categoryBitMask = colliderType.categoryMask
self.physicsBody.collisionBitMask = colliderType.collisionMask
self.physicsBody.contactTestBitMask = colliderType.contactMask
}
}
目前为止,一切都很好。由于我来自Objective-C,我的问题是我不完全理解RPColliderType结构中以下代码的含义:
/// A value that can be assigned to a 'SKPhysicsBody`'s `collisionMask` property.
var collisionMask: UInt32 {
// Combine all of the collision requests for this type using a bitwise or.
let mask = RPColliderType.definedCollisions[self]?.reduce(RPColliderType()) { initial, colliderType in
return initial.union(colliderType)
}
// Provide the rawValue of the resulting mask or 0 (so the object doesn't collide with anything).
return mask?.rawValue ?? 0
}
这是否意味着每次我调用计算属性(在Swift中称为计算属性),例如当我将其分配给SKPhysicsBody
时,它会将此添加到这些静态类字典中。但我对“mask
”、“reduce
”和“union
”命令的解释存在问题。
那真正的作用是什么呢?
OptionSetType
管理类别、碰撞和接触位掩码的好例子。 - 0x141E