Smack It

Description

One of the first games that The Game Creators developed for mobile platforms was Smack It. This is a whack a mole game that managed to make it to number 1 in the family and kids charts on the iPhone in the US and UK. At the time AGK didn't exist, so the game was written using a mixture of C++, Objective C and OpenGL.

Now that AGK has arrived, as a test, it was decided to port a version of Smack It across to tier 1 and tier 2. Even though the logic and general structure remains the same in the original compared to the conversion, the actual development process has been simplified massively by using AGK and also brings the benefit of being able to run on multiple platforms.

This guide provides an overview of the code for tier 1 version of Smack It (using BASIC).

Overview

The main menu is the starting point for the game. This consists of a background, a start button and several animated entities being displayed on screen.

When the game starts a collection of moles pop up and down and the user must hit them to score points. As time progresses the game speeds up and it becomes more frantic and tests the players reaction skills.

Once the time for the level has elapsed a collection of statistics will be shown. If the player reaches a certain target they will win, if not they will lose.

The game is fairly simple to code, as there's nothing really complicated going on, it's mainly a case of animating some sprites and moving them around.

Globals and types

At the top of the source code is a collection of global variables and type listings.

sItem is used to store information about a balloon that flies across the screen (the user can hit this to get a big bonus added to their score).

Another type is declared sEnemy. This is used for all the moles that pop up on the main menu and in game. It contains data such as sprite ID numbers and timers.

sLevel is the final type. This contains everything related to a level such as the ID numbers of sprites, ID numbers of text, the current score, statistics and more. In this conversion of Smack It only 1 level is utilised, so it could be possible to have these variables outside of a type, however, it does help to encapsulate this data, especially if more levels were to be used in the future (like in the original game).

Initial Set up

Prior to entering the main loop a custom function SetupMainMenu is called. This function is responsible for setting up the main menu and getting its contents ready to be displayed on screen. It performs the following actions:

Main loop

The main loop consists of a simple select block based on the variable g_State. The seqeunce is fairly straightforward:

Initially g_State is 0 therefore DisplayFadeIn will be called first, which will handle a simple fade in transition. The state will then move to DisplayMainContents. At this point the game will wait until the user chooses to start the game and then it moves to DisplayStartGame, LoadLevel and then PlayLevel. When the game is being played the state can move to HandlePause if the user chooses to pause the game and they can either resume the game or go back to the main menu (which begins at state 0). Once the game has finished either HandleWin or HandleLose is called and after this section has been displayed the state goes back to 0 and the main menu is displayed once again.

The main menu

The states relating to the main menu are 0, 1 and 2 that call DisplayFadeIn, DisplayMainContents and DisplayStartGame.

The function DisplayFadeIn will reduce the alpha of the overlay sprite until it reaches 0, at which point the state will change to 1. This overlay sprite covers the whole screen and is white, so reducing its alpha down to 0 creates a simple fade in effect.

The function DisplayMainContents will wait until the user presses the "Start" text on screen. When this happens the state will change to to 2.

The final function for the main menu is DisplayStartGame. This is very similar to DisplayFadeIn, except this time it's raising the alpha of the overlay back to full white. It also hides some text and moves the state onto 3 so that the level can be loaded. It would probably make sense to merge this function with DisplayFadeIn and have a parameter that controls whether the overlay fades in or out.

Notice that all these three functions call UpdateItems, UpdateClouds and UpdateEnemies. The first deals with the balloon moving across the screen, the second handles the clouds and the third is responsible for moles popping up.

UpdateItems is used on the main menu and in the game as a way of moving a bonus sprite across the screen, when hitting this in game you get extra points added to your score. The original game had numerous items that would go across the screen, but for the conversion only a hot air balloon is used. The function will randomly launch the balloon from the left or right of the screen. As it moves across a check is made to see whether the user hits it and if so a smoke animation is played. Finally it gets reset so that it can be launched again.

UpdateClouds simply moves the 3 clouds over to the left of the screen at varying speeds. Once they have gone past the screen they get placed back to the right of the screen so they can scroll back in.

The final function UpdateEnemies deals with the 3 moles popping up at the bottom of the screen. It checks whether all 3 moles are down and if so will release one of them. It will then cycle through the moles and update them based on their state. The final block of code checks whether a mole has been hit and if so plays a sound effect and changes the state of the mole.

Loading the level

When the user presses the "Start" button on the main menu the state switches to 3, which will call the function LoadLevel. This function handles the following:

Playing the game

When the user enters the game from the main menu the function PlayLevel is called. In turn this function calls another set of functions:

The UpdateItems function is the same as the one used in the main menu - it simply sets up the balloon moving across the top of the screen.

UpdateEnemiesInGame is pretty much similar to UpdateEnemies. The alterations relate to the way an enemy is popped up and dealing with scoring. Probably a good option to merge these two functions and have a parameter to control the mode. Here's what this function does:

The CheckForPause function allows the user to pause the game by clicking or touching the pause button at the top left of the screen. If this happens the state of the game is switched so that HandlePause will be called.

CheckForInput checks if the user hits or clicks the screen. When this happens we see if the user hit a mole or empty space. If they missed a mole a miss icon appears on screen and 5 seconds of time are lost. If they hit a mole the score is incremented by 5.

The UpdateInfo function updates the score and time display.

The final function call within PlayLevel is UpdateTime. This function will slowly reduce the time down from an initial 60 seconds to 0. When the time limit has been reached a check is made to see whether player has won or lost the game and based on this a new state is set.

Pausing the game

When the game is in a paused state the function HandlePause gets continually called. At this point the user can either continue the game or return to the menu by selecting the option on screen.

The initial state for pause (g_PauseState) will be 0 when the function is first called. There is a section of code that will display the "Continue" and "Main Menu" text options on screen. When there is input if the user pressed the pause / play button or the "Continue" text g_PauseState gets set to 1. If the user hits the "Main Menu" text then g_PauseState gets set to 2.

When g_PauseState is not 0 the "Continue" and "Main Menu" text will fade out, after which time action is taken to either return to the game or go to the main menu. If the user returns to the game it's a simple case of setting g_State back to ePlayLevel. Returning to the main menu is handled with a call to UnloadLevel, which will free all resources used by the level, followed by g_State being set to eDisplayFadeIn which results in returning to the main menu state.

Winning or losing the game

When the game is over either HandleWin or HandleLose gets called. These functions will display a bunch of statistics on screen, such as how many hit attempts were made, and then wait until the user touches the screen and then return to the main menu. The only difference between these functions is that one needs to show "Well Done" while the other must show "Game Over", so they are handled with a call to EndLevel, which takes a parameter allowing us to specify which text to display.

The EndLevel function has its own state stored in g_GameOverState. It does the following:

Other functionality

Logic for the moles is handled with a for loop, that checks the state and then calls one of:

Conclusion

Porting a basic version of Smack It to AGK turned out to be fairly easy and brings benefits such as simpler code (no need to deal with all the technical issues) and the ability to run on multiple platforms.