Can features be used to build a gaming component system in Scala?

I'm just curious, semantically correct, to use traits to create game objects. On the one hand, I see this as a relation (the object has components), but on the other hand, I consider the components as constituting the object.

For instance. You have a GameObject. GameObject does almost nothing on its own, but the things you mix with it give it additional properties. Components can be HealthComponent (has health), PhysicsComponent (simulates physics), ClickableComponent (can be clicked).

I like the idea of ​​using tags because all properties and methods are added to the source object, and I can do player.getHP instead of player.getHealthComponent.getHP . On the other hand, I find that the naming and semantics of using traits are strange. trait HealthComponent extends GameObject - this makes no sense. A HealthComponent owned by GameObject, it does not fulfill the relationships that extend means. Am I right in thinking that traits are usually treated as specialized versions of their parent class? If so, what would I call something like the above object?

+4
source share
3 answers

If you want to limit the types that can be mixed with your trait, you can express the dependency as an independent type:

 trait Health { self: GameObject => // ... } class Player extends GameObject with Movement with Health 

Thus, your trait does not extend GameObject , but can only be used as mixin for subtypes of GameObject .

See also Understanding the Scala Cake Pattern and related article.

+3
source

To add @Moritz's answer , you can also combine related behaviors without inheriting the implementation from the super-type:

 trait HasFoo { def foo: Unit } class GameObject extends HasFoo { def foo = {} } trait Health extends HasFoo { self: GameObject => abstract override def foo = { println("health foo") super.foo } } trait Dog extends HasFoo { self: GameObject => abstract override def foo = { println("dog foo") super.foo } } scala> val g = new GameObject with Health with Dog g: GameObject with Health with Dog = $anon$1@33b7b32c scala> g.foo dog foo health foo 
+4
source

" trait HealthComponent extends GameObject - this doesn't make sense. A HealthComponent` belongs to GameObject" - what you want is the types yourself, and building according to the cake template:

So you have

 trait HealthComponent { me: GameObject => def inspect { me.querySomeGameObjectProperty } } val x = new GameObject with HealthComponent with ... 

"Am I right in thinking that traits are usually seen as specialized versions of their parent class?" β€œI would not say that.” If you go for an upward approach similar to the above, you don’t think that traits are subtypes of some parents, but vice versa (larger components consist of specialized ones)

+3
source

Source: https://habr.com/ru/post/1347009/


All Articles