Play snake using mbed! A snake-like game that runs on the memoryLCD display on Happy Gecko.

Dependencies:   mbed MemoryLCD

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

Go to the documentation of this file.
00001 /***************************************************************************//**
00002  * @file main.cpp
00003  * @brief Demo program for game Hungry Gecko
00004  *******************************************************************************
00005  * @section License
00006  * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>
00007  *******************************************************************************
00008  *
00009  * Permission is granted to anyone to use this software for any purpose,
00010  * including commercial applications, and to alter it and redistribute it
00011  * freely, subject to the following restrictions:
00012  *
00013  * 1. The origin of this software must not be misrepresented; you must not
00014  *    claim that you wrote the original software.
00015  * 2. Altered source versions must be plainly marked as such, and must not be
00016  *    misrepresented as being the original software.
00017  * 3. This notice may not be removed or altered from any source distribution.
00018  *
00019  * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
00020  * obligation to support this Software. Silicon Labs is providing the
00021  * Software "AS IS", with no express or implied warranties of any kind,
00022  * including, but not limited to, any implied warranties of merchantability
00023  * or fitness for any particular purpose or warranties against infringement
00024  * of any proprietary rights of a third party.
00025  *
00026  * Silicon Labs will not be liable for any consequential, incidental, or
00027  * special damages, or any other relief, or for any claim by any third party,
00028  * arising from your use of this Software.
00029  *
00030  ******************************************************************************/
00031 
00032 #include "LS013B7DH03.h"
00033 #include "gecko.h"
00034 #include "food.h"
00035 #include "settings.h"
00036 
00037 /**************************** Define I/O **************************************/
00038 
00039 InterruptIn in(SW1);
00040 InterruptIn inB1(SW0);
00041 #define SCK     PE12
00042 #define MOSI    PE10
00043 
00044 DigitalOut CS(PA10);
00045 DigitalOut EXTCOM(PF3);
00046 DigitalOut DISP(PA8);
00047 
00048 SPI displaySPI(MOSI, NC, SCK);
00049 silabs::LS013B7DH03 display(&displaySPI, &CS, &EXTCOM);
00050 
00051 /**************************** Define Timers ***********************************/
00052 
00053 LowPowerTicker ticker;
00054 
00055 /**************************** Global variables ********************************/
00056 
00057 /* Flag that is set to true when the display is refreshed */
00058 volatile bool refreshed = false;
00059 
00060 /* Flag that is set to true by the ticker. Makes the gecko move at regular time intervals */
00061 volatile bool updateDisplay = true;
00062 
00063 /* A flag that ensures the controller to only read one click per frame */
00064 volatile bool PBenabled = true;
00065 
00066 /* Direction in which the gecko moves */
00067 Direction dir = UP;
00068 
00069 uint8_t score = 0;
00070 
00071 /**************************** Define callback handlers ************************/
00072 void tickerCallback(void);
00073 
00074 /* Push button handlers */
00075 void in_handler_B0();
00076 void in_handler_B1();
00077 
00078 /* Define game modes */
00079 typedef enum {
00080     PLAY, STOP
00081 } Modes;
00082 
00083 /* Set the game mode */
00084 Modes mode = PLAY;
00085 
00086 void in_handler_B0() {
00087     /* Only change the direction if push button is enabled */
00088     if (PBenabled)
00089     {
00090         switch (dir) {
00091         case (UP):
00092                 dir = LEFT;
00093             break;
00094         case (DOWN):
00095                 dir = RIGHT;
00096             break;
00097         case (RIGHT):
00098                 dir = UP;
00099             break;
00100         case (LEFT):
00101                 dir = DOWN;
00102             break;
00103         }
00104         PBenabled = false;
00105     }
00106 }
00107 
00108 void in_handler_B1() {
00109     /* Only change the direction if push button is enabled */
00110     if (PBenabled)
00111     {
00112         switch (dir) {
00113         case UP:
00114             dir = RIGHT;
00115             break;
00116         case DOWN:
00117             dir = LEFT;
00118             break;
00119         case RIGHT:
00120             dir = DOWN;
00121             break;
00122         case LEFT:
00123             dir = UP;
00124             break;
00125         }
00126         PBenabled = false;
00127     }
00128 }
00129 
00130 
00131 /* Callback functions */
00132 void tickerCallback(void) {
00133     updateDisplay = true;
00134 
00135     /* Enable push buttons if the display is refreshed */
00136     PBenabled = refreshed;
00137 }
00138 
00139 
00140 void refreshCallback(void) {
00141     refreshed = true;
00142 }
00143 
00144 /**************************** Fill the boarder ********************************/
00145 
00146 void fillBoarder(silabs::LS013B7DH03 &display){
00147     display.fill(0, 0, DISPLAY_WIDTH, TOPEDGE*STEPSIZE, Black);
00148 
00149     /* Fill right edge */
00150     display.fill(BOARD_WIDTH*STEPSIZE + BOARDERWIDTH/2, TOPEDGE*STEPSIZE + BOARDERWIDTH/2, 1, BOARD_HEIGHT*STEPSIZE, Black);
00151     for (uint8_t i=0;i<BOARD_HEIGHT;i++){
00152         for (uint8_t j=0;j<(DISPLAY_WIDTH-BOARD_WIDTH*STEPSIZE - BOARDERWIDTH/2);j++){
00153             display.pixel(BOARD_WIDTH*STEPSIZE + BOARDERWIDTH/2 +j, (i+TOPEDGE)*STEPSIZE + BOARDERWIDTH/2+j, Black);
00154         }
00155     }
00156 
00157     /* Fill bottom edge */
00158     display.fill(BOARDERWIDTH/2, (BOARD_HEIGHT+TOPEDGE)*STEPSIZE + BOARDERWIDTH/2, BOARD_WIDTH*STEPSIZE, 1, Black);
00159 
00160     for (uint8_t i=0;i<=BOARD_WIDTH;i++){
00161         for (uint8_t j=0;j<(DISPLAY_WIDTH-BOARD_WIDTH*STEPSIZE - BOARDERWIDTH/2);j++){
00162             display.pixel(i*STEPSIZE + BOARDERWIDTH/2 +j, (BOARD_HEIGHT+TOPEDGE)*STEPSIZE + BOARDERWIDTH/2+j, Black);
00163         }
00164     }
00165 
00166     /* Fill left edge */
00167     display.fill(BOARDERWIDTH/2-1, TOPEDGE*STEPSIZE + BOARDERWIDTH/2, 1, BOARD_HEIGHT*STEPSIZE, Black);
00168     for (uint8_t i=0;i<BOARD_HEIGHT;i++){
00169         for (uint8_t j=0;j<(DISPLAY_WIDTH-BOARD_WIDTH*STEPSIZE - BOARDERWIDTH/2 - 1);j++){
00170             display.pixel(j, (i+TOPEDGE)*STEPSIZE + BOARDERWIDTH/2+j, Black);
00171         }
00172     }
00173 
00174     /* Fill top edge */
00175     display.fill(BOARDERWIDTH/2, TOPEDGE*STEPSIZE + BOARDERWIDTH/2 - 1, BOARD_WIDTH*STEPSIZE, 1, Black);
00176 
00177     for (uint8_t i=0;i<=BOARD_WIDTH;i++){
00178         for (uint8_t j=0;j<(DISPLAY_WIDTH-BOARD_WIDTH*STEPSIZE - BOARDERWIDTH/2 - 1);j++){
00179             display.pixel(i*STEPSIZE + BOARDERWIDTH/2 +j, TOPEDGE*STEPSIZE + j, Black);
00180         }
00181     }
00182 
00183 }
00184 
00185 /**************************** MAIN ********************************************/
00186 int main() {
00187 
00188     /* Initialize pushbutton handlers */
00189     in.fall(in_handler_B0);
00190     inB1.fall(in_handler_B1);
00191 
00192     /* Enable the LCD */
00193     DISP = 1;
00194 
00195     /* Start generating the 3Hz call */
00196     ticker.attach(&tickerCallback, 0.3333f);
00197 
00198     /* Reset the LCD to a blank state. (All white) */
00199     refreshed = false;
00200     if (display.clearImmediate(refreshCallback) == LS013B7DH03_OK){
00201         while (refreshed == false) sleep();
00202     }
00203 
00204     fillBoarder(display);
00205     refreshed = false;
00206     if (display.update(refreshCallback) == LS013B7DH03_OK)
00207     {
00208         while (refreshed == false) sleep();
00209     }
00210     Gecko gck;
00211     Food fd;
00212     gck.draw(display);
00213     fd.draw(display);
00214 
00215     /* Push update to the display */
00216     refreshed = false;
00217     if (display.update(refreshCallback) == LS013B7DH03_OK)
00218     {
00219         while (refreshed == false) sleep();
00220     }
00221     display.foreground(White);
00222     display.background(Black);
00223     display.locate(4,0);
00224     display.printf("Score: ");
00225 
00226     display.locate(11,0);
00227     display.printf("%d", score);
00228 
00229     /* Main loop */
00230     while (1) {
00231         sleep();
00232         if (updateDisplay && refreshed && (mode==PLAY)) {
00233             updateDisplay = false;
00234 
00235             gck.move(display, dir);
00236 
00237             if (fd.isEaten(gck))
00238             {
00239                 fd.reset(display, gck);
00240                 gck.increaseLength(display, dir);
00241 
00242                 /* Redraw gecko */
00243                 gck.draw(display);
00244                 /* Update the score */
00245                 score++;
00246                 display.locate(11,0);
00247                 display.printf("%d", score);
00248             }
00249 
00250             /* Update display */
00251             refreshed = false;
00252             display.update(refreshCallback);
00253 
00254 
00255             if (gck.selfCollision()) {
00256                 mode = STOP;
00257                 gck.move(display, dir);
00258                 display.locate(3, 6);
00259                 display.printf("GAME OVER!");
00260                 refreshed = false;
00261                 display.update(refreshCallback);
00262             }
00263         }
00264     }
00265 }
00266 
00267