Whack-a-Mole is an excellent choice when you just want to play a game where you can hit things without having to think too hard about it, but can you make it in RPG Maker? Of course! So let’s take a look at how we can event it and add a fun little minigame to our projects.
There are quite a few ways we could do this, such as using pictures or including a bunch of possible targets. For this tutorial let’s keep things simple by having events on a specific minigame map be the targets and only include 4 targets so that we can use the arrow keys to hit them.
We’ll be once again using the TextPicture plugin that comes with MZ to show the current scores for the minigame on the screen, but it’s not necessary for the event itself to work.
Before we start on the minigame itself, let’s set up how our player will get to the minigame map. An event with a simple yes/no choice where ‘yes’ transfers our player to the minigame map works well. If we wanted to make our player pay a small fee before playing then we’d want to include a conditional branch to check if they have enough gold to afford the fee and if they do then remove the gold before the minigame starts.
As you can see in the screenshot, before we send our player to the minigame map we set a few variables to 0. This is to make sure that 6 variables we’ll be using in the whack-a-mole event aren’t set to a different amount (since it would be odd if our score variable started at something like 15 instead of 0). Since we’re zeroing our variables before use, we could also use those variables in other parts of the game like another minigame.
Our minigame map can be as decorated or simple as you want, the most important thing is that it includes an event that will be our control event and 4 events that will be the whack-a-mole targets.
Each target event will need multiple pages so that our target will only ‘pop’ up at the right time, so let’s use our variable that will be tracking which target will randomly appear to set whether the target is there or not. To make some of our future eventing easier, let's match the required variable to our target event’s ID, so our event 2 will only be visible when the variable equals 2, event 3 will only be visible when the variable equals 3, and so forth.
Now that our player and our targets are placed properly on the minigame map, we can get to work on the autorun event that will control the entire minigame.
Let’s start our event by setting up a visible score with the TextPicture plugin and a quick intro to the minigame. We can put the message intro in a conditional branch that checks if one of our minigame variables equals 0 since once the minigame starts that variable cannot equal 0 again during that game. Last thing we need for our intro is to set the control timer command to however long we want the game to last, in this case 30 seconds.
But before we can whack a target, we need to set the target by setting our position variable to a random number that matches one of our target’s event IDs. While just setting the variable would work, it can look odd or even confusing for our player to have the target appear in the same spot multiple times in a row so let’s add in a method to avoid that. By putting it all in a loop and then comparing our current position variable to another variable that will contain the previous spot, we can break the loop when they don’t equal each other. That way our target will switch positions each round.
Once our target is chosen, we can set up a few more of our variables for this round. If we want our targets to only appear for a short time before switching to a new spot then we need to set a target timer variable to 30 (which lasts roughly half a second). Then we can set our player choice variable (to keep track of which direction button is pressed) to 0, set the previous spot variable to equal the current position, and add 1 to the number of total targets seen during the minigame. With that taken care of, we can start a loop which will run and check what our player does.
Now we can add in conditional branches to the loop that will check which button our player triggers where our player will turn to face that direction and set the player choice variable to match the event ID of the target that our player is now facing.
We’ll need a conditional branch for each button direction, for a total of 4 conditional branches in that section.
Under those button-checking branches we can set up what happens if our player hits a button. Inside a conditional branch that checks if our player choice variable is more than 1 (it will be 0 if no button is pressed), we can compare the player choice variable with the target’s position variable. If they match, that means our player hit the right button and whacked the target so we can flash the screen green and play an animation on the target before we increase our player’s score by 1. While we could use conditional branches to make sure the animation plays on the right target event, a shorter method is to use the script call: $gameTemp.requestAnimation([target], animationID); . Then we can set the target to match the target’s event by using the position variable (this is why we set the variable to choose a number that matched the target event IDs) and the animationID to whatever animation we want, leading us to a script call that looks like this:
target = $gameMap.event($gameVariables.value(1))
With that all done, we can break the loop and the whole process can repeat.
If the variables don’t match, then our player missed the target and we can flash the screen red and play a ‘woosh’ SE. Setting up a custom ‘miss’ animation would be a good alternative, but no matter what you decide it should end with a break loop command so that a new target can appear.
The last thing we need in our loop is to decrease our target timer event by 1 and a conditional branch to check if that variable equals 0. If it does, then that means our player missed hitting a button in time and we can break the loop so that a new target appears.
With our targets and button pressing commands all set up and ready for our player to hit (or miss) targets when they appear, what’s left? How we end the minigame! Since we used the Timer command we can add a conditional branch to see if the timer has hit 0, and if it has then run the end of the game. For this example let’s have our Gamemaster comment about how many targets our player hit. If we wanted to reward our player for getting specific scores, this would be a good place to add that in. Lastly, we need to send our player back to the normal map so they can continue their adventure.
And with that taken care of, we can see our event all together:
Then we can playtest and make sure it’s working just how we want it to.
We could always adjust the timers to give our player more time to hit each target or add in versions where there isn’t a timer and instead ends when our player misses a target. Where would you use this in your game? Would you set up an arcade for your players to enjoy, or tweak the event to turn it into a scene where your heroes need to whack spawning enemies before they can overwhelm them?