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

Dependencies:   mbed MemoryLCD

Hungry Gecko Game on Memory LCD

This game is meant to run on a Silicon labs EFM32 Happy Gecko Starter Kit, and demonstrate the use of the Memory LCD. User controls the push buttons on the kit PB1, and PB0 to let the gecko turn left and right respectively in order to eat the food. User should avoid running into the body of the gecko, otherwise game is over. It is allowed to hit the wall and go from the other side of it. Have fun!

Information

All examples in this repo are considered EXPERIMENTAL QUALITY, meaning this code has been created as one-off proof-of-concept and is suitable as a demonstration for experimental purposes only. This code will not be regularly maintained by Silicon Labs and there is no guarantee that these projects will work across all environments, SDK versions and hardware.

Libraries

gecko.h

This class creates a gecko object, draws it on the memory LCD according to its movement, and keeps track of the length of the gecko

gecko.h

#include "LS013B7DH03.h"
#include "settings.h"
#include "asymmetricPart.h"
 
class Gecko{
  private:
      uint8_t _position[MAXLENGTH];
      uint8_t _last;
      uint8_t _length;
 
      asymmetricPart _head;
 
      void drawPart(silabs::LS013B7DH03 &display, uint8_t x, uint8_t y) const;
      void removePart(silabs::LS013B7DH03 &display, uint8_t x, uint8_t y) const;
    public:
        Gecko();
 
        /* Moves the snake and redraws it on the display */
        void move(silabs::LS013B7DH03 &display, Direction dir);
 
        /* Redraw the entire snake */
        void draw(silabs::LS013B7DH03 &display) const;
 
        /* Check if the snake has collides with itself */
        bool selfCollision() const;
 
        /* Increases the length of the snake by one STEPSIZE x STEPSIZE tile */
        void increaseLength(silabs::LS013B7DH03 &display, Direction dir);
 
        /* Checks if the head of the snake occupies a STEP */
        bool headOccupiesTile(uint8_t x, uint8_t y) const;
 
        /* Chech if the snake occupies a STEPSIZE x STEPSIZE tile */
        bool occupiesTile(uint8_t x, uint8_t y) const;
 
        /* Get coordinates */
        uint8_t getX(uint8_t indx) const;
        uint8_t getY(uint8_t indx) const;
};

food.h

This class creates a food object, displays it on memory LCD and updates its location every time it is eaten by gecko.

food.h

#include "settings.h"
#include "LS013B7DH03.h"
 
class Gecko; // Forward declaration
#ifndef FOOD_H_
#define FOOD_H_
/* Pixel map for the food
 * 4 most significant bits y-crd, 4 least significant bits x-crd
 * The upper left corner of the part is asigned coordinates (x,y)=(0,0)
 */
class Food{
public:
    Food();
    bool isEaten(Gecko &gck);
    void reset(silabs::LS013B7DH03 &display, const Gecko &gck);
    void draw(silabs::LS013B7DH03 &display);
 
private:
    uint8_t x;
    uint8_t y;
    void remove(silabs::LS013B7DH03 &display);
};
 
#endif /* FOOD_H_ */

settings.h

This file defines the settings including the wall location, board height and width, and enum for gecko movements.

settings.h

#ifndef SETTINGS_H_
#define SETTINGS_H_
#include "LCDSettings.h"
 
#define MAXLENGTH 255
#define STEPSIZE 7
 
/*  Define board limits, note that the display height and display width is 128
 * This particlular choice leads to 255 STEPSIZE x STEPSIZE tiles. Thus,
 * the tile number can be stored in 1 uint8_t
 * */
#define TOPEDGE 2
#define BOARD_HEIGHT 15
#define BOARD_WIDTH 17
#define BOARDERWIDTH (DISPLAY_WIDTH - STEPSIZE*BOARD_WIDTH)
 
/* Define allowed direction to move */
typedef enum{
    LEFT=0, RIGHT, UP, DOWN
} Direction;
 
#endif /* SETTINGS_H_ */

asymmetricPart.h

This class creates the object of the asymmetric part of the gecko body, and updates its location on the memory LCD.

asymmetricPart.h

#include "settings.h"
#include "LS013B7DH03.h"
 
/* Bitfield containing the position of the top left corner of the part and the orientation
 * The minimum number of bits to store x, y and orientation is 10 bits (there are 255 tiles).
 * Since this will be expanded to 16 bits the x and y values are stored in 7 bits each.
 * */
 
struct positionAndDirection{
    uint8_t x:7;
    uint8_t y:7;
    uint8_t direction:2;
};
 
class asymmetricPart{
private:
    positionAndDirection _posAndDir;
    const uint8_t *_px_map;
    uint8_t _nPix;
 
    /* Private member functions */
    void draw(silabs::LS013B7DH03 &display, uint8_t color) const;
public:
    asymmetricPart();
    asymmetricPart(uint8_t x, uint8_t y, Direction dir,  const uint8_t *px_map, uint8_t nPix);
 
    /* Set all member variables */
    void init(uint8_t x, uint8_t y, Direction dir,  const uint8_t *px_map, uint8_t nPix);
 
    /* Draw the part on the screen */
    void draw(silabs::LS013B7DH03 &display) const {draw(display, Black);};
 
    /* Erase the part from the screen */
    void remove(silabs::LS013B7DH03 &display) const {draw(display, White);};
 
    /* Get member variables */
    uint8_t getX() const {return _posAndDir.x;};
    uint8_t getY() const {return _posAndDir.y;};
    uint8_t getDir() const {return _posAndDir.direction;};
 
    /* Set member variables */
    void setX(uint8_t x) {_posAndDir.x = x&0x7F;};
    void setY(uint8_t y) {_posAndDir.y = y&0x7F;};
    void setDir(Direction dir) {_posAndDir.direction = static_cast<int>(dir)&0x0003;};
};

Full Example

mian.cpp

#include "LS013B7DH03.h"
#include "gecko.h"
#include "food.h"
#include "settings.h"
 
/**************************** Define I/O **************************************/
 
InterruptIn in(SW1);
InterruptIn inB1(SW0);
#define SCK     PE12
#define MOSI    PE10
 
DigitalOut CS(PA10);
DigitalOut EXTCOM(PF3);
DigitalOut DISP(PA8);
 
SPI displaySPI(MOSI, NC, SCK);
silabs::LS013B7DH03 display(&displaySPI, &CS, &EXTCOM);
 
/**************************** Define Timers ***********************************/
 
LowPowerTicker ticker;
 
/**************************** Global variables ********************************/
 
/* Flag that is set to true when the display is refreshed */
volatile bool refreshed = false;
 
/* Flag that is set to true by the ticker. Makes the gecko move at regular time intervals */
volatile bool updateDisplay = true;
 
/* A flag that ensures the controller to only read one click per frame */
volatile bool PBenabled = true;
 
/* Direction in which the gecko moves */
Direction dir = UP;
 
uint8_t score = 0;
 
/**************************** Define callback handlers ************************/
void tickerCallback(void);
 
/* Push button handlers */
void in_handler_B0();
void in_handler_B1();
 
/* Define game modes */
typedef enum {
    PLAY, STOP
} Modes;
 
/* Set the game mode */
Modes mode = PLAY;
 
void in_handler_B0() {
    /* Only change the direction if push button is enabled */
    if (PBenabled)
    {
        switch (dir) {
        case (UP):
                dir = LEFT;
            break;
        case (DOWN):
                dir = RIGHT;
            break;
        case (RIGHT):
                dir = UP;
            break;
        case (LEFT):
                dir = DOWN;
            break;
        }
        PBenabled = false;
    }
}
 
void in_handler_B1() {
    /* Only change the direction if push button is enabled */
    if (PBenabled)
    {
        switch (dir) {
        case UP:
            dir = RIGHT;
            break;
        case DOWN:
            dir = LEFT;
            break;
        case RIGHT:
            dir = DOWN;
            break;
        case LEFT:
            dir = UP;
            break;
        }
        PBenabled = false;
    }
}
 
 
/* Callback functions */
void tickerCallback(void) {
    updateDisplay = true;
 
    /* Enable push buttons if the display is refreshed */
    PBenabled = refreshed;
}
 
 
void refreshCallback(void) {
    refreshed = true;
}
 
/**************************** Fill the boarder ********************************/
 
void fillBoarder(silabs::LS013B7DH03 &display){
    display.fill(0, 0, DISPLAY_WIDTH, TOPEDGE*STEPSIZE, Black);
 
    /* Fill right edge */
    display.fill(BOARD_WIDTH*STEPSIZE + BOARDERWIDTH/2, TOPEDGE*STEPSIZE + BOARDERWIDTH/2, 1, BOARD_HEIGHT*STEPSIZE, Black);
    for (uint8_t i=0;i<BOARD_HEIGHT;i++){
        for (uint8_t j=0;j<(DISPLAY_WIDTH-BOARD_WIDTH*STEPSIZE - BOARDERWIDTH/2);j++){
            display.pixel(BOARD_WIDTH*STEPSIZE + BOARDERWIDTH/2 +j, (i+TOPEDGE)*STEPSIZE + BOARDERWIDTH/2+j, Black);
        }
    }
 
    /* Fill bottom edge */
    display.fill(BOARDERWIDTH/2, (BOARD_HEIGHT+TOPEDGE)*STEPSIZE + BOARDERWIDTH/2, BOARD_WIDTH*STEPSIZE, 1, Black);
 
    for (uint8_t i=0;i<=BOARD_WIDTH;i++){
        for (uint8_t j=0;j<(DISPLAY_WIDTH-BOARD_WIDTH*STEPSIZE - BOARDERWIDTH/2);j++){
            display.pixel(i*STEPSIZE + BOARDERWIDTH/2 +j, (BOARD_HEIGHT+TOPEDGE)*STEPSIZE + BOARDERWIDTH/2+j, Black);
        }
    }
 
    /* Fill left edge */
    display.fill(BOARDERWIDTH/2-1, TOPEDGE*STEPSIZE + BOARDERWIDTH/2, 1, BOARD_HEIGHT*STEPSIZE, Black);
    for (uint8_t i=0;i<BOARD_HEIGHT;i++){
        for (uint8_t j=0;j<(DISPLAY_WIDTH-BOARD_WIDTH*STEPSIZE - BOARDERWIDTH/2 - 1);j++){
            display.pixel(j, (i+TOPEDGE)*STEPSIZE + BOARDERWIDTH/2+j, Black);
        }
    }
 
    /* Fill top edge */
    display.fill(BOARDERWIDTH/2, TOPEDGE*STEPSIZE + BOARDERWIDTH/2 - 1, BOARD_WIDTH*STEPSIZE, 1, Black);
 
    for (uint8_t i=0;i<=BOARD_WIDTH;i++){
        for (uint8_t j=0;j<(DISPLAY_WIDTH-BOARD_WIDTH*STEPSIZE - BOARDERWIDTH/2 - 1);j++){
            display.pixel(i*STEPSIZE + BOARDERWIDTH/2 +j, TOPEDGE*STEPSIZE + j, Black);
        }
    }
 
}
 
/**************************** MAIN ********************************************/
int main() {
 
    /* Initialize pushbutton handlers */
    in.fall(in_handler_B0);
    inB1.fall(in_handler_B1);
 
    /* Enable the LCD */
    DISP = 1;
 
    /* Start generating the 3Hz call */
    ticker.attach(&tickerCallback, 0.3333f);
 
    /* Reset the LCD to a blank state. (All white) */
    refreshed = false;
    if (display.clearImmediate(refreshCallback) == LS013B7DH03_OK){
        while (refreshed == false) sleep();
    }
 
    fillBoarder(display);
    refreshed = false;
    if (display.update(refreshCallback) == LS013B7DH03_OK)
    {
        while (refreshed == false) sleep();
    }
    Gecko gck;
    Food fd;
    gck.draw(display);
    fd.draw(display);
 
    /* Push update to the display */
    refreshed = false;
    if (display.update(refreshCallback) == LS013B7DH03_OK)
    {
        while (refreshed == false) sleep();
    }
    display.foreground(White);
    display.background(Black);
    display.locate(4,0);
    display.printf("Score: ");
 
    display.locate(11,0);
    display.printf("%d", score);
 
    /* Main loop */
    while (1) {
        sleep();
        if (updateDisplay && refreshed && (mode==PLAY)) {
            updateDisplay = false;
 
            gck.move(display, dir);
 
            if (fd.isEaten(gck))
            {
                fd.reset(display, gck);
                gck.increaseLength(display, dir);
 
                /* Redraw gecko */
                gck.draw(display);
                /* Update the score */
                score++;
                display.locate(11,0);
                display.printf("%d", score);
            }
 
            /* Update display */
            refreshed = false;
            display.update(refreshCallback);
 
 
            if (gck.selfCollision()) {
                mode = STOP;
                gck.move(display, dir);
                display.locate(3, 6);
                display.printf("GAME OVER!");
                refreshed = false;
                display.update(refreshCallback);
            }
        }
    }
}
Committer:
dakleive
Date:
Fri Jul 24 13:51:29 2015 +0000
Revision:
1:5342a84ff663
Parent:
0:008c379fb5e6
Child:
2:5a41b935bc86
Removed an unused variable in main.cpp. Imported the MemoryLCD library instead of using the memLCD demo.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dakleive 0:008c379fb5e6 1 #include "LS013B7DH03.h"
dakleive 0:008c379fb5e6 2 #include "gecko.h"
dakleive 0:008c379fb5e6 3 #include "food.h"
dakleive 0:008c379fb5e6 4 #include "settings.h"
dakleive 0:008c379fb5e6 5
dakleive 0:008c379fb5e6 6 /**************************** Define I/O **************************************/
dakleive 0:008c379fb5e6 7
dakleive 0:008c379fb5e6 8 InterruptIn in(SW1);
dakleive 0:008c379fb5e6 9 InterruptIn inB1(SW0);
dakleive 0:008c379fb5e6 10 #define SCK PE12
dakleive 0:008c379fb5e6 11 #define MOSI PE10
dakleive 0:008c379fb5e6 12
dakleive 0:008c379fb5e6 13 DigitalOut CS(PA10);
dakleive 0:008c379fb5e6 14 DigitalOut EXTCOM(PF3);
dakleive 0:008c379fb5e6 15 DigitalOut DISP(PA8);
dakleive 0:008c379fb5e6 16
dakleive 0:008c379fb5e6 17 SPI displaySPI(MOSI, NC, SCK);
dakleive 0:008c379fb5e6 18 silabs::LS013B7DH03 display(&displaySPI, &CS, &EXTCOM);
dakleive 0:008c379fb5e6 19
dakleive 0:008c379fb5e6 20 /**************************** Define Timers ***********************************/
dakleive 0:008c379fb5e6 21
dakleive 0:008c379fb5e6 22 LowPowerTicker ticker;
dakleive 0:008c379fb5e6 23
dakleive 0:008c379fb5e6 24 /**************************** Global variables ********************************/
dakleive 0:008c379fb5e6 25
dakleive 0:008c379fb5e6 26 /* Flag that is set to true when the display is refreshed */
dakleive 0:008c379fb5e6 27 volatile bool refreshed = false;
dakleive 0:008c379fb5e6 28
dakleive 0:008c379fb5e6 29 /* Flag that is set to true by the ticker. Makes the gecko move at regular time intervals */
dakleive 0:008c379fb5e6 30 volatile bool updateDisplay = true;
dakleive 0:008c379fb5e6 31
dakleive 0:008c379fb5e6 32 /* A flag that ensures the controller to only read one click per frame */
dakleive 0:008c379fb5e6 33 volatile bool PBenabled = true;
dakleive 0:008c379fb5e6 34
dakleive 0:008c379fb5e6 35 /* Direction in which the gecko moves */
dakleive 0:008c379fb5e6 36 Direction dir = UP;
dakleive 0:008c379fb5e6 37
dakleive 0:008c379fb5e6 38 uint8_t score = 0;
dakleive 0:008c379fb5e6 39
dakleive 0:008c379fb5e6 40 /**************************** Define callback handlers ************************/
dakleive 0:008c379fb5e6 41 void tickerCallback(void);
dakleive 0:008c379fb5e6 42
dakleive 0:008c379fb5e6 43 /* Push button handlers */
dakleive 0:008c379fb5e6 44 void in_handler_B0();
dakleive 0:008c379fb5e6 45 void in_handler_B1();
dakleive 0:008c379fb5e6 46
dakleive 0:008c379fb5e6 47 /* Define game modes */
dakleive 0:008c379fb5e6 48 typedef enum {
dakleive 0:008c379fb5e6 49 PLAY, STOP
dakleive 0:008c379fb5e6 50 } Modes;
dakleive 0:008c379fb5e6 51
dakleive 0:008c379fb5e6 52 /* Set the game mode */
dakleive 0:008c379fb5e6 53 Modes mode = PLAY;
dakleive 0:008c379fb5e6 54
dakleive 0:008c379fb5e6 55 void in_handler_B0() {
dakleive 0:008c379fb5e6 56 /* Only change the direction if push button is enabled */
dakleive 0:008c379fb5e6 57 if (PBenabled)
dakleive 0:008c379fb5e6 58 {
dakleive 0:008c379fb5e6 59 switch (dir) {
dakleive 0:008c379fb5e6 60 case (UP):
dakleive 0:008c379fb5e6 61 dir = LEFT;
dakleive 0:008c379fb5e6 62 break;
dakleive 0:008c379fb5e6 63 case (DOWN):
dakleive 0:008c379fb5e6 64 dir = RIGHT;
dakleive 0:008c379fb5e6 65 break;
dakleive 0:008c379fb5e6 66 case (RIGHT):
dakleive 0:008c379fb5e6 67 dir = UP;
dakleive 0:008c379fb5e6 68 break;
dakleive 0:008c379fb5e6 69 case (LEFT):
dakleive 0:008c379fb5e6 70 dir = DOWN;
dakleive 0:008c379fb5e6 71 break;
dakleive 0:008c379fb5e6 72 }
dakleive 0:008c379fb5e6 73 PBenabled = false;
dakleive 0:008c379fb5e6 74 }
dakleive 0:008c379fb5e6 75 }
dakleive 0:008c379fb5e6 76
dakleive 0:008c379fb5e6 77 void in_handler_B1() {
dakleive 0:008c379fb5e6 78 /* Only change the direction if push button is enabled */
dakleive 0:008c379fb5e6 79 if (PBenabled)
dakleive 0:008c379fb5e6 80 {
dakleive 0:008c379fb5e6 81 switch (dir) {
dakleive 0:008c379fb5e6 82 case UP:
dakleive 0:008c379fb5e6 83 dir = RIGHT;
dakleive 0:008c379fb5e6 84 break;
dakleive 0:008c379fb5e6 85 case DOWN:
dakleive 0:008c379fb5e6 86 dir = LEFT;
dakleive 0:008c379fb5e6 87 break;
dakleive 0:008c379fb5e6 88 case RIGHT:
dakleive 0:008c379fb5e6 89 dir = DOWN;
dakleive 0:008c379fb5e6 90 break;
dakleive 0:008c379fb5e6 91 case LEFT:
dakleive 0:008c379fb5e6 92 dir = UP;
dakleive 0:008c379fb5e6 93 break;
dakleive 0:008c379fb5e6 94 }
dakleive 0:008c379fb5e6 95 PBenabled = false;
dakleive 0:008c379fb5e6 96 }
dakleive 0:008c379fb5e6 97 }
dakleive 0:008c379fb5e6 98
dakleive 0:008c379fb5e6 99
dakleive 0:008c379fb5e6 100 /* Callback functions */
dakleive 0:008c379fb5e6 101 void tickerCallback(void) {
dakleive 0:008c379fb5e6 102 updateDisplay = true;
dakleive 0:008c379fb5e6 103
dakleive 0:008c379fb5e6 104 /* Enable push buttons if the display is refreshed */
dakleive 0:008c379fb5e6 105 PBenabled = refreshed;
dakleive 0:008c379fb5e6 106 }
dakleive 0:008c379fb5e6 107
dakleive 0:008c379fb5e6 108
dakleive 0:008c379fb5e6 109 void refreshCallback(void) {
dakleive 0:008c379fb5e6 110 refreshed = true;
dakleive 0:008c379fb5e6 111 }
dakleive 0:008c379fb5e6 112
dakleive 0:008c379fb5e6 113 /**************************** Fill the boarder ********************************/
dakleive 0:008c379fb5e6 114
dakleive 0:008c379fb5e6 115 void fillBoarder(silabs::LS013B7DH03 &display){
dakleive 0:008c379fb5e6 116 display.fill(0, 0, DISPLAY_WIDTH, TOPEDGE*STEPSIZE, Black);
dakleive 0:008c379fb5e6 117
dakleive 0:008c379fb5e6 118 /* Fill right edge */
dakleive 0:008c379fb5e6 119 display.fill(BOARD_WIDTH*STEPSIZE + BOARDERWIDTH/2, TOPEDGE*STEPSIZE + BOARDERWIDTH/2, 1, BOARD_HEIGHT*STEPSIZE, Black);
dakleive 0:008c379fb5e6 120 for (uint8_t i=0;i<BOARD_HEIGHT;i++){
dakleive 0:008c379fb5e6 121 for (uint8_t j=0;j<(DISPLAY_WIDTH-BOARD_WIDTH*STEPSIZE - BOARDERWIDTH/2);j++){
dakleive 0:008c379fb5e6 122 display.pixel(BOARD_WIDTH*STEPSIZE + BOARDERWIDTH/2 +j, (i+TOPEDGE)*STEPSIZE + BOARDERWIDTH/2+j, Black);
dakleive 0:008c379fb5e6 123 }
dakleive 0:008c379fb5e6 124 }
dakleive 0:008c379fb5e6 125
dakleive 0:008c379fb5e6 126 /* Fill bottom edge */
dakleive 0:008c379fb5e6 127 display.fill(BOARDERWIDTH/2, (BOARD_HEIGHT+TOPEDGE)*STEPSIZE + BOARDERWIDTH/2, BOARD_WIDTH*STEPSIZE, 1, Black);
dakleive 0:008c379fb5e6 128
dakleive 0:008c379fb5e6 129 for (uint8_t i=0;i<=BOARD_WIDTH;i++){
dakleive 0:008c379fb5e6 130 for (uint8_t j=0;j<(DISPLAY_WIDTH-BOARD_WIDTH*STEPSIZE - BOARDERWIDTH/2);j++){
dakleive 0:008c379fb5e6 131 display.pixel(i*STEPSIZE + BOARDERWIDTH/2 +j, (BOARD_HEIGHT+TOPEDGE)*STEPSIZE + BOARDERWIDTH/2+j, Black);
dakleive 0:008c379fb5e6 132 }
dakleive 0:008c379fb5e6 133 }
dakleive 0:008c379fb5e6 134
dakleive 0:008c379fb5e6 135 /* Fill left edge */
dakleive 0:008c379fb5e6 136 display.fill(BOARDERWIDTH/2-1, TOPEDGE*STEPSIZE + BOARDERWIDTH/2, 1, BOARD_HEIGHT*STEPSIZE, Black);
dakleive 0:008c379fb5e6 137 for (uint8_t i=0;i<BOARD_HEIGHT;i++){
dakleive 0:008c379fb5e6 138 for (uint8_t j=0;j<(DISPLAY_WIDTH-BOARD_WIDTH*STEPSIZE - BOARDERWIDTH/2 - 1);j++){
dakleive 0:008c379fb5e6 139 display.pixel(j, (i+TOPEDGE)*STEPSIZE + BOARDERWIDTH/2+j, Black);
dakleive 0:008c379fb5e6 140 }
dakleive 0:008c379fb5e6 141 }
dakleive 0:008c379fb5e6 142
dakleive 0:008c379fb5e6 143 /* Fill top edge */
dakleive 0:008c379fb5e6 144 display.fill(BOARDERWIDTH/2, TOPEDGE*STEPSIZE + BOARDERWIDTH/2 - 1, BOARD_WIDTH*STEPSIZE, 1, Black);
dakleive 0:008c379fb5e6 145
dakleive 0:008c379fb5e6 146 for (uint8_t i=0;i<=BOARD_WIDTH;i++){
dakleive 0:008c379fb5e6 147 for (uint8_t j=0;j<(DISPLAY_WIDTH-BOARD_WIDTH*STEPSIZE - BOARDERWIDTH/2 - 1);j++){
dakleive 0:008c379fb5e6 148 display.pixel(i*STEPSIZE + BOARDERWIDTH/2 +j, TOPEDGE*STEPSIZE + j, Black);
dakleive 0:008c379fb5e6 149 }
dakleive 0:008c379fb5e6 150 }
dakleive 0:008c379fb5e6 151
dakleive 0:008c379fb5e6 152 }
dakleive 0:008c379fb5e6 153
dakleive 0:008c379fb5e6 154 /**************************** MAIN ********************************************/
dakleive 0:008c379fb5e6 155 int main() {
dakleive 0:008c379fb5e6 156
dakleive 0:008c379fb5e6 157 /* Initialize pushbutton handlers */
dakleive 0:008c379fb5e6 158 in.fall(in_handler_B0);
dakleive 0:008c379fb5e6 159 inB1.fall(in_handler_B1);
dakleive 0:008c379fb5e6 160
dakleive 0:008c379fb5e6 161 /* Enable the LCD */
dakleive 0:008c379fb5e6 162 DISP = 1;
dakleive 0:008c379fb5e6 163
dakleive 0:008c379fb5e6 164 /* Start generating the 3Hz call */
dakleive 0:008c379fb5e6 165 ticker.attach(&tickerCallback, 0.3333f);
dakleive 0:008c379fb5e6 166
dakleive 0:008c379fb5e6 167 /* Reset the LCD to a blank state. (All white) */
dakleive 0:008c379fb5e6 168 refreshed = false;
dakleive 0:008c379fb5e6 169 if (display.clearImmediate(refreshCallback) == LS013B7DH03_OK){
dakleive 0:008c379fb5e6 170 while (refreshed == false) sleep();
dakleive 0:008c379fb5e6 171 }
dakleive 0:008c379fb5e6 172
dakleive 0:008c379fb5e6 173 fillBoarder(display);
dakleive 0:008c379fb5e6 174 refreshed = false;
dakleive 0:008c379fb5e6 175 if (display.update(refreshCallback) == LS013B7DH03_OK)
dakleive 0:008c379fb5e6 176 {
dakleive 0:008c379fb5e6 177 while (refreshed == false) sleep();
dakleive 0:008c379fb5e6 178 }
dakleive 0:008c379fb5e6 179 Gecko gck;
dakleive 0:008c379fb5e6 180 Food fd;
dakleive 0:008c379fb5e6 181 gck.draw(display);
dakleive 0:008c379fb5e6 182 fd.draw(display);
dakleive 0:008c379fb5e6 183
dakleive 0:008c379fb5e6 184 /* Push update to the display */
dakleive 0:008c379fb5e6 185 refreshed = false;
dakleive 0:008c379fb5e6 186 if (display.update(refreshCallback) == LS013B7DH03_OK)
dakleive 0:008c379fb5e6 187 {
dakleive 0:008c379fb5e6 188 while (refreshed == false) sleep();
dakleive 0:008c379fb5e6 189 }
dakleive 0:008c379fb5e6 190 display.foreground(White);
dakleive 0:008c379fb5e6 191 display.background(Black);
dakleive 0:008c379fb5e6 192 display.locate(4,0);
dakleive 0:008c379fb5e6 193 display.printf("Score: ");
dakleive 0:008c379fb5e6 194
dakleive 0:008c379fb5e6 195 display.locate(11,0);
dakleive 0:008c379fb5e6 196 display.printf("%d", score);
dakleive 0:008c379fb5e6 197
dakleive 0:008c379fb5e6 198 /* Main loop */
dakleive 0:008c379fb5e6 199 while (1) {
dakleive 0:008c379fb5e6 200 sleep();
dakleive 0:008c379fb5e6 201 if (updateDisplay && refreshed && (mode==PLAY)) {
dakleive 0:008c379fb5e6 202 updateDisplay = false;
dakleive 0:008c379fb5e6 203
dakleive 0:008c379fb5e6 204 gck.move(display, dir);
dakleive 0:008c379fb5e6 205
dakleive 0:008c379fb5e6 206 if (fd.isEaten(gck))
dakleive 0:008c379fb5e6 207 {
dakleive 0:008c379fb5e6 208 fd.reset(display, gck);
dakleive 0:008c379fb5e6 209 gck.increaseLength(display, dir);
dakleive 0:008c379fb5e6 210
dakleive 0:008c379fb5e6 211 /* Redraw gecko */
dakleive 0:008c379fb5e6 212 gck.draw(display);
dakleive 0:008c379fb5e6 213 /* Update the score */
dakleive 0:008c379fb5e6 214 score++;
dakleive 0:008c379fb5e6 215 display.locate(11,0);
dakleive 0:008c379fb5e6 216 display.printf("%d", score);
dakleive 0:008c379fb5e6 217 }
dakleive 0:008c379fb5e6 218
dakleive 0:008c379fb5e6 219 /* Update display */
dakleive 0:008c379fb5e6 220 refreshed = false;
dakleive 0:008c379fb5e6 221 display.update(refreshCallback);
dakleive 0:008c379fb5e6 222
dakleive 0:008c379fb5e6 223
dakleive 0:008c379fb5e6 224 if (gck.selfCollision()) {
dakleive 0:008c379fb5e6 225 mode = STOP;
dakleive 0:008c379fb5e6 226 gck.move(display, dir);
dakleive 0:008c379fb5e6 227 display.locate(3, 6);
dakleive 0:008c379fb5e6 228 display.printf("GAME OVER!");
dakleive 0:008c379fb5e6 229 refreshed = false;
dakleive 0:008c379fb5e6 230 display.update(refreshCallback);
dakleive 0:008c379fb5e6 231 }
dakleive 0:008c379fb5e6 232 }
dakleive 0:008c379fb5e6 233 }
dakleive 0:008c379fb5e6 234 }
dakleive 0:008c379fb5e6 235
dakleive 0:008c379fb5e6 236