How can we control actions through buttons?

In Chapter 3, Improving on the Decorator Pattern with the Component Object Model, we implemented game objects. Now that we have them, it seems trivial to create buttons on the screen. In fact, in genres such as real-time strategy, there is no difference between clickable buttons and game objects. The player can click on any unit or building and give them orders.

At first thought, our buttons could just be game objects. They both have a position, scale, and texture, and that texture will be drawn to the screen. Depending on the game, you might draw your buttons using orthographic projection while the objects will be drawn using perspective projection. However, the differences go deeper than that.

At its core, a button has an action that needs to be performed when it is clicked or selected. This behavior is usually simple; it doesn't require creating an entire state machine class. It does however, require a little thought so we don't end up hardcoding button functionality all over our high-level modules or repeating similar code in many different places.

In Chapter 5, Decoupling Code via the Factory Method Pattern, we saw an extremely naive way to handle a button click on a menu screen. Recall that this code was written by one of the authors early in their programming career:

if ((p.x > .15 * GetSystemMetrics(SM_CXSCREEN)) && 
(p.x < .42 * GetSystemMetrics(SM_CXSCREEN)) &&
(p.y > .58 * GetSystemMetrics(SM_CYSCREEN)) &&
(p.y < .70 * GetSystemMetrics(SM_CYSCREEN)))
{
if (mousedown)
{
mGameState = TCodeRex::LOAD;
mGameLevel = L0;
}
}

There are a lot of problems with this code:

  • First, the rectangular click region is hardcoded to the aspect ratio in full screen mode. If we were to switch from widescreen 16:9 aspect ratio to standard 4:3 aspect ratio or even if we changed from full screen to windowed mode, this code wouldn't work correctly.
  • Second, the click region is based on the screen and not the button itself. If the button position or size were to change, this code wouldn't work correctly.
  • Third, this menu screen is coupled to the Windows GetSystemMetrics function instead of an encapsulated platform code class like the M5App class. This means if we want to run on a different operating system or platform, this menu and possibly all menus need to be modified.
  • Finally, the state (stage in Mach5) switching action is hardcoded to the menu. If we decide to perform a different action, we need to modify the menu. If this action can be performed by both a button click and keyboard input, we need to update and maintain both sections of code.

As you can see, this isn't an ideal way to handle buttons in a game. This is basically the worst way you can implement buttons. This code is very likely to break if anything changes. It would be nice if the author could say this code was only written as a demonstration of what not to do. Unfortunately, a book like the one you are reading didn't exist at the time, so he had to learn the hard way.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.152.198