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:
stevew817
Date:
Mon Sep 12 10:52:53 2016 +0000
Revision:
3:db0ad94fc6aa
Parent:
2:5a41b935bc86
Pull latest libraries

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lichang 2:5a41b935bc86 1 /***************************************************************************//**
lichang 2:5a41b935bc86 2 * @file gecko.cpp
lichang 2:5a41b935bc86 3 * @brief class for creating a gecko-like object and keeps track of its momvement
lichang 2:5a41b935bc86 4 *******************************************************************************
lichang 2:5a41b935bc86 5 * @section License
lichang 2:5a41b935bc86 6 * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>
lichang 2:5a41b935bc86 7 *******************************************************************************
lichang 2:5a41b935bc86 8 *
lichang 2:5a41b935bc86 9 * Permission is granted to anyone to use this software for any purpose,
lichang 2:5a41b935bc86 10 * including commercial applications, and to alter it and redistribute it
lichang 2:5a41b935bc86 11 * freely, subject to the following restrictions:
lichang 2:5a41b935bc86 12 *
lichang 2:5a41b935bc86 13 * 1. The origin of this software must not be misrepresented; you must not
lichang 2:5a41b935bc86 14 * claim that you wrote the original software.
lichang 2:5a41b935bc86 15 * 2. Altered source versions must be plainly marked as such, and must not be
lichang 2:5a41b935bc86 16 * misrepresented as being the original software.
lichang 2:5a41b935bc86 17 * 3. This notice may not be removed or altered from any source distribution.
lichang 2:5a41b935bc86 18 *
lichang 2:5a41b935bc86 19 * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
lichang 2:5a41b935bc86 20 * obligation to support this Software. Silicon Labs is providing the
lichang 2:5a41b935bc86 21 * Software "AS IS", with no express or implied warranties of any kind,
lichang 2:5a41b935bc86 22 * including, but not limited to, any implied warranties of merchantability
lichang 2:5a41b935bc86 23 * or fitness for any particular purpose or warranties against infringement
lichang 2:5a41b935bc86 24 * of any proprietary rights of a third party.
lichang 2:5a41b935bc86 25 *
lichang 2:5a41b935bc86 26 * Silicon Labs will not be liable for any consequential, incidental, or
lichang 2:5a41b935bc86 27 * special damages, or any other relief, or for any claim by any third party,
lichang 2:5a41b935bc86 28 * arising from your use of this Software.
lichang 2:5a41b935bc86 29 *
lichang 2:5a41b935bc86 30 ******************************************************************************/
lichang 2:5a41b935bc86 31
dakleive 0:008c379fb5e6 32 #include "gecko.h"
dakleive 0:008c379fb5e6 33
dakleive 0:008c379fb5e6 34 /* Number of pixels used in the Gecko head */
dakleive 0:008c379fb5e6 35 #define NPIXHEAD 16
dakleive 0:008c379fb5e6 36 /* Number of pixels used in one Gecko part */
dakleive 0:008c379fb5e6 37 #define NPARTPIXEL 21
dakleive 0:008c379fb5e6 38
dakleive 0:008c379fb5e6 39 /*
dakleive 0:008c379fb5e6 40 * Pixel map for a gecko part and head
dakleive 0:008c379fb5e6 41 * y-crd is encoded in the 4 most significant bits, x-crd is encoded in the 4 least significant bits
dakleive 0:008c379fb5e6 42 * The upper left corner of the part is assigned coordinates (x,y)=(0,0)
dakleive 0:008c379fb5e6 43 */
dakleive 0:008c379fb5e6 44
dakleive 0:008c379fb5e6 45 const uint8_t head_px_map[NPIXHEAD] = {0x03, 0x12, 0x14, 0x21, 0x25, 0x30, 0x32, 0x34, 0x36, 0x40, 0x46, 0x51, 0x55, 0x62, 0x63, 0x64};
dakleive 0:008c379fb5e6 46 const uint8_t gecko_px_map[NPARTPIXEL] = {0x02, 0x03, 0x04, 0x11, 0x15, 0x20, 0x23, 0x26, 0x30, 0x32, 0x33, 0x34, 0x36, 0x40, 0x43, 0x46, 0x51, 0x55, 0x62, 0x63, 0x64};
dakleive 0:008c379fb5e6 47
dakleive 0:008c379fb5e6 48
dakleive 0:008c379fb5e6 49 Gecko::Gecko():_length(10){
dakleive 0:008c379fb5e6 50 _head.init(10, 4, UP, head_px_map, NPIXHEAD);
dakleive 0:008c379fb5e6 51 _last = _length-1;
dakleive 0:008c379fb5e6 52 for (int i=0;i<_length;i++){
dakleive 0:008c379fb5e6 53 _position[i] = (_head.getY() + i +1)*BOARD_WIDTH + _head.getX();
dakleive 0:008c379fb5e6 54 }
dakleive 0:008c379fb5e6 55
dakleive 0:008c379fb5e6 56 }
dakleive 0:008c379fb5e6 57
dakleive 0:008c379fb5e6 58 void Gecko::move(silabs::LS013B7DH03 &display, Direction dir){
dakleive 0:008c379fb5e6 59
dakleive 0:008c379fb5e6 60 /* Remove the last part of the gecko */
dakleive 0:008c379fb5e6 61 this->removePart(display, this->getX(_last)*STEPSIZE + BOARDERWIDTH/2, (this->getY(_last)+TOPEDGE)*STEPSIZE + BOARDERWIDTH/2);
dakleive 0:008c379fb5e6 62
dakleive 0:008c379fb5e6 63 /* Remove head */
dakleive 0:008c379fb5e6 64 _head.remove(display);
dakleive 0:008c379fb5e6 65
dakleive 0:008c379fb5e6 66 /* Update the part next to the head */
dakleive 0:008c379fb5e6 67 _head.setDir(dir);
dakleive 0:008c379fb5e6 68 _position[_last] = _head.getY()*BOARD_WIDTH + _head.getX();
dakleive 0:008c379fb5e6 69
dakleive 0:008c379fb5e6 70 switch(dir){
dakleive 0:008c379fb5e6 71 case UP:
dakleive 0:008c379fb5e6 72 if (_head.getY() == 0)
dakleive 0:008c379fb5e6 73 {
dakleive 0:008c379fb5e6 74 _head.setY(BOARD_HEIGHT-1);
dakleive 0:008c379fb5e6 75 }
dakleive 0:008c379fb5e6 76 else
dakleive 0:008c379fb5e6 77 {
dakleive 0:008c379fb5e6 78 _head.setY(_head.getY() - 1);
dakleive 0:008c379fb5e6 79 }
dakleive 0:008c379fb5e6 80 break;
dakleive 0:008c379fb5e6 81 case DOWN:
dakleive 0:008c379fb5e6 82 if ( _head.getY() == (BOARD_HEIGHT-1))
dakleive 0:008c379fb5e6 83 {
dakleive 0:008c379fb5e6 84 _head.setY(0);
dakleive 0:008c379fb5e6 85 }
dakleive 0:008c379fb5e6 86 else
dakleive 0:008c379fb5e6 87 {
dakleive 0:008c379fb5e6 88 _head.setY(_head.getY() + 1);
dakleive 0:008c379fb5e6 89 }
dakleive 0:008c379fb5e6 90 break;
dakleive 0:008c379fb5e6 91 case RIGHT:
dakleive 0:008c379fb5e6 92 if (_head.getX() == (BOARD_WIDTH-1))
dakleive 0:008c379fb5e6 93 {
dakleive 0:008c379fb5e6 94 _head.setX(0);
dakleive 0:008c379fb5e6 95 }
dakleive 0:008c379fb5e6 96 else
dakleive 0:008c379fb5e6 97 {
dakleive 0:008c379fb5e6 98 _head.setX(_head.getX() + 1);
dakleive 0:008c379fb5e6 99 }
dakleive 0:008c379fb5e6 100 break;
dakleive 0:008c379fb5e6 101 case LEFT:
dakleive 0:008c379fb5e6 102 if (_head.getX() == 0)
dakleive 0:008c379fb5e6 103 {
dakleive 0:008c379fb5e6 104 _head.setX(BOARD_WIDTH-1);
dakleive 0:008c379fb5e6 105 }
dakleive 0:008c379fb5e6 106 else
dakleive 0:008c379fb5e6 107 {
dakleive 0:008c379fb5e6 108 _head.setX(_head.getX() - 1);
dakleive 0:008c379fb5e6 109 }
dakleive 0:008c379fb5e6 110 break;
dakleive 0:008c379fb5e6 111 }
dakleive 0:008c379fb5e6 112
dakleive 0:008c379fb5e6 113 /* Draw the parts of the gecko which have been moved */
dakleive 0:008c379fb5e6 114 _head.draw(display);
dakleive 0:008c379fb5e6 115 this->drawPart(display, this->getX(_last)*STEPSIZE + BOARDERWIDTH/2, (this->getY(_last)+TOPEDGE)*STEPSIZE + BOARDERWIDTH/2);
dakleive 0:008c379fb5e6 116
dakleive 0:008c379fb5e6 117 /* Update the index of the last part */
dakleive 0:008c379fb5e6 118 if (_last == 0){
dakleive 0:008c379fb5e6 119 _last += _length;
dakleive 0:008c379fb5e6 120 }
dakleive 0:008c379fb5e6 121 _last -= 1;
dakleive 0:008c379fb5e6 122 }
dakleive 0:008c379fb5e6 123
dakleive 0:008c379fb5e6 124 void Gecko::draw(silabs::LS013B7DH03 &display) const{
dakleive 0:008c379fb5e6 125 _head.draw(display);
dakleive 0:008c379fb5e6 126
dakleive 0:008c379fb5e6 127 /* Loop over indices of all parts of the gecko */
dakleive 0:008c379fb5e6 128 for (uint8_t i=0;i<_length;i++){
dakleive 0:008c379fb5e6 129 this->drawPart(display, this->getX(i)*STEPSIZE + BOARDERWIDTH/2, (this->getY(i)+TOPEDGE)*STEPSIZE + BOARDERWIDTH/2);
dakleive 0:008c379fb5e6 130 }
dakleive 0:008c379fb5e6 131 }
dakleive 0:008c379fb5e6 132
dakleive 0:008c379fb5e6 133 bool Gecko::selfCollision() const{
dakleive 0:008c379fb5e6 134 /* Check if some pixels have the same coordinate */
dakleive 0:008c379fb5e6 135 for (int i=0;i<_length;i++)
dakleive 0:008c379fb5e6 136 {
dakleive 0:008c379fb5e6 137 if ((_head.getX()==this->getX(i)) && (_head.getY()==this->getY(i))){
dakleive 0:008c379fb5e6 138 return true;
dakleive 0:008c379fb5e6 139 }
dakleive 0:008c379fb5e6 140 }
dakleive 0:008c379fb5e6 141 return false;
dakleive 0:008c379fb5e6 142 }
dakleive 0:008c379fb5e6 143
dakleive 0:008c379fb5e6 144 void Gecko::increaseLength(silabs::LS013B7DH03 &display, Direction dir)
dakleive 0:008c379fb5e6 145 {
dakleive 0:008c379fb5e6 146 if ((_length + 1)> MAXLENGTH) return;
dakleive 0:008c379fb5e6 147
dakleive 0:008c379fb5e6 148 /* Store the tail of the gecko */
dakleive 0:008c379fb5e6 149 uint8_t tempPos = _position[_last] ;
dakleive 0:008c379fb5e6 150
dakleive 0:008c379fb5e6 151 /* Move the gecko */
dakleive 0:008c379fb5e6 152 this->move(display, dir);
dakleive 0:008c379fb5e6 153
dakleive 0:008c379fb5e6 154 uint8_t temp[MAXLENGTH];
dakleive 0:008c379fb5e6 155
dakleive 0:008c379fb5e6 156 /* Copy the front of the gecko */
dakleive 0:008c379fb5e6 157 for (uint8_t i = _last + 1;i<_length;i++)
dakleive 0:008c379fb5e6 158 {
dakleive 0:008c379fb5e6 159 temp[i] = _position[i];
dakleive 0:008c379fb5e6 160 }
dakleive 0:008c379fb5e6 161
dakleive 0:008c379fb5e6 162 /* Insert the "old" tail */
dakleive 0:008c379fb5e6 163 _position[_last + 1] = tempPos;
dakleive 0:008c379fb5e6 164
dakleive 0:008c379fb5e6 165 /* Insert the front of the gecko */
dakleive 0:008c379fb5e6 166 for (uint8_t i = _last + 1;i<_length;i++)
dakleive 0:008c379fb5e6 167 {
dakleive 0:008c379fb5e6 168 _position[i+1] = temp[i];
dakleive 0:008c379fb5e6 169 }
dakleive 0:008c379fb5e6 170
dakleive 0:008c379fb5e6 171 /* Draw last part of the gecko */
dakleive 0:008c379fb5e6 172 this->drawPart(display, this->getX(_last+1)*STEPSIZE + BOARDERWIDTH/2, (this->getY(_last+1)+TOPEDGE)*STEPSIZE + BOARDERWIDTH/2);
dakleive 0:008c379fb5e6 173
dakleive 0:008c379fb5e6 174
dakleive 0:008c379fb5e6 175 /* Update length and position of last */
dakleive 0:008c379fb5e6 176 _length += 1;
dakleive 0:008c379fb5e6 177 _last += 1;
dakleive 0:008c379fb5e6 178 }
dakleive 0:008c379fb5e6 179
dakleive 0:008c379fb5e6 180 bool Gecko::headOccupiesTile(uint8_t x_ref, uint8_t y_ref) const{
dakleive 0:008c379fb5e6 181 return ((x_ref == _head.getX()) && (y_ref == _head.getY()));
dakleive 0:008c379fb5e6 182 }
dakleive 0:008c379fb5e6 183
dakleive 0:008c379fb5e6 184 bool Gecko::occupiesTile(uint8_t x_ref, uint8_t y_ref) const{
dakleive 0:008c379fb5e6 185 if ( (x_ref == _head.getX()) && (y_ref == _head.getY()) ){
dakleive 0:008c379fb5e6 186 return true;
dakleive 0:008c379fb5e6 187 }
dakleive 0:008c379fb5e6 188
dakleive 0:008c379fb5e6 189 for (uint8_t i=0;i<_length;i++)
dakleive 0:008c379fb5e6 190 {
dakleive 0:008c379fb5e6 191 if ((x_ref == this->getX(i)) && (y_ref == this->getY(i)) )
dakleive 0:008c379fb5e6 192 {
dakleive 0:008c379fb5e6 193 return true;
dakleive 0:008c379fb5e6 194 }
dakleive 0:008c379fb5e6 195 }
dakleive 0:008c379fb5e6 196 return false;
dakleive 0:008c379fb5e6 197 }
dakleive 0:008c379fb5e6 198
dakleive 0:008c379fb5e6 199 void Gecko::drawPart(silabs::LS013B7DH03 &display, uint8_t x, uint8_t y) const
dakleive 0:008c379fb5e6 200 {
dakleive 0:008c379fb5e6 201 /**
dakleive 0:008c379fb5e6 202 * x and y denotes the coordinates of the top left corner
dakleive 0:008c379fb5e6 203 * Assumes that x and y are given such that the entire part is on the screen
dakleive 0:008c379fb5e6 204 **/
dakleive 0:008c379fb5e6 205 for (int i=0;i<NPARTPIXEL;i++){
dakleive 0:008c379fb5e6 206 display.pixel(x + static_cast<uint8_t>(gecko_px_map[i] & 0xF), y + static_cast<uint8_t>( (gecko_px_map[i] >> 4) & 0xF), Black);
dakleive 0:008c379fb5e6 207 }
dakleive 0:008c379fb5e6 208 }
dakleive 0:008c379fb5e6 209
dakleive 0:008c379fb5e6 210 void Gecko::removePart(silabs::LS013B7DH03 &display, uint8_t x, uint8_t y) const
dakleive 0:008c379fb5e6 211 {
dakleive 0:008c379fb5e6 212 /*
dakleive 0:008c379fb5e6 213 * x and y denotes the coordinates of the top left corner
dakleive 0:008c379fb5e6 214 * Assumes that x and y are given such that the part is on the screen
dakleive 0:008c379fb5e6 215 */
dakleive 0:008c379fb5e6 216 for (int i=0;i<NPARTPIXEL;i++){
dakleive 0:008c379fb5e6 217 display.pixel(x + static_cast<uint8_t>(gecko_px_map[i] & 0xF), y + static_cast<uint8_t>( (gecko_px_map[i] >> 4) & 0xF), White);
dakleive 0:008c379fb5e6 218 }
dakleive 0:008c379fb5e6 219 }
dakleive 0:008c379fb5e6 220
dakleive 0:008c379fb5e6 221 uint8_t Gecko::getX(uint8_t indx) const{
dakleive 0:008c379fb5e6 222 return _position[indx] - BOARD_WIDTH*(_position[indx]/BOARD_WIDTH);
dakleive 0:008c379fb5e6 223 }
dakleive 0:008c379fb5e6 224
dakleive 0:008c379fb5e6 225 uint8_t Gecko::getY(uint8_t indx) const{
dakleive 0:008c379fb5e6 226 return _position[indx]/BOARD_WIDTH;
dakleive 0:008c379fb5e6 227 }
dakleive 0:008c379fb5e6 228
dakleive 0:008c379fb5e6 229