Post navigation

Decoupling game logic from input handling logic

In this post we want to share how we are decoupling our game logic from the input handling as we explained briefly in a previous post about different controls we tested for Super Flying Thing.

Introduction

There are different ways to handle the input in a game. Basically, you could have a framework that provides a way to define event handlers for each input event, or to poll input values from the API. LibGDX provides both worlds so it is up to you what you consider best for your game. We prefer to poll for input values for the game logic itself.

When starting to make games, you probably feel tempted to add the input handling logic in one or more base concepts of your game, for example, if you were making Angry Birds you probably would add it to the Slingshot class to detect when to fire a bird or not. That is not totally bad if you are making a quick prototype but it is not recommended for long term because it would be harder to add or change between different control implementations.

Abstracting the input

To improve a bit this scenario in our games, we are using an intermediary class named Controller. That class provides values more friendly and related with the game concepts. A possible Controller class for our example could be:

class SlingshotController {
boolean charging;
Vector2 direction;
}

Now, we could process the input handling in one part of the code and update a common Controller instance shared between it and the game logic. Something like this:

As you can see, the game concept Slingshot doesn't know anything about input anymore and we could switch to use the keyboard, Xbox 360 Controller, etc, and the game logic will not notice the change.

Conclusion

Decoupling your game logic from the input by abstracting it in a class is a good way to keep your game logic depending mainly on game concepts making it easier to understand and improving its design. Also, it is a good way to create several controls for the game (input, AI, network, recorded input, etc), while the game logic don't even notice the change.

This post provides a really simple concept, the concept of abstraction, it is nothing new and probably most of the game developers are already doing this, even though we wanted to share it, maybe it is helpful for someone.

We tried to use simple and direct code in this post to increase understandability, however in our games, as we use an entity system framework, we do it a bit different using components, scripts and systems instead of direct classes for concepts like the class Slingshot we presented in this post, but that's food for another blog post.

Finally, we use another abstraction layer over the framework input handling which provides us a better and simplified API to poll info from, that's why we prefer to poll values, food for another post as well.

Hope you like it, as always.

VN:F [1.9.22_1171]

please wait...

Rating: 4.6/5 (17 votes cast)

Decoupling game logic from input handling logic, 4.6 out of 5 based on 17 ratings

Another benefit of such approach is that you can switch between controllers of various types which are provided for player (accelerometer, virtual screen joystick, etc.)

Ariel Coppes

Exactly, we mentioned something like that in the paragraph before the Conclusion

Thanks for your comment

Namek

Oh dear, you're right. It's like reading between lines so I didn't notice 😛 Anyway, I'm using same approach in my code and it works great because by creating such decoupled abstraction you define what you really need to steer the character/game and so on. Keep sharing, good article!

Ariel Coppes

Thanks. Hope to have time one of these days to write an article I have in mind since some time ago