This lesson is about visual improvement to your game. You can spend as much time on these types of features as you'd like and, as long as you understand how to fit them into the existing program, you can create all kinds of new characters and conditions to show them.

Topics Covered:

/* * In this lesson, you'll add a new custom character that is triggered when * JumpMan is mid-jump to give him the appearance of leaping over the wall. */ #include "MakerScreenXVI.h" MakerScreenXVI lcd; byte run0[8] = { //legs in partial stride 0b00000, 0b01100, 0b01100, 0b01100, 0b01110, 0b01100, 0b01010, 0b01010 }; byte run1[8] = { //legs in full stride 0b00000, 0b01100, 0b01100, 0b01111, 0b01100, 0b01100, 0b01010, 0b10001 }; byte wall[8] = { //wall obstacle 0b11111, 0b10101, 0b11111, 0b10001, 0b11111, 0b10101, 0b11111, 0b10001 }; byte crash[8] = { //crashed JumpMan 0b00000, 0b00011, 0b01011, 0b00111, 0b00011, 0b00011, 0b00001, 0b00001 }; //The new icon for the jump part of the animation. byte jump[8] = { //mid-jump icon 0b00110, 0b10110, 0b01100, 0b01111, 0b01110, 0b01011, 0b10000, 0b00000 }; int position = 0; //holds the changing position of the cursor bool runState = 0; //which running animation to draw (0 or 1). int jumpState = 0; //0 ='pre-jump', 1 ='mid jump', 2='post jump' bool buttonState = 0; //will equal 1 after press, 0 after jump completed int wallPosition = 14; //wall can be placed from 0 to 15 int points = 0; //jumps without hitting a wall long animationTimer; //tracks animation (custom character) updates long runTimer; //tracks position updates void setup() { lcd.begin(); lcd.backlightOn(); lcd.createChar(0, run0); //partial stride character lcd.createChar(1, run1); //full stride character lcd.createChar(2, wall); //wall character in 'slot' 2 of custom characters lcd.createChar(3, crash); //splatted character against the wall lcd.createChar(4, jump); //mid-jump icon pinMode(6,INPUT_PULLUP); //button to trigger jump //Start both timers equal to millis() so that the difference between //millis and the variables is 0. animationTimer = millis(); runTimer = millis(); } void loop() { lcd.setCursor(0,0); //upper left of the screen lcd.print("Pt: "); lcd.print(points); //Set the cursor depending on the state of the character if (jumpState == 0){ lcd.setCursor(position,1); } else if (jumpState == 1){ lcd.setCursor(position,0); } else if (jumpState == 2){ lcd.setCursor(position,1); } /* * Draw the new mid-jump animation, which has been controlled * only by runState until now. Make the drawing conditional * based on jumpState, 'if' jumpState is 1, then draw the 'jump' icon. * Else, draw the running animation as you have before. */ if (jumpState == 1){ //if jump has been activated... lcd.write(4); //draw JumpMan mid-air } /* * An 'else' statement goes after 'if' and all the 'else if' statements * that follow it. It tells the program "if all preceeding 'if' conditions * are not true, then do what comes in the block after". */ else{ lcd.write(runState);//draw the run0 or run1 animation } lcd.setCursor(wallPosition,1); lcd.write(2); //draw wall if ((digitalRead(6) == LOW)&&(jumpState == 0)){ buttonState = 1; //1 means a press is recorded } //Button is unpressed and a jump has been completed if ((digitalRead(6) == HIGH)&&(jumpState == 2)){ jumpState = 0; } if (millis() - animationTimer > 300){//Update animation every 300 ms runState = 1 - runState; //draw the next JumpMan animation animationTimer = millis(); lcd.clear(); //clear the LCD to draw a new character } if (millis() - runTimer > 600){//Every 600 milliseconds, run this... position = position + 1; //move character one space to the right if (position == 16){ wallPosition = random(3,16);//place wall in column 3 through 15 position = 0; } //if button has been pressed and a jump hasn't been initiated... if ((buttonState == 1)&&(jumpState == 0)){ jumpState = 1; //signal a jump buttonState = 0; //reset button to 'unpressed' in the code } else if (jumpState == 1){//true if jumpState set to one in the last loop jumpState = 2; //jump is marked as complete } if ((position == wallPosition)&&(jumpState != 1)){//check for a crash points = 0; //remove all points if you crash drawCrash(); } //If you've reached the wallPosition and haven't crashed, you must have //survived the leap. Add a point else if (position == wallPosition){ points = points + 1; } lcd.clear(); runTimer = millis(); } } void drawCrash(){ lcd.clear(); lcd.setCursor(position-1,1); //move cursor one position left of the collision lcd.write(3);//draw 'splatted' JumpMan lcd.setCursor(wallPosition,1); lcd.write(2); //draw the wall delay(1000); // Reset the variables to put the JumpMan back at the starting point position = 0; buttonState = 0; jumpState = 0; } /* * A new character adds more realism to your game. Because your game has * 'state variables' that change as the program changes, you are able to * identify spots in the game where something should happen and then quickly * find those in the code and make the update. */ //(c) 2017 Let's Start Coding. License: www.letsstartcoding.com/bsdlicense
 

In this program you created a 'special case' for the custom character when JumpMan is in the air over a wall. This special case has a few conditions: the button must be pressed and the character must be above the wall. Your 'else' statement covers every other drawing in the game. 'Else' statements are designed to blanket 'all other cases'.