I have a class that creates collectable items:
class CollectableCreate {
var collectable = SKSpriteNode()
var type = String()
var onCollect : () -> Void = {}
init(type: String, position: CGPoint, text: String = "This collectable uses no text!", onCollect : () -> Void) {
self.type = type.lowercaseString
switch self.type {
default:
collectable.size = CGSize(width: 1, height: 200)
collectable.color = SKColor.blueColor()
collectable.physicsBody = SKPhysicsBody(rectangleOfSize: collectable.size)
break
}
collectable.position = position
collectable.name = self.type
collectable.physicsBody?.categoryBitMask = PhysicsCategory.Collectable
collectable.physicsBody?.collisionBitMask = PhysicsCategory.Player
collectable.physicsBody?.contactTestBitMask = PhysicsCategory.Player
self.onCollect = onCollect
}
func chatBoxActivate() -> SKSpriteNode {
collectable.physicsBody?.dynamic = false
collectable.physicsBody?.affectedByGravity = false
return collectable
}
func collect() {
self.onCollect()
}
}
I create the collectable item like this:
let d = CollectableCreate(type: "chatbox", position: CGPoint(x: 500, y: 100), onCollect: {
self.createChatBox("test blalb|blablalba")
})
self.addChild(d.chatBoxActivate())
And on didBeginContact I have this:
if (firstBody.categoryBitMask == PhysicsCategory.Collectable || secondBody.categoryBitMask == PhysicsCategory.Collectable) {
let collectableBody = (firstBody.categoryBitMask == PhysicsCategory.Collectable ? firstBody.node : secondBody.node)
//collectableBody.collect() <---
collectableBody?.removeFromParent()
}
I want to run the CollectableCreate().collect()
function when I run into a collectable. How to I make this happen?
I'm afraid i'm shooting in the dark here since i've never worked with SpriteKit
, so please feel free to add to/or edit my answer.
You should subclass SKSpriteNode
:
class Collectable : SKSpriteNode {
var type: String?
var onCollect: (() -> ())?
convenience init(type: String, position: CGPoint, text: String = "This collectable uses no text!", onCollect : () -> Void) {
self.init()
self.type = type.lowercaseString
switch self.type {
default:
self.size = CGSize(width: 1, height: 200)
self.color = SKColor.blueColor()
self.physicsBody = SKPhysicsBody(rectangleOfSize: self.size)
break
}
self.position = position
self.name = self.type
self.physicsBody?.categoryBitMask = PhysicsCategory.Collectable
self.physicsBody?.collisionBitMask = PhysicsCategory.Player
self.physicsBody?.contactTestBitMask = PhysicsCategory.Player
self.onCollect = onCollect
}
func chatBoxActivate() -> SKSpriteNode {
self.physicsBody?.dynamic = false
self.physicsBody?.affectedByGravity = false
return self
}
func collect(){
self.onCollect?()
}
}
And use it in the following matter, and add whatever class you are subclassing in your controller, and add the correct delegates:
class SomeClass {
func someFunc(){
let collectable = Collectable(type: "chatbox", position: CGPoint(x: 500, y: 100), onCollect: {
self.createChatBox("FooBar")
})
self.addChild(collectable.chatBoxActivate())
}
func didBeginContact(contact: SKPhysicsContact){
let firstBody = contact.bodyA
let secondBody = contact.bodyB
if (firstBody.categoryBitMask == PhysicsCategory.Collectable || secondBody.categoryBitMask == PhysicsCategory.Collectable) {
let collectableBody = firstBody.categoryBitMask == PhysicsCategory.Collectable ? firstBody.node : secondBody.node
if let collectable = collectableBody as? Collectable {
collectable.collect()
}
collectableBody?.removeFromParent()
}
}
func addChild(collectable: SKSpriteNode){
// Some logic
}
func createChatBox(text: String) {
// Some logic
}
}
Hope this can point you in the right direction!