Reputation: 28
So im currently working on a game with spriteKit
and gameplayKit
. I've created a custom GKComponent
class that I'm giving to certain SKSpriteNode
via the scene inspector in Xcode (image). Now, when I want to re-create random SKSpritenodes
with the same GKComponent
, it doesn't seems to work because the overridden update method of my custom GKComponent
is not working. Any clues?
I've tried to give the node a new entity object (since it was returning nil) and I gave that entity my custom GKComponent
but nothing is working
// In scene
let node = SKSpriteNode(texture: "coin", color: UIColor.clear, size: CGSize(width: 60, height: 60))
let entities: GKEntity! = GKEntity()
let component: CollectableComponent = CollectableComponent()
component.itemType = 1
node.anchorPoint = CGPoint(x: 0.5, y: 0.5)
node.zPosition = 6
node.setScale(0.5)
node.size = CGSize(width: 60, height: 60)
node.position = CGPoint(x: 90, y: 90)
entities.addComponent(component)
node.entity = entities
self.scene?.addChild(node)
// GKComponent
class CustomComponent: GKComponent {
var node: SKSpriteNode?
@GKInspectable var itemType: Int = 0
@GKInspectable var isStatic: Bool = false
override init() {
super.init()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func update(deltaTime seconds: TimeInterval) {
if node == nil {
if let nodeComponent = self.entity?.component(ofType: GKSKNodeComponent.self){
node = nodeComponent.node as? SKSpriteNode
}
}
}
}
Desired behaviour: if the nodeComponent
variable in CustomComponent
is not nil, I would like to make it run an animation like this:
node = nodeComponent.node as? SKSpriteNode; node.run(SKAction.moveBy(x: 0, y: 15, duration: 0.3));
but with the code, the action would not be running
Upvotes: 0
Views: 557
Reputation: 16827
This is the way you want to be doing this.
Take note that you need to retain your entities, so a global variable is needed.
Also, when you add a node to GKSKNodeComponent
, the node.entity
variable is set automatically.
class GameScene : SKScene{
var entities: [GKEntity] = [GKEntity]()
func doSomething(){
let node = SKSpriteNode(texture: "coin", color: UIColor.clear, size: CGSize(width: 60, height: 60))
node.anchorPoint = CGPoint(x: 0.5, y: 0.5)
node.zPosition = 6
node.setScale(0.5) //<--- YUCK!!!!!
node.size = CGSize(width: 60, height: 60)
node.position = CGPoint(x: 90, y: 90)
self.scene?.addChild(node)
let entity = GKEntity()
let nodeComponent : GKSKNodeComponent = GKSKNodeComponent(node:node)
let component: CollectableComponent = CollectableComponent()
component.itemType = 1
entity.addComponent(nodeComponent)
entity.addComponent(component)
entities.append(entity)
}
}
// GKComponent
class CustomComponent: GKComponent {
//We want this line to crash if node is empty, so do not use ?
lazy var node: SKSpriteNode! = {return self.entity!.component(ofType: GKSKNodeComponent.self).node as? SKSpriteNode! }
@GKInspectable var itemType: Int = 0
@GKInspectable var isStatic: Bool = false
override init() {
super.init()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func update(deltaTime seconds: TimeInterval) {
}
}
Upvotes: 2