I'm diving into GameplayKit with Spritekit and from what I gather, you subclass GKEntity
and then start adding GKComponents
to that entity. The entity would more or less just be a bag of components that fill some function.
The part I'm confused about is communication between components. How do you keep them decoupled. For example, lets say I have a HealthComponent
class, and I add that component to a PlayerEntity
, and an EnemyEntity
. I also have a HealthBarComponent
but I only want a health bar to appear above the player. When the player takes damage, that information needs to be updated in the HealthBarComponent
.
So how should that information be sent? I see there is a class called GKComponentSystem
in the documentation. I'm not 100% on how that should be used.
Another question is.. when the player's health reaches zero he should regenerate while the enemy should stay dead. When the player runs out of lives, the game ends.
The health system for both an enemy and player would be roughly the same, but the events around death would be totally different for each. I'm not following how to use a component system while keeping the unique behavior of each entity.
some pseudo-code would be great
It looks like this framework works a bit differently than others I've seen, in that systems only work on a single type of component rather than on entities with groups of component types.
In the GamePlay-Kit framework you can either loop through and update your entities manually (which in turns updates each entities components) or create a class which inherits from GKComponentSystem. Then when you update the system it updates all the components you have added to it so long as their class type matches the type you initialized the system with
To handle your health bar issue I would say make a HealthBarComponent
which, during its update, retrieves the HealthComponent
from its owner entity, reads the health value & renders itself every frame. But you only add a HealthBarComponent
to your player entity.
You can retrieve the owner entity from a component and vice versa (see GKComponent.entity & GKEntity.components) so you could update your health bar like this:
/*Note: I'm not an ios developer, this is pseudocode*/
HealthBarComponent.update(){
int healthValue = self.entity.components.get(HealthComponent).value;
//Now render your health bar accordingly or hold onto this for later
}
To handle the player death issue I would think your best bet would be to have two different types of Health components (PlayerHealth & EnemyHealth) with two different corresponding systems. That or have a single Health component but 2 separate 'Death' components. Yeah it seems redundant but I'm having a hard time thinking of a better way inside of this framework. In my experience you either spend your time worrying about keeping everything completely decoupled and reusable or you build a game :)
Components can access their entities via the self.entity
property. From there, you can query other components to pass data to via the entity componentForClass
property:
guard let moveComponent = entity?.componentForClass(MoveComponent.self) else {
fatalError("A MovementComponent's entity must have a MoveComponent")
}
The iOS Games by Tutorials book has an excellent tutorial that covers GameplayKit entities and components.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With