FRDM-KL25Z with Nokia 3110 type LCD display Using accelerometer to make movements

Dependencies:   MMA8451Q N3310LCD mbed

Fork of FRDM_MMA8451Q by mbed official

Revision:
11:90d35ac294af
Parent:
10:f3e93cc092d7
Child:
12:dbd6c9c366ac
--- a/main.cpp	Thu Mar 21 00:09:07 2013 +0000
+++ b/main.cpp	Thu Mar 21 21:53:58 2013 +0000
@@ -87,6 +87,22 @@
     }
 }
 
+void centreBoard( MMA8451Q *acc, float *cValues )
+{
+    // Take 100 readings to get stable centre point
+    for( int i = 0; i < 100; i++ ) {
+        float axis[3] = { 0.0, 0.0, 0.0 };
+        acc->getAccAllAxis( axis );
+        cValues[0] += axis[0];
+        cValues[1] += axis[1];
+        cValues[2] += axis[2];
+    }
+    cValues[0] /= 100.0;
+    cValues[1] /= 100.0;
+    cValues[2] /= 100.0;
+//    pc.printf( "Steady State X: %f Y: %f Z: %f\n", cValues[0], cValues[1], cValues[2] );
+}
+
 
 void draw(N3310LCD* lcd, Joystick* jstick)
 {
@@ -96,19 +112,20 @@
     int16_t xI, yI;
     int16_t xInc, yInc;
 
+    centreBoard( &acc, cValues );
     lcd->cls();
 
     // Take 100 readings to get stable centre point
-    for( int i = 0; i < 100; i++ ) {
-        float axis[3] = { 0.0, 0.0, 0.0 };
-        acc.getAccAllAxis( axis );
-        cValues[0] += axis[0];
-        cValues[1] += axis[1];
-    }
+    /*    for( int i = 0; i < 100; i++ ) {
+            float axis[3] = { 0.0, 0.0, 0.0 };
+            acc.getAccAllAxis( axis );
+            cValues[0] += axis[0];
+            cValues[1] += axis[1];
+        }
 
-    cValues[0] /= 100.0;
-    cValues[1] /= 100.0;
-
+        cValues[0] /= 100.0;
+        cValues[1] /= 100.0;
+    */
     // Draw a rectangle
     lcd->drawRectangle(0,0,83,47, PIXEL_ON);
 
@@ -141,10 +158,8 @@
 
         nx = MAX( 1, MIN( nx, 82 ) );
         ny = MAX( 1, MIN( ny, 46 ) );
-pc.printf( "X: %d Y: %d\n", nx, ny );
+//pc.printf( "X: %d Y: %d\n", nx, ny );
 
-
-// Seem to have broken this
         if( abs(xInc) > 1 || abs(yInc) > 1 ) {
             // Draw line
             lcd->drawLine((uint8_t)px, (uint8_t)py, (uint8_t)nx, (uint8_t)ny, PIXEL_ON);
@@ -161,16 +176,21 @@
 }
 
 #define MAX_SNAKE_LEN 400
+#define MAX_FOOD 10
 #define SNAKE_X 0
 #define SNAKE_Y 1
 #define DIR_N 1
 #define DIR_E 2
 #define DIR_S 3
 #define DIR_W 4
+#define FOOD_X 0
+#define FOOD_Y 1
 
 int16_t snakeLen = 10;
+int16_t foodCount = 0;
 
 int8_t snake[MAX_SNAKE_LEN][2];       // Snake positions, use -1 for no point
+int8_t food[MAX_FOOD][2];
 
 void initSnake( void )
 {
@@ -221,7 +241,7 @@
         oX = snake[i][SNAKE_X];
         oY = snake[i][SNAKE_Y];
         snake[i][SNAKE_X] = nX;
-        snake[i][SNAKE_Y] = nY;        
+        snake[i][SNAKE_Y] = nY;
     }
 
     drawSnake(lcd);
@@ -234,16 +254,102 @@
         // Clear tail
         lcd->setPixel( oX, oY, PIXEL_OFF );
     }
-    
 }
 
-bool checkCollision() {
-bool collisionFlag = false;
+bool checkCollision( uint8_t dir)
+{
+    bool collisionFlag = false;
 
     return collisionFlag;
 }
 
 
+void initFood()
+{
+    for( uint8_t i = 0; i< MAX_FOOD; i++ ) {
+        food[i][FOOD_X] = -1;
+        food[i][FOOD_Y] = -1;
+    }
+}
+
+
+// Get current snake head and work out if position is a food
+bool checkFood(uint8_t dir)
+{
+    bool foodFlag = false;
+pc.printf("CHECK: X %d, Y %d\n",snake[0][SNAKE_X], snake[0][SNAKE_Y]);
+    for( int i = 0; i < MAX_FOOD; i++ ) {
+pc.printf("FOOD: X %d, Y %d\n",food[i][FOOD_X], food[i][FOOD_Y]);
+    
+        if( snake[0][SNAKE_X] == food[i][FOOD_X] && snake[0][SNAKE_Y] == food[i][FOOD_Y] ) {
+            foodFlag = true;
+            food[i][FOOD_X] = -1;
+            food[i][FOOD_Y] = -1;
+            foodCount--;
+pc.printf("FOOD!\n");
+            break;
+        }
+    }
+    return foodFlag;
+}
+
+bool isOnSnake( int8_t *sX, int8_t *sY )
+{
+    bool onSnake = false;
+    pc.printf("isOnSnake sX = %d, sY = %d \n", *sX, *sY );
+    for( int i = 0; i< snakeLen; i++ ) {
+        if( snake[i][SNAKE_X] == *sX && snake[i][SNAKE_Y] == *sY ) {
+            onSnake = true;
+            break;
+        }
+    }
+    return onSnake;
+}
+
+
+void getRandomPosition( int8_t *rX, int8_t *rY )
+{
+    *rX = ((rand() % 100)*82)/100+1;
+    *rY = ((rand() % 100)*46)/100+1;
+
+    while( isOnSnake( rX, rY )) {
+        *rX = ((rand() % 100)*82)/100+1;
+        *rY = ((rand() % 100)*46)/100+1;
+    }
+
+}
+
+void storeFood( int8_t fX, int8_t fY )
+{
+    pc.printf("Store fX = %d, fY = %d \n", fX, fY );
+    for( int i = 0; i< MAX_FOOD; i++ ) {
+        if( food[i][FOOD_X] < 0 ) {
+        pc.printf("Store in %d\n",i);
+            food[i][FOOD_X] = fX;
+            food[i][FOOD_Y] = fY;
+            break;
+        }
+    }
+}
+
+
+void dropFood(N3310LCD* lcd)
+{
+    // If no food present then drop some
+    // Pick random x and y coords x >0 and x < 83, y > 0 and y <47
+    while( foodCount < MAX_FOOD ) {
+        int8_t fX = 0;
+        int8_t fY = 0;
+        getRandomPosition( &fX, &fY );
+        lcd->setPixel( fX, fY, PIXEL_ON );
+        storeFood( fX, fY );
+        foodCount++;
+
+        pc.printf("fX = %d, fY = %d \n", fX, fY );
+    }
+
+}
+
 void snakeGame(N3310LCD* lcd, Joystick* jstick)
 {
     MMA8451Q acc(PTE25, PTE24, MMA8451_I2C_ADDRESS, false, 4);
@@ -252,51 +358,39 @@
     int16_t xI, yI; //, zI;
     int16_t xInc, yInc;
 
-    // Take 100 readings to get stable centre point
-
-    for( int i = 0; i < 100; i++ ) {
-        float axis[3] = { 0.0, 0.0, 0.0 };
-        acc.getAccAllAxis( axis );
-        cValues[0] += axis[0];
-        cValues[1] += axis[1];
-//        cValues[2] += axis[2];
-    }
-
-    cValues[0] /= 100.0;
-    cValues[1] /= 100.0;
-//    cValues[2] /= 100.0;
-//    pc.printf( "Steady State X: %f Y: %f Z: %f\n", cValues[0], cValues[1], cValues[2] );
-
-    initSnake();
+    centreBoard( &acc, cValues );
 
     lcd->cls();
 
     // Draw a rectangle
     lcd->drawRectangle(0,0,83,47, PIXEL_ON);
 
+    initSnake();
+    initFood();
+    dropFood(lcd);
     drawSnake( lcd );
-
-    for( int i=0; i<10; i++ ) {
-        moveSnake(lcd, DIR_N, 1);
-        wait(0.2);
-    }
-    for( int i=0; i<20; i++ ) {
-        moveSnake(lcd, DIR_E, 0);
-        wait(0.2);
-    }
-    for( int i=0; i<20; i++ ) {
-        moveSnake(lcd, DIR_S, 1);
-        wait(0.2);
-    }
-    for( int i=0; i<20; i++ ) {
-        moveSnake(lcd, DIR_W, 1);
-        wait(0.2);
-    }
-
-    int8_t px = 42;
-    int8_t py = 25;
-    int8_t nx = px;
-    int8_t ny = py;
+    /* Test to move snake
+        for( int i=0; i<10; i++ ) {
+            moveSnake(lcd, DIR_N, 1);
+            wait(0.2);
+        }
+        for( int i=0; i<20; i++ ) {
+            moveSnake(lcd, DIR_E, 0);
+            wait(0.2);
+        }
+        for( int i=0; i<20; i++ ) {
+            moveSnake(lcd, DIR_S, 1);
+            wait(0.2);
+        }
+        for( int i=0; i<20; i++ ) {
+            moveSnake(lcd, DIR_W, 1);
+            wait(0.2);
+        }
+    */
+//    int8_t px = 42;
+//    int8_t py = 25;
+//    int8_t nx = px;
+//    int8_t ny = py;
 
 //    lcd->setPixel( px, py, PIXEL_ON );
 
@@ -305,7 +399,7 @@
     bool exitFlag = false;
     uint8_t snakeDirection = DIR_W;
     uint8_t snakeGrowth = 0;
-    
+
     while ( !exitFlag ) {
         uint8_t keyPress = checkKeypressed( jstick );
         if( keyPress == CENTER_KEY )
@@ -313,15 +407,13 @@
 
         x = (acc.getAccX() - cValues[0]) * 100.0;
         y = (acc.getAccY() - cValues[1]) * 100.0;
-//        z = (acc.getAccZ() - cValues[2]) * 100.0;
 //       pc.printf( "X: %f Y: %f Z: %f\n", x, y, z);
 
         xI = (int16_t)(x);
         yI = (int16_t)(y);
-//        zI = (int16_t)(z);
         xInc = xI/10;
         yInc = ((yI/10) * -1);
-        
+
         if( xInc > 2 )
             snakeDirection = DIR_E;
         else if( xInc < -2 )
@@ -330,36 +422,27 @@
             snakeDirection = DIR_S;
         else if( yInc < -2 )
             snakeDirection = DIR_N;
+
+        if( snakeGrowth > 0 ) snakeGrowth--;
+
         moveSnake(lcd, snakeDirection, snakeGrowth);
         // TODO Check if we've collided with anything
-        if( checkCollision() ) {
+        if( checkCollision(snakeDirection) ) {
             // Collision detected!!
         }
-        
-        if( snakeGrowth > 0 ) snakeGrowth--;
+
+        if( checkFood(snakeDirection) ) {
+            // Gobbled some food!!
+            // Indicate that snake is to grow during next moves
+            snakeGrowth = 10;
+
+            // Handle new food bing added to area
+            dropFood(lcd);
+        }
+
+        // A little pause - vary this after snake length has reached 100, then 200, then 300
         wait(0.2);
 
-/*
-        nx += xInc;
-        ny += yInc;
-
-        nx = MAX( 1, MIN( nx, 82 ) );
-        ny = MAX( 1, MIN( ny, 46 ) );
-
-        if( abs(xInc) > 1 || abs(yInc) > 1 ) {
-            // Draw line
-            lcd->drawLine((uint8_t)px, (uint8_t)py, (uint8_t)nx, (uint8_t)ny, PIXEL_ON);
-        } else {
-            // Plot pixel
-            lcd->setPixel( (uint8_t)nx, (uint8_t)ny, PIXEL_ON );
-        }
-
-        px = nx;
-        py = ny;
-
-//        pc.printf( "X: %d Y: %d Z: %d\n", xI, yI, zI);
-        wait(0.1);
-        */
     }
 
 }
@@ -419,8 +502,8 @@
     // demo stuff
     // autoDemo(&lcd);
 
-    lcd.drawBitmap(0, 0, splash, 84, 48);
-    wait( 5 );
+//    lcd.drawBitmap(0, 0, splash, 84, 48);
+//    wait( 5 );
     lcd.cls();
 
     initMenu(&lcd);