Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GameplayKit - Confusion about sending messages between components

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

like image 494
hamobi Avatar asked Sep 07 '15 21:09

hamobi


2 Answers

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 :)

like image 177
Deftwun Avatar answered Nov 15 '22 06:11

Deftwun


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.

like image 31
mfessenden Avatar answered Nov 15 '22 06:11

mfessenden