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 gecko.cpp Source File

gecko.cpp

Go to the documentation of this file.
00001 /***************************************************************************//**
00002  * @file gecko.cpp
00003  * @brief class for creating a gecko-like object and keeps track of its momvement
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 "gecko.h"
00033 
00034 /* Number of pixels used in the Gecko head */
00035 #define NPIXHEAD 16
00036 /* Number of pixels used in one Gecko part */
00037 #define NPARTPIXEL 21
00038 
00039 /*
00040  * Pixel map for a gecko part and head
00041  * y-crd is encoded in the 4 most significant bits, x-crd is encoded in the 4 least significant bits
00042  * The upper left corner of the part is assigned coordinates (x,y)=(0,0)
00043  */
00044 
00045 const uint8_t head_px_map[NPIXHEAD] = {0x03, 0x12, 0x14, 0x21, 0x25, 0x30, 0x32, 0x34, 0x36, 0x40, 0x46, 0x51, 0x55, 0x62, 0x63, 0x64};
00046 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};
00047 
00048 
00049 Gecko::Gecko():_length(10){
00050     _head.init(10, 4, UP, head_px_map, NPIXHEAD);
00051     _last = _length-1;
00052     for (int i=0;i<_length;i++){
00053         _position[i] = (_head.getY() + i +1)*BOARD_WIDTH + _head.getX();
00054     }
00055 
00056 }
00057 
00058 void Gecko::move(silabs::LS013B7DH03 &display, Direction dir){
00059     
00060     /* Remove the last part of the gecko */
00061     this->removePart(display, this->getX(_last)*STEPSIZE + BOARDERWIDTH/2, (this->getY(_last)+TOPEDGE)*STEPSIZE + BOARDERWIDTH/2);
00062 
00063     /* Remove head */
00064     _head.remove(display);
00065 
00066     /* Update the part next to the head */
00067     _head.setDir(dir);
00068     _position[_last] = _head.getY()*BOARD_WIDTH + _head.getX();
00069 
00070     switch(dir){
00071         case UP:
00072             if (_head.getY() == 0)
00073             {
00074                 _head.setY(BOARD_HEIGHT-1);
00075             }
00076             else
00077             {
00078                 _head.setY(_head.getY() - 1);
00079             }
00080             break;
00081         case DOWN:
00082             if ( _head.getY() == (BOARD_HEIGHT-1))
00083             {
00084                 _head.setY(0);
00085             }
00086             else
00087             {
00088                 _head.setY(_head.getY() + 1);
00089             }
00090             break; 
00091         case RIGHT:
00092             if (_head.getX() == (BOARD_WIDTH-1))
00093             {
00094                 _head.setX(0);
00095             }
00096             else
00097             {
00098                 _head.setX(_head.getX() + 1);
00099             }
00100             break;
00101         case LEFT:
00102             if (_head.getX() == 0)
00103             {
00104                 _head.setX(BOARD_WIDTH-1);
00105             }
00106             else
00107             {
00108                   _head.setX(_head.getX() - 1);
00109             }
00110             break;
00111     }
00112     
00113     /* Draw the parts of the gecko which have been moved */
00114     _head.draw(display);
00115     this->drawPart(display, this->getX(_last)*STEPSIZE + BOARDERWIDTH/2, (this->getY(_last)+TOPEDGE)*STEPSIZE + BOARDERWIDTH/2);
00116 
00117     /* Update the index of the last part */
00118     if (_last == 0){
00119         _last += _length;
00120     }
00121     _last -= 1;
00122 }
00123 
00124 void Gecko::draw(silabs::LS013B7DH03 &display) const{
00125     _head.draw(display);
00126 
00127     /* Loop over indices of all parts of the gecko */
00128     for (uint8_t i=0;i<_length;i++){
00129         this->drawPart(display, this->getX(i)*STEPSIZE + BOARDERWIDTH/2, (this->getY(i)+TOPEDGE)*STEPSIZE + BOARDERWIDTH/2);
00130     }
00131 }   
00132 
00133 bool Gecko::selfCollision() const{
00134     /* Check if some pixels have the same coordinate */
00135     for (int i=0;i<_length;i++)
00136     {
00137         if ((_head.getX()==this->getX(i)) && (_head.getY()==this->getY(i))){
00138             return true;
00139         }
00140     }
00141     return false;
00142 }
00143 
00144 void Gecko::increaseLength(silabs::LS013B7DH03 &display, Direction dir)
00145 {
00146     if ((_length + 1)> MAXLENGTH) return;
00147 
00148     /* Store the tail of the gecko */
00149     uint8_t tempPos = _position[_last] ;
00150 
00151     /* Move the gecko */
00152     this->move(display, dir);
00153 
00154     uint8_t temp[MAXLENGTH];
00155 
00156     /* Copy the front of the gecko */
00157     for (uint8_t i = _last + 1;i<_length;i++)
00158     {
00159         temp[i] = _position[i];
00160     }
00161 
00162     /* Insert the "old" tail */
00163     _position[_last + 1] = tempPos;
00164 
00165     /* Insert the front of the gecko */
00166     for (uint8_t i = _last + 1;i<_length;i++)
00167     {
00168         _position[i+1] = temp[i];
00169     }
00170 
00171     /* Draw last part of the gecko */
00172     this->drawPart(display, this->getX(_last+1)*STEPSIZE + BOARDERWIDTH/2, (this->getY(_last+1)+TOPEDGE)*STEPSIZE + BOARDERWIDTH/2);
00173 
00174 
00175     /* Update length and position of last */
00176     _length += 1;
00177     _last += 1;
00178 }
00179 
00180 bool Gecko::headOccupiesTile(uint8_t x_ref, uint8_t y_ref) const{
00181     return ((x_ref == _head.getX()) && (y_ref == _head.getY()));
00182 }
00183 
00184 bool Gecko::occupiesTile(uint8_t x_ref, uint8_t y_ref) const{
00185     if ( (x_ref == _head.getX()) && (y_ref == _head.getY()) ){
00186         return true;
00187     }
00188 
00189     for (uint8_t i=0;i<_length;i++)
00190     {
00191             if ((x_ref == this->getX(i)) && (y_ref == this->getY(i)) )
00192             {
00193                     return true;
00194             }
00195     }
00196     return false;
00197 }
00198 
00199 void Gecko::drawPart(silabs::LS013B7DH03 &display, uint8_t x, uint8_t y) const
00200 {
00201      /**
00202       * x and y denotes the coordinates of the top left corner
00203       * Assumes that x and y are given such that the entire part is on the screen
00204       **/
00205     for (int i=0;i<NPARTPIXEL;i++){
00206         display.pixel(x +  static_cast<uint8_t>(gecko_px_map[i] & 0xF), y + static_cast<uint8_t>( (gecko_px_map[i] >> 4) & 0xF), Black);
00207     }
00208 }
00209 
00210 void Gecko::removePart(silabs::LS013B7DH03 &display, uint8_t x, uint8_t y) const
00211 {
00212     /*
00213      * x and y denotes the coordinates of the top left corner
00214      * Assumes that x and y are given such that the  part is on the screen
00215      */
00216     for (int i=0;i<NPARTPIXEL;i++){
00217         display.pixel(x + static_cast<uint8_t>(gecko_px_map[i] & 0xF), y + static_cast<uint8_t>( (gecko_px_map[i] >> 4) & 0xF), White);
00218     }
00219 }
00220 
00221 uint8_t Gecko::getX(uint8_t indx) const{
00222     return _position[indx] - BOARD_WIDTH*(_position[indx]/BOARD_WIDTH);
00223 }
00224 
00225 uint8_t Gecko::getY(uint8_t indx) const{
00226     return _position[indx]/BOARD_WIDTH;
00227 }
00228 
00229