sprite kit - How to interpret this Swift SpriteKit example code of a physics body bitmask system -


i taking deep apples spritekit & gameplaykit example code , found project called 'demobots' written in swift. there interesting concepts used in projects wanted adapt projects.

i working encapsulating collision-handling handler-class similar way collisions handled in example code.

in project found following code struct called rpcollidertype:

struct rpcollidertype: optionsettype, hashable, customdebugstringconvertible {     // mark: static properties      /// dictionary specify `collidertype`s should notified of contacts other `collidertype`s.     static var requestedcontactnotifications = [rpcollidertype: [rpcollidertype]]()      /// dictionary of `collidertype`s should collide 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      /// value can assigned 'skphysicsbody`'s `categorymask` property.     var categorymask: uint32 {         return rawvalue     }      /// value can assigned 'skphysicsbody`'s `collisionmask` property.     var collisionmask: uint32 {         // combine of collision requests type using bitwise or.         let mask = rpcollidertype.definedcollisions[self]?.reduce(rpcollidertype()) { initial, collidertype in             return initial.union(collidertype)         }          // provide rawvalue of resulting mask or 0 (so object doesn't collide anything).         return mask?.rawvalue ?? 0     }      /// value can assigned 'skphysicsbody`'s `contactmask` property.     var contactmask: uint32 {         // combine of contact requests type using bitwise or.         let mask = rpcollidertype.requestedcontactnotifications[self]?.reduce(rpcollidertype()) { initial, collidertype in             return initial.union(collidertype)         }          // provide rawvalue of resulting mask or 0 (so object doesn't need contact callbacks).         return mask?.rawvalue ?? 0     }      // mark: contactnotifiabletype convenience      /**         returns `true` if `contactnotifiabletype` associated `collidertype` should         notified of contact passed `collidertype`.     */     func notifyoncontactwithcollidertype(collidertype: rpcollidertype) -> bool {         if let requestedcontacts = rpcollidertype.requestedcontactnotifications[self] {             return requestedcontacts.contains(collidertype)         }          return false     } } 

this struct used every time set .collisionbitmask / .contactbitmask / .categorybitmask property of skphysicsbody this: (i have implemented using component & entity design guide)

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     } } 

so far good. coming objective-c problem not understand following lines of code out of rpcollidertype struct do:

/// value can assigned 'skphysicsbody`'s `collisionmask` property. var collisionmask: uint32 {     // combine of collision requests type using bitwise or.     let mask = rpcollidertype.definedcollisions[self]?.reduce(rpcollidertype()) { initial, collidertype in         return initial.union(collidertype)     }      // provide rawvalue of resulting mask or 0 (so object doesn't collide anything).     return mask?.rawvalue ?? 0 } 

does mean every time call computed (that's called in swift, right?) property - when assign skphysicsbody - adds static class dictionaries. have problem interpreting 'mask' / 'reduce' / 'union' commands.

what do?

collisionmask computed property returns uint32 value can used physics body's collision bit mask. it's easier understand how computed property works if broken down functional parts.

but first, let's add array of rpcollidertype objects playerbot should collide definedcollisions dictionary:

rpcollidertype.definedcollisions[.playerbot] = [.obstacle, .taskbot] 

at point, definedcollisions dictionary contains single item playerbot , [.obstacle, .taskbot] key , value, respectively. think of categories can collide playerbot obstacle , taskbot.

we can use .playerbot retrieve value (i.e., array) dictionary:

let array = rpcollidertype.definedcollisions[.playerbot] 

since collisionmask defined in rpcollidertype, self used dictionary key. also, array optional since value corresponding key may not exist in dictionary.

the code combines array of rpcollidertype objects single rpcollidertype object using reduce method. reduce takes 2 arguments: initial value (with same type elements of array) , function (or closure) takes value argument , returns value. in case, initial value new rpcollidertype object , closure's argument , returned value rpcollidertype objects:

array?.reduce(rpcollidertype(), afunction) 

apple's code uses trailing closure instead of passing function reduce. docs,

if need pass closure expression function function’s final argument , closure expression long, can useful write trailing closure instead. trailing closure closure expression written outside of (and after) parentheses of function call supports.

reduce iterates on array , calls closure initial value , each array element arguments , returned value used initial value next iteration:

let mask = array?.reduce(rpcollidertype()) {     initial, collidertype in     return initial.union(collidertype) } 

where initial keeps intermediate union of rpcollidertype array elements , collidertype current element of array.

at point, mask rpcollidertype object can convert uint32 with

mask?.rawvalue 

which returned value of collisionmask computed property.


Comments

Popular posts from this blog

php - Wordpress website dashboard page or post editor content is not showing but front end data is showing properly -

javascript - Get parameter of GET request -

javascript - Twitter Bootstrap - how to add some more margin between tooltip popup and element -