Snake Game using accelerometer with many fun features.

Dependencies:   C12832 MMA7660 mbed

Fork of app-board-Bubble-Level by jim hamblen

Revision:
2:dd83ac1aba6c
Parent:
1:876f52a697c1
Child:
3:2d625f49afb9
--- a/main.cpp	Sun Sep 22 17:44:42 2013 +0000
+++ b/main.cpp	Thu Feb 19 08:15:47 2015 +0000
@@ -1,27 +1,179 @@
-//Uses x & y acceleration to simulate a bubble level
-//on the application board LCD display
 #include "mbed.h"
-#include "MMA7660.h"
-#include "C12832_lcd.h"
+//#include "C12832_lcd.h"
+#include "C12832.h"
+#include "motion_detect.h"
+
+#define N 200
+#define LEFT 0
+#define RIGHT 1
+#define UP 2
+#define DOWN 3
+
+#define WIDTH 128
+#define HEIGHT 32
+
+#define WIDTH_MOD 32
+#define HEIGHT_MOD 8
+
+DigitalIn fire(p14);
+BusIn joy(p15,p12,p13,p16);
+static C12832 lcd(p5, p7, p6, p8, p11);
+//static C12832_LCD lcd;
+PwmOut spkr(p26);
+
+int level = 1;
+int score = 0;
+bool acc_joy = true;
+
+struct Food {
+    int x;
+    int y;
+    int yes;
+} food;
 
-C12832_LCD lcd; //On board LCD display
-MMA7660 MMA(p28, p27); //I2C Accelerometer
-DigitalOut connectionLed(LED1);//Accel OK LED
+struct Snake {
+    int x[N];
+    int y[N];
+    int node_num;
+    int direction;
+    int life;
+} snake;
+
+void generate_food() {
+    food.x = rand() % WIDTH_MOD * 4;
+    food.y = rand() % HEIGHT_MOD * 4;
+}
+
+bool check_joy() {
+    if(joy == 0) {
+        return false;
+    }
+    if(joy == 1) {
+        if(snake.direction != DOWN) {
+            snake.direction = UP;
+        }
+    }
+    if(joy == 2) {
+        if(snake.direction != UP) {
+            snake.direction = DOWN;
+        }
+    }
+    if(joy == 4) {
+        if(snake.direction != RIGHT) {
+            snake.direction = LEFT;
+        }
+    }
+    if(joy == 8) {
+        if(snake.direction != LEFT) {
+            snake.direction = RIGHT;
+        }
+    }
+    return true;
+}
 
-int main()
-{
-    int x=0,y=0;
-    lcd.cls(); //clear LCD screen
-    if (MMA.testConnection())
-        connectionLed = 1; //Accelerometer init OK
-    while(1) {
-        //read X,Y +/-Gs and scale for #display pixels
-        x = (x + MMA.x() * 32.0)/2.0;
-        y = (y -(MMA.y() * 16.0))/2.0;
-        lcd.fillcircle(x+63, y+15, 3, 1); //draw bubble
-        lcd.circle(63, 15, 8, 1);
-        wait(.1); //time delay
-        lcd.fillcircle(x+63, y+15, 3, 0); //erase bubble
+void game_play() {
+    level = 1;
+    score = 0;
+    acc_joy = true;
+    food.yes = 1;
+    snake.life = 1;
+    snake.direction = RIGHT;
+    snake.x[0] = 72;
+    snake.y[0] = 16;
+    snake.x[1] = 68;
+    snake.y[1] = 16;
+    snake.x[2] = 64;
+    snake.y[2] = 16;
+    snake.node_num = 3;
+    while(true) {
+        if(fire) {
+            acc_joy = !acc_joy;
+        }
+        if(acc_joy == false) {
+            check_joy();
+        }
+        if(acc_joy == true) {
+            motion_detect(snake.direction);
+        }
+        if(food.yes == 1) {
+            generate_food();
+            food.yes = 0;
+        }
+        lcd.fillrect(snake.x[snake.node_num - 1], snake.y[snake.node_num - 1], snake.x[snake.node_num - 1] + 3, snake.y[snake.node_num - 1] + 3, 0);
+        if(food.yes == 0) {
+            lcd.fillrect(food.x, food.y, food.x + 3, food.y + 3, 1);
+        }        
+        for(int i = snake.node_num - 1; i > 0; i--) {
+            snake.x[i] = snake.x[i - 1];
+            snake.y[i] = snake.y[i - 1];
+        }
+        switch(snake.direction) {
+            case UP:
+                snake.y[0] -= 4; break;
+            case DOWN:
+                snake.y[0] += 4; break;
+            case LEFT:
+                snake.x[0] -= 4; break;
+            case RIGHT:
+                snake.x[0] += 4; break;
+        }
+        for(int i = 3; i < snake.node_num; i++) {
+            if(snake.x[i] == snake.x[0] && snake.y[i] == snake.y[0]) {
+                snake.life = 0;
+                break;
+            }
+        }
+        
+        if(snake.x[0] < 0 || snake.x[0] > 128 || snake.y[0] < 0 || snake.y[0] > 32 || snake.life == 0) {
+            break;
+        }
+        
+        if(snake.x[0] == food.x && snake.y[0] == food.y) {
+            lcd.fillrect(food.x, food.y, food.x + 3, food.y + 3, 0);
+            snake.x[snake.node_num] = -20;
+            snake.y[snake.node_num] = -20;
+            snake.node_num++;
+            food.yes = 1;
+            score += 10 * level;
+            if(snake.node_num % 5 == 0) {
+                level++;
+            }
+        }
+        
+        for(int i = 0; i < snake.node_num; i++) {
+            lcd.fillrect(snake.x[i], snake.y[i], snake.x[i] + 3, snake.y[i] + 3, 1);
+        }
+        
+        wait(0.5 - 0.1 * level);
     }
+}
 
+int main() {
+    validity();
+    while(true) {
+        game_play();
+        lcd.cls();
+        lcd.locate(35,6);
+        lcd.printf("GAME OVER");
+        lcd.locate(16,16);
+        lcd.printf("MOVE THE JOYSTICK");
+        while(!check_joy() || fire) {
+            for (float i=2000.0; i<10000.0; i+=100) {
+                if(check_joy()) {
+                    break;
+                }
+                spkr.period(1.0/i);
+                spkr=0.5;
+                wait(0.1);
+            }
+            spkr=0.0;
+        }
+        lcd.cls();
+        lcd.locate(35,6);
+        lcd.printf("LENGTH: %d", snake.node_num);
+        lcd.locate(35,16);
+        lcd.printf("SCORE: %d", score);
+        
+        wait(3);
+    }
 }