4
\$\begingroup\$

I am working on a platformer and I want to have the player be able to switch control types based on items that may be carried + default controls for things such as water, in the air, on the ground etc...

I understand how to make a player move in anyway I desire but I don't understand how I can encapsulate these behaviors into their own classes and call and apply them to the player when needed.

The way I have it is this:

Input is handled by the input class. During the update, the player looks at the input class. It then figures out how it should move itself with a bunch of if statements to figure out what rule set should be applied. For example: Am I in the water? Am I on the ground? Am I in the air? and so on. Based on the previous questions the player object then decides how to interpret the input. After everything is done, the results are edited by world rules which applies things such as gravity, etc...

This seems to work but it is not elegant and results in duplicated code. Its ugly. How should I set up some classes and how should they talk to each other? All I manage to do is make a mess of my code trying to class it out. I have searched around for sometime on how I need to do this but can't find anything.

Any pointers on where I can go to figure this out? Any advice? I just know I need the code contained so it's easy to debug later and figure out what is happening.

\$\endgroup\$
6
\$\begingroup\$

Add an intermediate layer.

You have some kind of PlatformInput that manages all the different input methods and generates low-level events like KeyUp, KeyDown, etc.

Another layer then processes these messages into logic events, like MoveUp, Jump, etc. It can do this by receiving the inputs, mapping keys to logic events, and doing only the most basic checks. The main idea is that you have multiple events coming into this layer from multiple devices but only a simplified and unified output stream of events.

The actual character controller then processes the logic input events as normal, e.g. if it gets a Jump event it makes sure the player is actually allowed the jump and if so makes the player avatar jump.

The mapping layer an be data-driven to a degree, so e.g. you have an entry saying KeyDownEvent:<JumpKey> --> Jump and ButtonDownEvent:<JumpButton --> Jump and then players can change mappings for JumpKey to whatever keyboard key (or keys) they want and the same for buttons (or select from some pre-configured controller layouts). In this way, you both have easy support for multiple devices and multiple configurations.

I would also put more intricate input "combinations" here. That is, if you have an attack that requires holding the left trigger and pushing the A button, the logic event should still just be Attack and the mapping layer is responsible for sending that event when A is pressed but only if the trigger is held, e.g. ButtonDownEvent:<AttackButton> AND TriggerValue:Left>=0.9 --> Attack. Combo attacks are a different story and belong in your character controller, since the state is dependent on the game/avatar.

Basically, all input handling that is dependent on low-level input state goes into the mapping layer. All input handling that is dependent on the game state goes into the character controller. Any input handling that is somehow dependent on both should be split up into separate parts each dependent on either only low-level input or only game state.

\$\endgroup\$
  • \$\begingroup\$ I would even go as far as to say this should be done even if you DON'T require remapable keys. Mostly because this makes your code much more readable. \$\endgroup\$ – UnderscoreZero Jul 16 '13 at 22:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.