If you want to add/remove components at runtime, not only at the entity’s creation, how do you suggest to deal with that? Add helper methods to EntityManager and deal with the ComponentSystems from there?
Also is it possible to combine GKAgent2D for movement and physics body to detect contacts between sprites? maybe by creating a PhysicsBodyComponent and a ContactDelegateComponent or something…
Cn you remove the following line from your tutorial…
“If you want to learn more about GameplayKit, you should check out our book”
I bought the latest version book this week to try out GameplayKit based tutorials - but they have been removed… to be added at some undisclosed location at an undisclosed time! Luckily it’s still a great book but I was really disappointed that the original reason for buying the book is no longer true.
There are definitely some problems here. Perhaps it’s iOS10?
I am running Xcode 8.2.1, downloaded yesterday. Thought it was time.
Downloaded and opened the project. Got 10 errors, and the thing said it all needed to be updated to the latest Swift syntax. I have tried doing it manually, letting it go auto, and somewhere in between.
By the time I get to the end of “Adding Your Castles,” I have 8 fatal errors:
Castle.swift:20:46: Incorrect argument label in call (have ‘texture:’, expected ‘coder:’)
let spriteComponent = SpriteComponent(texture: SKTexture(imageNamed: imageName))
Castle.swift:23:1: ‘required’ initializer ‘init(coder:)’ must be provided by subclass of ‘GKEntity’
.
.
.
GameScene.swift:96:30: Value of type ‘Castle’ has no member ‘componentForClass’
if let spriteComponent = humanCastle.componentForClass(SpriteComponent.self) {
GameScene.swift:99:23: Missing argument label ‘entity:’ in call
entityManager.add(humanCastle)
GameScene.swift:103:30: Value of type ‘Castle’ has no member ‘componentForClass’
if let spriteComponent = aiCastle.componentForClass(SpriteComponent.self) {
GameScene.swift:106:23: Missing argument label ‘entity:’ in call
entityManager.add(aiCastle)
.
.
.
EntityManager.swift:28:29: Value of type ‘GKEntity’ has no member ‘componentForClass’
if let spriteNode = entity.componentForClass(SpriteComponent.self)?.node {
EntityManager.swift:35:29: Value of type ‘GKEntity’ has no member ‘componentForClass’
if let spriteNode = entity.componentForClass(SpriteComponent.self)?.node {
A few thing need changing in order to get this code up to date. I had the same fatal errors and found looking at the Apple documentation for GameplayKit Entities particularly helpful, most notably the Boxes demo
You will need to update the SpriteComponent init like so:
super.init() is required and it needs to follow our update to note else it complains.
Xcode should have already prompted you to add the missing required init, if it does simply double cluck the error popup and it will add it in automatically, if not after the closing curly brace of the init you added super.init() to add
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
The other thing that you will need to update is any call to entity.componentForClass( … )
this should now be written as entity.component(ofType: …) e.g.
func add(entity: GKEntity) {
entities.insert(entity)
if let spriteNode = entity.component(ofType: SpriteComponent.self)?.node {
scene.addChild(spriteNode)
}
}
Also in GameScene when calling entityManager.add(humanCastle) you will need to include entity: in the functions parameters like so:
entityManager.add(entity: humanCastle)
Hopefully that should get you to the first build stage, I’ve not gotten any further through the tutorial myself but I successfully built and ran the tutorial with these amendments. Hope that helps, Good luck.