Snake game on nokia N5110 LCD

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Snakelib.h Source File

Snakelib.h

00001 #ifndef E_SNAKE_H
00002 #define E_SNAKE_H
00003 #include <cstdlib>
00004 #include "mbed.h"
00005 #include "N5110.h"
00006 #include "Helper.h" 
00007 class Snakelib
00008     {
00009         static const bool SnakeTypes [2][6][3][3];
00010         static const bool SnakeFood [5][3][3];
00011         static const int Pos [2][3][3];
00012         short Snake [438][2];
00013         static const double Speeds [10];
00014         static const unsigned char Points[10];
00015         AnalogIn VX, VY;
00016         InterruptIn SW;
00017         int HScore, Score;
00018         int SnakeLen, Speed;
00019         int SnakeType, FoodType;
00020         int eX, eY, pX, pY, Dir;
00021         bool Moved, Pause, Draw, Started;
00022         N5110 DISP;
00023         DigitalOut ENBL;
00024         Ticker TJoy, TMove;
00025         Timer Dbnc;
00026         Ticker T;
00027         void SetBlock (int Block = 0, int X = 1, int Y = 1)
00028             {
00029                 for (int a = 0; a < 3; ++a)
00030                     for (int b = 0; b < 3; ++b)
00031                         if (Block == 2 && SnakeFood [FoodType][a][b])
00032                             DISP.setPixel (X + Pos[0][a][b], Y + Pos[1][a][b]);
00033                         else if (Block < 2 && SnakeTypes [Block][SnakeType][a][b])
00034                             DISP.setPixel (X + Pos[0][a][b], Y + Pos[1][a][b]);                
00035             }
00036         int Rand (int Min = 1, int Max = 83)
00037             {
00038                 static bool First = true;
00039                 if (First) srand (time (NULL)), First = false;
00040                 while (7)
00041                     {
00042                         int S = rand () % (Max - Min + 1) + Min;
00043                         if (!((S - 1)  % 3)) return S;
00044                     }
00045             }
00046         void GameOver ()
00047             {
00048  
00049                 //FlashB();
00050                 wait (2);
00051                 DISP.clear();
00052                 DISP.setXYAddress (0, 0);
00053                 DISP.printString ("END!", 29, 0);
00054                 DISP.printString ("Score: ", 10, 2);
00055                 char Buff[20];
00056                 ToString (Buff, Score);
00057                 DISP.printString (Buff, 50, 2);
00058                 DISP.printString ("Best: ", 10, 4);
00059                 ToString (Buff, HScore);
00060                 DISP.printString (Buff, 50, 4);
00061                 eX = eY = 0; //
00062                 Started = false;
00063                 wait (3);
00064                 Restart();
00065             }
00066         void Prekuco()
00067             {
00068                 DISP.clear();
00069                 DISP.setXYAddress (0, 0);
00070                 DISP.printString ("Well done!!!!!", 0, 0);
00071                 DISP.printString ("Congrats", 0, 2);
00072                 eX = eY = 0;
00073                 Started = false;
00074                 wait (3);
00075                 Restart();
00076             }
00077         void HitFood ()
00078             {
00079                 if (Snake [0][0] == pX && Snake [0][1] == pY)
00080                     {
00081                         Score += Points[Speed - 1];
00082                         AddSnakeBody();
00083                         RandFood(pX, pY);
00084                     }
00085             }
00086         void HitWall()
00087             {
00088                 if (Snake[0][0] + 1 > 83 || Snake[0][0] - 1 < 0 || Snake[0][1] + 1 > 47 || Snake[0][1] - 1 < 0)
00089                     {
00090                         if (Score > HScore)
00091                             HScore = Score;
00092                         Started = false;;
00093                         GameOver();
00094                         return;
00095                     }
00096             }
00097         void HitSelf()
00098             {
00099                 for (int a  = 1; a <= SnakeLen; ++a)
00100                     if (Snake[0][0] == Snake[a][0] && Snake[0][1] == Snake[a][1])
00101                         {
00102                             if (Score > HScore)
00103                                 HScore = Score;
00104                             GameOver();
00105                             return;
00106                         }
00107             }
00108         void Start()
00109             {
00110                 Snake[0][0] = Rand(20, 70);
00111                 Snake[0][1] = Rand(10, 35);
00112                 RandFood(pX, pY);
00113                 AddSnakeBody();
00114                 AddSnakeBody();
00115                 Refresh();
00116             }
00117         void FlashB ()
00118             {
00119                 for (int z = 0; z < 5; ++z)
00120                     {
00121                         DISP.clear();
00122                         DISP.setXYAddress (0, 0);
00123                         DISP.refresh();
00124                         wait (0.5);
00125                         DrawWall();
00126                         for (int a = 0; a <= SnakeLen; ++a)
00127                             SetBlock(a == 0 ? 0 : 1, Snake[a][0], Snake[a][1]);
00128                         SetBlock(2, pX, pY);
00129                         DISP.refresh();
00130                     }
00131             }
00132         void MoveSnake ()
00133             {
00134                 if (Pause || !Started) return;
00135                 for (int a = SnakeLen; a >= 1; --a)
00136                     {
00137                         Snake[a][0] = Snake[a - 1][0];
00138                         Snake[a][1] = Snake[a - 1][1];
00139                     }
00140                 Snake[0][0] += eX;
00141                 Snake[0][1] += eY;
00142                 Moved = true;  
00143                 Refresh();
00144             }   
00145         void AddSnakeBody()
00146             {
00147                 SnakeLen++;
00148                 int X = 0, Y = 0;
00149                 if (Dir == 0) X = 3, Y = 0;
00150                 if (Dir == 1) X = 0, Y = 3;
00151                 if (Dir == 2) X = -3, Y = 0;
00152                 if (Dir == 3) X = 0, Y = -3;
00153                 Snake [SnakeLen][0] = Snake[SnakeLen - 1][0] + X;
00154                 Snake [SnakeLen][1] = Snake[SnakeLen - 1][1] + Y;
00155             }
00156         void RandFood(int &X, int &Y)
00157             {
00158                 while (7)
00159                     {
00160                         int A = Rand(1, 83);
00161                         int B = Rand(1, 47);
00162                         bool S = false;
00163                         for (int I = 0; I <= SnakeLen; ++I)
00164                             if (Snake[I][0] == A && Snake[I][1] == B)
00165                                 S = true;
00166                         if (!S) {X = A; Y = B; return;}
00167                     }
00168             }
00169         void DrawWall ()
00170             {
00171                 for (int a = 0; a < 84; ++a)
00172                     for (int b = 0; b < 48; ++b)
00173                         if (!a || !b || a == 83 || b == 47)
00174                             DISP.setPixel (a, b);
00175             }
00176         void Refresh ()
00177             {
00178                 if (!Draw) return;
00179                 HitFood();
00180                 HitWall();
00181                 HitSelf();
00182                 DISP.clear();
00183                 DISP.setXYAddress (0, 0);
00184                 DrawWall();
00185                 for (int a = 0; a <= SnakeLen; ++a)
00186                     SetBlock(a == 0 ?  0 : 1, Snake[a][0], Snake[a][1]);
00187                 SetBlock(2, pX, pY);
00188                 DISP.refresh();
00189                 if (SnakeLen > 437) Prekuco();            
00190             }
00191         void Moving () 
00192             {
00193                 if (!Moved) return;
00194                 double vx = VX, vy = VY;
00195                 if (vx < 1./3.) 
00196                     {
00197                         if (Dir == 2) return;
00198                         eX = -3; eY = 0;
00199                         Dir = 0;
00200                         Moved = false;
00201                     }
00202                 else if (vx > 2./3.)
00203                     {
00204                         if (Dir == 0) return;
00205                         eX = 3; eY = 0;
00206                         Dir = 2;
00207                         Moved = false;
00208                     }
00209                 if (vy < 1./3.) 
00210                     {
00211                         if (Dir == 1) return;
00212                         eX = 0; eY = -3;
00213                         Dir = 3;
00214                         Moved = false;
00215                     }
00216                 else if (vy > 2./3.)
00217                     {
00218                         if (Dir == 3) return;
00219                         eX = 0; eY = 3;
00220                         Dir = 1;
00221                         Moved = false;
00222                     }
00223             }
00224         void Pressed () 
00225             {
00226                 if (Dbnc.read()  > .2)
00227                     {
00228                         if (!Started) 
00229                             {
00230                                 Started = true;
00231                                 TMove.attach (this, &Snakelib::MoveSnake, Speeds[Speed - 1]);
00232                             }
00233                         else 
00234                             {
00235                                 Pause = !Pause;
00236                                 Draw = !Pause;
00237                             }
00238                     }
00239                 Dbnc.reset();
00240             }
00241     public:
00242         Snakelib (PinName P1, PinName P2, PinName P3, PinName P4, PinName P5, 
00243                     PinName P6, PinName P7, PinName BX, PinName BY, PinName BS) 
00244             :   VX (BX), VY (BY), SW (BS), HScore (0), Score (0), SnakeLen (0), Speed (6), SnakeType (0),
00245                 FoodType (0), eX (3), eY (0), pX(0), pY (0), Dir (2), Moved(false), Pause (false), Draw (true), Started (false),
00246                 DISP (P1, P2, P3, P4, P5, P6, P7), ENBL (LED_RED)
00247             {
00248  
00249             }
00250         void START()
00251             {
00252                 ENBL = 1;
00253                 Dbnc.start();
00254                 SW.mode (PullUp);
00255                 DISP.init();
00256                 DISP.setXYAddress (0, 0);
00257                 DISP.clear();
00258                 TJoy.attach (this, &Snakelib::Moving, 0.01);
00259                 DISP.printString ("- SNAKE   -", 0, 0);
00260                 DISP.printString ("K64F", 0, 3);
00261                 DISP.printString ("Freescale", 0, 4);
00262                 wait (2);
00263                 SW.rise (this, &Snakelib::Pressed);
00264                 Start();
00265                 
00266                 
00267             }
00268         int SnakeSpeed () const {return Speed;}
00269         void SetSnakeSpeed (unsigned char S)
00270             {
00271                 if (S == Speed) return;
00272                 Speed = S;
00273                 Speed = Speed < 1 ? 1 : Speed > 10 ? 10 : Speed;
00274                 TMove.detach();
00275                 wait_ms (2);
00276                 TMove.attach (this, &Snakelib::MoveSnake, Speeds[Speed - 1]);
00277             }
00278         int GetSnakeType () const {return SnakeType + 1;}
00279         void SetSnakeType (unsigned char S)
00280             {
00281                 if (S == SnakeType) return;
00282                 int ST = S < 1 ? 1 : S > 6 ? 6 : S;
00283                 SnakeType = ST - 1;
00284                 Refresh();
00285             }
00286         int GetFoodType () const {return FoodType + 1;}
00287         void SetFoodType (unsigned char S)
00288             {
00289                 if (S == FoodType) return;
00290                 int FT = S < 1 ? 1 : S > 5 ? 5 : S;
00291                 FoodType = FT - 1;
00292                 Refresh();
00293             }
00294         void PauseGame () {Pause = true; Draw = false;}
00295         void ResumeGame () {Pause = false; Draw = true;}
00296         bool Paused () const {return Pause;}
00297         void Restart()
00298             {
00299                 TMove.detach();
00300                 SnakeLen  = eY = Score = 0;
00301                 eX = 3;
00302                 Dir = 2;
00303                 Started = false;
00304                 Start();
00305             }
00306     };
00307 const bool Snakelib::SnakeTypes [2][6][3][3] = 
00308     {
00309         {
00310             {{1, 1, 1}, {1, 1, 1}, {1, 1, 1}},
00311             {{1, 1, 1}, {1, 0, 1}, {1, 1, 1}},
00312             {{0, 1, 0}, {1, 1, 1}, {0, 1, 0}},
00313             {{0, 1, 0}, {1, 0, 1}, {0, 1, 0}},
00314             {{1, 1, 1}, {1, 1, 1}, {1, 1, 1}},
00315             {{1, 1, 1}, {1, 0, 1}, {1, 1, 1}}
00316         },
00317         {
00318             {{1, 1, 1}, {1, 0, 1}, {1, 1, 1}},
00319             {{1, 1, 1}, {1, 1, 1}, {1, 1, 1}},
00320             {{0, 1, 0}, {1, 0, 1}, {0, 1, 0}},
00321             {{0, 1, 0}, {1, 1, 1}, {0, 1, 0}},
00322             {{1, 1, 1}, {1, 1, 1}, {1, 1, 1}},
00323             {{1, 1, 1}, {1, 0, 1}, {1, 1, 1}}
00324         }
00325     };
00326 const bool Snakelib::SnakeFood [5][3][3] =  
00327     {
00328         {{1, 0, 1}, {0, 1, 0}, {1, 0, 1}},
00329         {{1, 1, 1}, {1, 1, 1}, {1, 1, 1}},
00330         {{1, 1, 1}, {1, 0, 1}, {1, 1, 1}},
00331         {{0, 1, 0}, {1, 1, 1}, {0, 1, 0}},
00332         {{0, 1, 0}, {1, 0, 1}, {0, 1, 0}}    
00333     };
00334 const int Snakelib::Pos [2][3][3] = 
00335     {
00336         {{-1, 0, 1}, {-1, 0, 1}, {-1, 0, 1}},
00337         {{1, 1, 1}, {0, 0, 0}, {-1, -1, -1}}
00338     };
00339 const double Snakelib::Speeds [10] = {1., .8, .7, .5, .32, .25, .15, .1, .075, .050};
00340 const unsigned char Snakelib::Points[10] = {1, 1, 1, 2, 3, 4, 5, 6, 8, 10};
00341 #endif  //E_SNAKE_H