私はApples SpriteKit & GameplayKitのサンプルコードをよく見て、Swiftで書かれた 'DemoBots'というプロジェクトを見つけました。私が自分のプロジェクトに適応させたいと思っていたプロジェクトには、非常に興味深い概念がいくつかあります。このSwift SpriteKitのフィジックスボディビットマスクシステムのコード例
私はすでに衝突ハンドリングをハンドラクラスにカプセル化しています。これは、そのコード例で衝突が処理される方法に非常に似ています。この構造体は、あなたがこのようなSKPhysicsBody
の.collisionBitmask
/.contactBitmask
/.categoryBitmask
プロパティを設定するたびに使用されて
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
}
}
:このプロジェクトで
私は構造体の次のコードは、RPColliderType
と呼ばれた(私が実施していますこのコンポーネント&実体設計ガイドを使用して)これまで
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
}
}
とても良いです。それは私が呼ぶたびに計算されたことをことを意味してい
/// 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
}
(つまり、彼らは呼ばれているものです:私の問題は、私は完全にRPColliderType構造体のうち、コードのものを次の行は何をすべきか理解していないということであるObjective-Cのから来ます私はこれをSKPhysicsBody
に割り当てると、静的なクラス辞書に追加されます。しかし、私は 'mask
'/'reduce
'/'union
'のコマンドを解釈する際に問題があります。
本当にそれは何ですか?
このような詳細な説明ありがとうございます。ほとんどあなたのようなビットは、このコードを書いています!しかしながら。私の理解から、これは非常にエレガントなコードですね。 –
ようこそ。このコードは、 'OptionSetType'を使用してカテゴリ、衝突、およびコンタクトビットマスクを管理する方法の良い例です。 – 0x141E