Snake
Dependencies: microbit
Fork of microbit_snake by
A Snake Game with animation, score and continuous play
Steps:
- Switch On.
- Snake animation plays.
- Game starts.
- Press buttons to move the snake left, right, up and down.
- Food appears as a dot on the display.
- Try eating the food by manoeuvring Snake to run over it.
- Snake grows as it eats food.
- As it grows it becomes hard to avoid snake biting itself.
- Game Over.
- Snake is flashed and then score is scrolled.
- Game restarts after replaying animation.
Controls:
- Left Button (A)
- If snake moving UP/DOWN moves snake to LEFT.
- If snake moving LEFT moves snake to DOWN.
- If snake moving RIGHT moves snake to UP.
- Right Button (B)
- If snake moving UP/DOWN moves snake to RIGHT.
- If snake moving LEFT moves snake to UP.
- If snake moving RIGHT moves snake to DOWN.
How it looks:
https://www.youtube.com/watch?v=unEs3NOvIKA
Binary to play with
/media/uploads/mazimkhan/microbit_snake_nrf51_microbit.hex
Diff: main.cpp
- Revision:
- 3:a0200bceae4b
- Parent:
- 2:38060465e019
- Child:
- 4:9fd9402eca3d
--- a/main.cpp Sun Apr 10 19:20:49 2016 +0000 +++ b/main.cpp Sun Apr 10 23:31:53 2016 +0000 @@ -22,8 +22,8 @@ #include "MicroBit.h" #include "DigitalOut.h" -#define SNAKE_HEAD_PIXEL_BRIGHTNESS 25 -#define SNAKE_REST_PIXEL_BRIGHTNESS 15 +#define SNAKE_HEAD_PIXEL_BRIGHTNESS 150 +#define SNAKE_BONE_PIXEL_BRIGHTNESS 15 #define SNAKE_FOOD_PIXEL_BRIGHTNESS 255 template <class T> class Node{ @@ -83,6 +83,9 @@ if (tail) { tail = tail->getPrev(); node->detach(); + if (tail == NULL){ + head = NULL; + } } return node; } @@ -307,7 +310,7 @@ class Game { public: - Game(MicroBit & ubit): uBit(ubit), foodx(-1), foody(-1), image(5,5), + Game(MicroBit & ubit): uBit(ubit), foodx(-1), foody(-1), image(5,5), score(0), buttonPressed(false) { uBit.display.setDisplayMode(DISPLAY_MODE_GREYSCALE); uBit.display.print(image); @@ -328,11 +331,10 @@ } bool move(){ - // Display food - if (foodx != -1 && foody != -1){ - image.setPixelValue(foodx, foody, 255); - uBit.display.print(image); - } + // Dim old head + Dimension x = snake.getHeadX(); + Dimension y = snake.getHeadY(); + image.setPixelValue(x, y, SNAKE_BONE_PIXEL_BRIGHTNESS); snake.grow(); @@ -350,6 +352,7 @@ // food gone foodx = -1; foody = -1; + score++; // Since we have grown to the head. no need to delete tail. } else { @@ -363,7 +366,7 @@ } // Turn On head. - image.setPixelValue(nextX, nextY, 15); + image.setPixelValue(nextX, nextY, SNAKE_HEAD_PIXEL_BRIGHTNESS); uBit.display.print(image); buttonPressed = false; return true; @@ -406,6 +409,8 @@ if (isGoodFood(x, y)){ foodx = x; foody = y; + image.setPixelValue(foodx, foody, 255); + uBit.display.print(image); break; } } @@ -413,6 +418,99 @@ uBit.sleep(500); } } + + void animateSnake(){ +#define ANIMATION_SPEED 50 + // UP 2 + foodx = 2;foody = 1; + move(); + uBit.sleep(ANIMATION_SPEED); + + foodx = 2;foody = 0; + move(); + uBit.sleep(ANIMATION_SPEED); + + // LEFT + foodx = 1;foody = 0; + left(); + move(); + uBit.sleep(ANIMATION_SPEED); + + // DOWN + foodx = 1;foody = 1; + left(); + move(); + uBit.sleep(ANIMATION_SPEED); + + foodx = 1;foody = 2; + move(); + uBit.sleep(ANIMATION_SPEED); + move(); + uBit.sleep(ANIMATION_SPEED); + move(); + uBit.sleep(ANIMATION_SPEED); + + for (int i = 0; i < 4; i++){ + // LEFT + left(); + move(); + uBit.sleep(ANIMATION_SPEED); + + // UP + right(); + move(); + uBit.sleep(ANIMATION_SPEED); + + move(); + uBit.sleep(ANIMATION_SPEED); + move(); + uBit.sleep(ANIMATION_SPEED); + move(); + uBit.sleep(ANIMATION_SPEED); + + // LEFT + left(); + move(); + uBit.sleep(ANIMATION_SPEED); + + // DOWN + left(); + move(); + uBit.sleep(ANIMATION_SPEED); + + move(); + uBit.sleep(ANIMATION_SPEED); + move(); + uBit.sleep(ANIMATION_SPEED); + move(); + uBit.sleep(ANIMATION_SPEED); + } + + // Back to the centre + left(); + move(); + uBit.sleep(ANIMATION_SPEED); + + left(); + move(); + uBit.sleep(ANIMATION_SPEED); + + move(); + uBit.sleep(ANIMATION_SPEED); + move(); + uBit.sleep(ANIMATION_SPEED); + + // eat the tail + while(snake.getHead()){ + image.setPixelValue(snake.getTailX(), snake.getTailY(), 0); + uBit.display.print(image); + snake.reduce(); + uBit.sleep(ANIMATION_SPEED); + } + + reset(); + } + void showGameOver(){ // switch off food if (foodx != -1 && foody != -1){ @@ -424,7 +522,7 @@ // are not affected by display.setBrightness(). Possible Bug!!! Node<SnakeBone> * bone = snake.getHead(); while (bone){ - image.setPixelValue(bone->d.getX(), bone->d.getY(), 255); + image.setPixelValue(bone->d.getX(), bone->d.getY(), SNAKE_FOOD_PIXEL_BRIGHTNESS); bone = bone->getNext(); } // Flash snake @@ -434,9 +532,13 @@ if (toggle) uBit.display.setBrightness(255); else - uBit.display.setBrightness(15); + uBit.display.setBrightness(SNAKE_BONE_PIXEL_BRIGHTNESS); uBit.sleep(500); } + uBit.display.print(MicroBitImage(5,5)); + uBit.display.setBrightness(255); + uBit.display.scroll("SCORE-"); // don't mind spaces in a scrolling display. + uBit.display.scroll(score, 300); } void reset(){ @@ -445,8 +547,10 @@ foodx = -1; foody = -1; + score = 0; image = MicroBitImage(5, 5); uBit.display.setDisplayMode(DISPLAY_MODE_GREYSCALE); + image.setPixelValue(snake.getHeadX(), snake.getHeadY(), SNAKE_HEAD_PIXEL_BRIGHTNESS); uBit.display.print(image); } @@ -457,6 +561,7 @@ int foody; Snake snake; MicroBitImage image; + int score; // Sync button press and movement. Don't let quick button presses // change snake direction twice/thrice/... before moving. As a @@ -477,6 +582,7 @@ game.right(); } + int main() { // Initialise the micro:bit runtime. @@ -486,14 +592,9 @@ uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, onButtonB); // Continous play - while (true) - { + while (true){ + game.animateSnake(); game.play(); - - uBit.display.print(MicroBitImage(5,5)); - uBit.display.setBrightness(255); - uBit.display.scroll("URBITTEN"); // don't mind spaces in a scrolling display. - game.reset(); } } \ No newline at end of file