Supporting Video
A video is available for the controller build (Ep. 3) and for this article, click below to view;
Prerequisites
If you’ve not read any of the previous articles (there have been 3 previous articles) then it is recommended that you do so. See the “projects” menu above. If you want to build this project you require the following kit (listed in detail in article 2, here)
The parts List
ESP32 development board (I’m using the NodeMCU 32S)
128×128 Colour LCD (SPI protocol and 7735 driver based)
Type D Audio Amplifier (PAM 8403)
Small 8 Ohm (or higher) speaker.
Optional rotary control or variable logarithmic resistor potentiometer – for volume control
Breadboard to mount it all on (until you build a proper board)
5 tactile push switches
Various wires
In this article
The frogs movement at present is not very good, it moves suddenly from one spot to the other and is not affected by anything on screen. In this article we will animate the jumping and allow lives to be lost and for it to land on logs etc. and be moved. We will also implement a very basic “attract” screen, which will be expanded upon towards the end of the series.
The Code
The full code for this article is below. As in the previous article it is a zip (compressed) file that consists of several files that make up the game. You need to download and drag the folder within the archive to your Arduino’s Sketch folder. See the previous article if you are not sure how to do this.
The attract screen and lives
In order to implement loss of lives we need a state when the game is actually not running, at present just runs all the time none stop. In the arcade version this has a demo of the game as well as an “eye candy” attract sequence. We will just have text for now but will be implementing it fully later. The function is shown below;
382 383 384 385 386 387 388 389 390 391 392 |
void AttractScreen() { Frogger.tft.fillScreen(0); Frogger.tft.setCursor(10,64); Frogger.tft.print("Press Start"); if((digitalRead(BUT_PLAYER_1)==0)|(digitalRead(BUT_PLAYER_2)==0)) { Frogger.StartNewGame(); } Frogger.tft.displayBuffer(); } |
The number of lives is set by this line in “Frogger.h”
#define START_LIVES 3
The big lives left debate (well maybe not so big!)
Change this to whatever you like, I think the original arcade cabinet had options for 3,5 and 7. Now… the big “lives” debate. On games the number of lives left shown on screen has been debated for years. Do you include the current one your playing with or the lives left after the one your playing with. There is no set consensus now let alone back in the 80’s. Frogger chose to show the lives left after the one your playing with. So when you start with three lives it shows two little frogs (representing lives left) at the bottom of the screen. So on your last frog/life you would see no little frogs at the bottom of the screen.
Frog movement
The frog only has two frames of animation when it moves and which is being displayed and for how long is handled by it’s class’s draw and physics routines. These routines take there information from the Animation_Class, which in itself contains an array of Frame_Class to store information on each animation frame. These are found in the (Frog_Class, Animation_Class and Frame_Class ) within Graphics.h and Graphics.cpp files. The added graphics for these animations are in the “GraphicsData.h” file.
Collision Detection
Frogger uses simple collision detection in exactly the same way as “Space Invaders” did. The collision function is shown below and returns true if two objects are in collision or false otherwise. It’s a method of the MovingObject_Class which can be overriden by descendent classes if they require more complex collision detection. As can be seen if they collide the frog animation is set to a death animation. Other objects such as logs and turtles override this function so that the frog doesn’t die but instead travels on the log.
32 33 34 35 36 37 38 39 |
bool BaseObject_Class::Collision(MovingObject_Class *Object,Frogger_Class *Frogger) { // returns true if object is in collsion with this object, only used for collision objects, floating objects handle this temselves bool Collided=((x+width>Object->x)&(x<Object->x+Object->width)&(y+height>Object->y)&(y<Object->y+Object->height)); if(Collided) Frogger->Frog->SetAnimation(COLLISION_DEATH,Frogger); return Collided; } |
There is a (not really a mistake) issue with the code below, can you spot it? We pass an object in (which actually always is the frog) and then in the code we explicitly kill the frog with this line (or at least start the animation)
Frogger->Frog->SetAnimation(COLLISION_DEATH,Frogger);
To be consistant it should really have been
Object->SetAnimation(COLLISION_DEATH,Frogger);
But, however, the code was written. It will be corrected at a later date. For this program it will never make a big difference but may have been an issue with other games.
The code above is relatively simple but sometimes the code can be hard to imagine what it’s doing in your head. So below I have created a hands example of this exact code, this is available in Space Invaders “Part 5 – Player missiles and collisions”. There are 4 conditions that must be met for a collision to have taken place, when any one of these conditions are true it highlights in red. When they are all true you will see the all conditions in red and the only time this happens is when the two objects overlap. Underneath the code I’ve also shown that actual numbers for each of the four conditions. Have a play with the controls to move object 1 whilst looking at the code and the coordinates as they change.
To Be or not to Be
Our little frog dies or does not depending on what it is in collision with. Anything on the road, the snake, the crocodile, the hedges will lose you a life, anything on the river will save it by enabling you to float above the treacherous waters – although why water is so fatal to a frog is anyone’s guess! My guess is that the river is full of deadly submerged crocodiles that instantly kill the frog if it goes in. The only exception on the river is if the frog is on some turtles and they dive under the water, then you perish if your on them. The game ends when all lives are lost. Also if we detect it making it home safely then you we will reset for another frog until all holes occupied.
Next episode/article
We’ll implement the sound next in order to give the game some extra atmosphere! Till next time!