Yes there is no point in call that a game when nothing moves on the screen. Not even our ship in the base is controlable in any way. At least we should be able to control the ship, move it left and right. I show you a way to do this by moving the mouse pointer left and right. Sounds promising, no?
Ok here it comes a minimalistic approach, further details for those action listerners can be found here.
We could have more than one ship, so we just take the first we find. In our example we only have one ship as we did not add more than one ship. But maybe we could use that to have three ships, a ship for a live for example and display the awailable ships a little smaller on the top left of the screen.
The following snippet gets the entities by model name, I used a filter for this.
Just that you know something like that exist. The filter only works if we also have the Model.class in the entity query.
We also could use a tag like component with no data at all just an empty component to tag the active ship we want to use. I actually don't know which way is better and it mostly depends. For now this approach above is good enough.
In the analog listener we read out the x axis of the mouse pointer in the game screen and use this to calculate the ship x position. It's the cheapes way and good enough for this article though. You can improve this and make it more "pysical" than my version if you like and feel the need.
But this position itself will not move our ship, this is done here in the update loop of this state. Remember? All states do have an update loop?
As you can see I just pick the first ship I can find in the ship entity set (ok I know there is only one in it anyway) and set the new position. Immutual, remember?
Register the controler system to the Main.class
And do now my ship move? Really? Really, with the help of the visual state app we hacked in the last blog article. Cool isn't it? I can move that ship without touching a single line in any other state we have so far, just add this system.
But of course if we will have new systems which needs different components on the ship, invaders, what so ever, we have to touch code to inject those components. Resist to solve that in an object oriented way or you will end up pretty soon in a mess you can hardly wade out of. Entity system is not object oriented it is data driven, don't mix. At least don't mix on the same abstraction level.
The ship moves now controlled by our mouse movement but the invaders still are completly motionless. To make the invaders move I will add some sort of a very very simple AI state.
Don't forget the register AI system in the Main.class
The invaders now do move left to right and up and down in a grid like formating flight. Enough to show you more chilling entity system approaches. But you can see even now how clean the representation and the logic is separated.
Let's improve that to make the visual a little more Wow. To make it look cooler and more vivid rotate the invaders around there y axis.
I use the position component and add there as well a rotation. Of course you also can add a rotation component and do it that way, but then you have to touch more code. So just replace your current position component with the following code
Now we have to deal as well with the rotation in the VisualAppState system. So let's slightly change the updateModelSpatial method of it like that
Maybe there is a more elegant way doing this, it's just the way I know. By now the visual state can handle as well rotation.
To make them rotate we have to improve our InvadersAIAppState slightly. Replace the code of the wabbeling method in InvadersAIAppState with the following snippet.
Only this has actually changed
and gives a 90 degree per second y axis rotation to all invaders. I added some logic to clamp the rotation to 360 degrees.