Today was the big push! It took a while to figure out how to implement what I wanted to do, but now it’s done! The game play mode and pause state are completed! You can, of course, check out the full commits on my GitLab, but I plan to go over some of the most important parts here.

if (gameState == 3) { // Play state.
// The player has entered play mode.

gameTime++;
if (gameTime > 1){
gameTime = 0;
gamePaused = false;
}

This portion allows the game to pause. An odd occurrence is that you cannot press the pause button and release it fast enough. It will essentially get pressed and check that it is pressed about 1000 times per second, so I needed to add an “unpause” delay, and this is how I did it. If the buttons were software buttons, I could have done this differently, but they are physical buttons, so I needed this to make it work every time.

gameShoot = true; // you have not shot yet this round.
gameAsteroidOne–; // First asteroid starting space.
gameAsteroidTwo–; // Second asteroid starting space.
gameAsteroidThree–; // Third asteroid starting space.
gameAsteroidFour–; // Fourth Asteroid starting space.

Here, we increment (or move) each asteroid by one space.

if (gameAsteroidOne == -1) {
if (gamePosition == 0) {
// Game over, you lose.
gameState = 6;
gameLineNum = 0;
} else {
gameScore++; // get a point!
gameSpeed = set_gameSpeed(gameScore);
gameAsteroidOne = get_random(4);
}
} // end gameAsteroidOne.

In this block, I am figuring out everything for asteroid number one. So, if it’s position (which we moved just the block before this) is now -1, then it is at the position on the screen where the player’s ship is. It now checks if it is on the same row as the ship (gamePosition is the position of the ship, 0 for upper, 1 for lower). If they both are on the same row, then a collision has occurred. So, you switch to the lose screen.

If they are not on the same row, then the player gets a point for passing the asteroid. Then the game speed is increased (there are some other factors that change it as well), and the asteroid is moved to a random new location.

if (gameAsteroidTwo == -1) {
if (gamePosition == 0) {
// Game over, you lose.
gameState = 6;
gameLineNum = 0;
} else {
gameScore++; // get a point!
gameSpeed = set_gameSpeed(gameScore);
gameAsteroidTwo = get_random(2);
}
} // end gameAsteroidTwo.

if (gameAsteroidThree == -1) {
if (gamePosition == 1) {
// Game over, you lose.
gameState = 6;
gameLineNum = 0;
} else {
gameScore++; // get a point!
gameSpeed = set_gameSpeed(gameScore);
gameAsteroidThree = get_random(3);
}
} // end gameAsteroidThree.

if (gameAsteroidFour == -1) {
if (gamePosition == 1) {
// Game over, you lose.
gameState = 6;
gameLineNum = 0;
} else {
gameScore++; // get a point!
gameSpeed = set_gameSpeed(gameScore);
gameAsteroidFour = get_random(1);
}
} // end gameAsteroidFour.

if (gameScore > 99){
// You win! Great job!
gameState = 5;
gameLineNum = 0;
}

These are the portions for asteroids two through four, which work identically to asteroid one. Note that there are two asteroids on row 0, and two asteroids on row 1. Four asteroids total. It seems rather limited, but it is appropriate for such a small screen.

// Set up our display.
// The space ship
String shipUpper = ” “;
String shipLower = ” “;
if (gamePosition == 0){
shipUpper = “>”;
shipLower = ” “;
} else {
shipUpper = ” “;
shipLower = “>”;
}

Here we check the location of the player’s space ship and set the upper and lower icons appropriate for the display.

// Upper blocks.
lcd.setCursor(0,0);
lcd.print(“00”);
lcd.setCursor(2,0);
lcd.print(gameBullets);
lcd.setCursor(3,0);
lcd.print(“|”);
lcd.setCursor(4,0);
lcd.print(shipUpper);

for (int a = 5; a < 17; a++){
lcd.setCursor(a,0);
if (a == gameAsteroidOne+5){
lcd.print(“*”);
} else if (a == gameAsteroidTwo+5){
lcd.print(“*”);
} else {
lcd.print(” “);
}
}

Now we draw the upper blocks. As you can see, I just set the LCD cursor to the correct spot and print the text to display what I want displayed. The “for” loop cycles through the remaining display area, or “asteroid field” and checks for asteroids. If there is one, it displays an asterisk, if not, then a blank space.

// Lower blocks.
lcd.setCursor(0,1);
lcd.print(gameScore);
if (gameScore < 10) {
lcd.setCursor(1,1);
lcd.print(” “);
} else if (gameScore < 100) {
lcd.setCursor(2,1);
lcd.print(” “);
}

lcd.setCursor(3,1);
lcd.print(“|”);
lcd.setCursor(4,1);
lcd.print(shipLower);

for (int a = 5; a < 17; a++){
lcd.setCursor(a,1);
if (a == gameAsteroidThree+5){
lcd.print(“*”);
} else if (a == gameAsteroidFour+5){
lcd.print(“*”);
} else {
lcd.print(” “);
}
}

Here we draw the lower line of the screen. It works basically the same as the upper line, but with the score instead of the number of bullets.

gameDelay = 0;
while (gameDelay < 1000){
// Add a delay in the loop.
delay(1);
gameDelay+=gameSpeed;
lcd_key = read_LCD_buttons(); // read the buttons

switch (lcd_key){

case btnRIGHT:{
// Shoot command
if (gameBullets > 0 && gameShoot) {
if (gamePosition == 0){
lcd.setCursor(5,0);
lcd.print(“————“);
gameBullets–;
gameShoot = false; // You already shot.
gameAsteroidOne = get_random(4);
gameAsteroidTwo = get_random(2);
} else {
lcd.setCursor(5,1);
lcd.print(“————“);
gameBullets–;
gameShoot = false; // You already shot.
gameAsteroidThree = get_random(3);
gameAsteroidFour = get_random(1);
}
}
break;
}
case btnLEFT:{
if (!gamePaused) {
gameState = 4;
gameLineNum = 0;
gamePaused = true;
}
break;
}
case btnUP:{
gamePosition = 0;
break;
}
case btnDOWN:{
gamePosition = 1;
break;
}
case btnSELECT:{
gameState = 0;
gameLineNum = 0;
break;
}
}
}
} // End gameState 3, play state.

The remainder is the delayed “while” loop, which checks the status of the buttons every millisecond and increments towards ending this “round” of display. Because it is using a counter that is based on game speed, the game will speed up as the game increases. At first, an entire game loop takes about 1 second, then .5 seconds, then .33 seconds, and finally, .25 seconds towards the end of the game.

The pause mode is much simpler:

if (gameState == 4) { // Pause state.
// The player paused the game.
lcd_key = read_LCD_buttons(); // read the buttons

switch (lcd_key){

case btnLEFT:{
gameState = 3;
gameLineNum = 0;
break;
}
case btnSELECT:{
gameState = 0;
gameLineNum = 0;
break;
}
}
} // End gameState 4, pause state.

The pause mode doesn’t actually draw anything, which is good, because then the screen displays what it was displaying last. Hence the game still visually appears, but no calculations are made to move anything.

Next post I’ll discuss the random number generator and some background information, as well as try to post a video of the game being played. If you have an LCD Keypad Shield and Arduino Uno, feel free to download my GitLab repository and play the game! You will need the LCD Keypad Shield library as well. Be sure to let me know if you tried it out!

Linux – keep it simple.

Leave a Reply

Your email address will not be published.