Snake game on nokia N5110 LCD
Dependencies: mbed
Snake game on nokia N5110 LCD and Keyes Syos Joystick. You control snake using joystick. Start/pause game ba using button on joystick or by pressing p on your keyboard (serial communication). More info on my blog: http://sdizdarevic.com/post/94147065625/frdm-k64f-project
Diff: Snakelib.h
- Revision:
- 0:5bdb67970267
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Snakelib.h Fri Aug 08 06:44:50 2014 +0000 @@ -0,0 +1,341 @@ +#ifndef E_SNAKE_H +#define E_SNAKE_H +#include <cstdlib> +#include "mbed.h" +#include "N5110.h" +#include "Helper.h" +class Snakelib + { + static const bool SnakeTypes [2][6][3][3]; + static const bool SnakeFood [5][3][3]; + static const int Pos [2][3][3]; + short Snake [438][2]; + static const double Speeds [10]; + static const unsigned char Points[10]; + AnalogIn VX, VY; + InterruptIn SW; + int HScore, Score; + int SnakeLen, Speed; + int SnakeType, FoodType; + int eX, eY, pX, pY, Dir; + bool Moved, Pause, Draw, Started; + N5110 DISP; + DigitalOut ENBL; + Ticker TJoy, TMove; + Timer Dbnc; + Ticker T; + void SetBlock (int Block = 0, int X = 1, int Y = 1) + { + for (int a = 0; a < 3; ++a) + for (int b = 0; b < 3; ++b) + if (Block == 2 && SnakeFood [FoodType][a][b]) + DISP.setPixel (X + Pos[0][a][b], Y + Pos[1][a][b]); + else if (Block < 2 && SnakeTypes [Block][SnakeType][a][b]) + DISP.setPixel (X + Pos[0][a][b], Y + Pos[1][a][b]); + } + int Rand (int Min = 1, int Max = 83) + { + static bool First = true; + if (First) srand (time (NULL)), First = false; + while (7) + { + int S = rand () % (Max - Min + 1) + Min; + if (!((S - 1) % 3)) return S; + } + } + void GameOver () + { + + //FlashB(); + wait (2); + DISP.clear(); + DISP.setXYAddress (0, 0); + DISP.printString ("END!", 29, 0); + DISP.printString ("Score: ", 10, 2); + char Buff[20]; + ToString (Buff, Score); + DISP.printString (Buff, 50, 2); + DISP.printString ("Best: ", 10, 4); + ToString (Buff, HScore); + DISP.printString (Buff, 50, 4); + eX = eY = 0; // + Started = false; + wait (3); + Restart(); + } + void Prekuco() + { + DISP.clear(); + DISP.setXYAddress (0, 0); + DISP.printString ("Well done!!!!!", 0, 0); + DISP.printString ("Congrats", 0, 2); + eX = eY = 0; + Started = false; + wait (3); + Restart(); + } + void HitFood () + { + if (Snake [0][0] == pX && Snake [0][1] == pY) + { + Score += Points[Speed - 1]; + AddSnakeBody(); + RandFood(pX, pY); + } + } + void HitWall() + { + if (Snake[0][0] + 1 > 83 || Snake[0][0] - 1 < 0 || Snake[0][1] + 1 > 47 || Snake[0][1] - 1 < 0) + { + if (Score > HScore) + HScore = Score; + Started = false;; + GameOver(); + return; + } + } + void HitSelf() + { + for (int a = 1; a <= SnakeLen; ++a) + if (Snake[0][0] == Snake[a][0] && Snake[0][1] == Snake[a][1]) + { + if (Score > HScore) + HScore = Score; + GameOver(); + return; + } + } + void Start() + { + Snake[0][0] = Rand(20, 70); + Snake[0][1] = Rand(10, 35); + RandFood(pX, pY); + AddSnakeBody(); + AddSnakeBody(); + Refresh(); + } + void FlashB () + { + for (int z = 0; z < 5; ++z) + { + DISP.clear(); + DISP.setXYAddress (0, 0); + DISP.refresh(); + wait (0.5); + DrawWall(); + for (int a = 0; a <= SnakeLen; ++a) + SetBlock(a == 0 ? 0 : 1, Snake[a][0], Snake[a][1]); + SetBlock(2, pX, pY); + DISP.refresh(); + } + } + void MoveSnake () + { + if (Pause || !Started) return; + for (int a = SnakeLen; a >= 1; --a) + { + Snake[a][0] = Snake[a - 1][0]; + Snake[a][1] = Snake[a - 1][1]; + } + Snake[0][0] += eX; + Snake[0][1] += eY; + Moved = true; + Refresh(); + } + void AddSnakeBody() + { + SnakeLen++; + int X = 0, Y = 0; + if (Dir == 0) X = 3, Y = 0; + if (Dir == 1) X = 0, Y = 3; + if (Dir == 2) X = -3, Y = 0; + if (Dir == 3) X = 0, Y = -3; + Snake [SnakeLen][0] = Snake[SnakeLen - 1][0] + X; + Snake [SnakeLen][1] = Snake[SnakeLen - 1][1] + Y; + } + void RandFood(int &X, int &Y) + { + while (7) + { + int A = Rand(1, 83); + int B = Rand(1, 47); + bool S = false; + for (int I = 0; I <= SnakeLen; ++I) + if (Snake[I][0] == A && Snake[I][1] == B) + S = true; + if (!S) {X = A; Y = B; return;} + } + } + void DrawWall () + { + for (int a = 0; a < 84; ++a) + for (int b = 0; b < 48; ++b) + if (!a || !b || a == 83 || b == 47) + DISP.setPixel (a, b); + } + void Refresh () + { + if (!Draw) return; + HitFood(); + HitWall(); + HitSelf(); + DISP.clear(); + DISP.setXYAddress (0, 0); + DrawWall(); + for (int a = 0; a <= SnakeLen; ++a) + SetBlock(a == 0 ? 0 : 1, Snake[a][0], Snake[a][1]); + SetBlock(2, pX, pY); + DISP.refresh(); + if (SnakeLen > 437) Prekuco(); + } + void Moving () + { + if (!Moved) return; + double vx = VX, vy = VY; + if (vx < 1./3.) + { + if (Dir == 2) return; + eX = -3; eY = 0; + Dir = 0; + Moved = false; + } + else if (vx > 2./3.) + { + if (Dir == 0) return; + eX = 3; eY = 0; + Dir = 2; + Moved = false; + } + if (vy < 1./3.) + { + if (Dir == 1) return; + eX = 0; eY = -3; + Dir = 3; + Moved = false; + } + else if (vy > 2./3.) + { + if (Dir == 3) return; + eX = 0; eY = 3; + Dir = 1; + Moved = false; + } + } + void Pressed () + { + if (Dbnc.read() > .2) + { + if (!Started) + { + Started = true; + TMove.attach (this, &Snakelib::MoveSnake, Speeds[Speed - 1]); + } + else + { + Pause = !Pause; + Draw = !Pause; + } + } + Dbnc.reset(); + } + public: + Snakelib (PinName P1, PinName P2, PinName P3, PinName P4, PinName P5, + PinName P6, PinName P7, PinName BX, PinName BY, PinName BS) + : VX (BX), VY (BY), SW (BS), HScore (0), Score (0), SnakeLen (0), Speed (6), SnakeType (0), + FoodType (0), eX (3), eY (0), pX(0), pY (0), Dir (2), Moved(false), Pause (false), Draw (true), Started (false), + DISP (P1, P2, P3, P4, P5, P6, P7), ENBL (LED_RED) + { + + } + void START() + { + ENBL = 1; + Dbnc.start(); + SW.mode (PullUp); + DISP.init(); + DISP.setXYAddress (0, 0); + DISP.clear(); + TJoy.attach (this, &Snakelib::Moving, 0.01); + DISP.printString ("- SNAKE -", 0, 0); + DISP.printString ("K64F", 0, 3); + DISP.printString ("Freescale", 0, 4); + wait (2); + SW.rise (this, &Snakelib::Pressed); + Start(); + + + } + int SnakeSpeed () const {return Speed;} + void SetSnakeSpeed (unsigned char S) + { + if (S == Speed) return; + Speed = S; + Speed = Speed < 1 ? 1 : Speed > 10 ? 10 : Speed; + TMove.detach(); + wait_ms (2); + TMove.attach (this, &Snakelib::MoveSnake, Speeds[Speed - 1]); + } + int GetSnakeType () const {return SnakeType + 1;} + void SetSnakeType (unsigned char S) + { + if (S == SnakeType) return; + int ST = S < 1 ? 1 : S > 6 ? 6 : S; + SnakeType = ST - 1; + Refresh(); + } + int GetFoodType () const {return FoodType + 1;} + void SetFoodType (unsigned char S) + { + if (S == FoodType) return; + int FT = S < 1 ? 1 : S > 5 ? 5 : S; + FoodType = FT - 1; + Refresh(); + } + void PauseGame () {Pause = true; Draw = false;} + void ResumeGame () {Pause = false; Draw = true;} + bool Paused () const {return Pause;} + void Restart() + { + TMove.detach(); + SnakeLen = eY = Score = 0; + eX = 3; + Dir = 2; + Started = false; + Start(); + } + }; +const bool Snakelib::SnakeTypes [2][6][3][3] = + { + { + {{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + {{1, 1, 1}, {1, 0, 1}, {1, 1, 1}}, + {{0, 1, 0}, {1, 1, 1}, {0, 1, 0}}, + {{0, 1, 0}, {1, 0, 1}, {0, 1, 0}}, + {{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + {{1, 1, 1}, {1, 0, 1}, {1, 1, 1}} + }, + { + {{1, 1, 1}, {1, 0, 1}, {1, 1, 1}}, + {{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + {{0, 1, 0}, {1, 0, 1}, {0, 1, 0}}, + {{0, 1, 0}, {1, 1, 1}, {0, 1, 0}}, + {{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + {{1, 1, 1}, {1, 0, 1}, {1, 1, 1}} + } + }; +const bool Snakelib::SnakeFood [5][3][3] = + { + {{1, 0, 1}, {0, 1, 0}, {1, 0, 1}}, + {{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + {{1, 1, 1}, {1, 0, 1}, {1, 1, 1}}, + {{0, 1, 0}, {1, 1, 1}, {0, 1, 0}}, + {{0, 1, 0}, {1, 0, 1}, {0, 1, 0}} + }; +const int Snakelib::Pos [2][3][3] = + { + {{-1, 0, 1}, {-1, 0, 1}, {-1, 0, 1}}, + {{1, 1, 1}, {0, 0, 0}, {-1, -1, -1}} + }; +const double Snakelib::Speeds [10] = {1., .8, .7, .5, .32, .25, .15, .1, .075, .050}; +const unsigned char Snakelib::Points[10] = {1, 1, 1, 2, 3, 4, 5, 6, 8, 10}; +#endif //E_SNAKE_H