You will be able to control a yellow ball through a level like a labyrinth

Dependencies:   BSP_DISCO_F746NG LCD_DISCO_F746NG MMA7660FC TS_DISCO_F746NG mbed

Revision:
1:f41e3d62e7b2
Parent:
0:9167afeead2e
--- a/main.cpp	Tue May 29 14:42:38 2018 +0000
+++ b/main.cpp	Tue Jun 12 14:46:18 2018 +0000
@@ -1,32 +1,94 @@
 #include "mbed.h"
+#include "TS_DISCO_F746NG.h"
 #include "LCD_DISCO_F746NG.h"
 #include <MMA7660FC.h>
 
-#define SLAVE_ADRESS 0x4c 
+#define SLAVE_ADRESS 0x4c
+//---USER---//
+int level = 1;                      //Actual Level
+int old_charac[2] = {0,0};          //Old Position
+int charac[2] = {0,0};              //Actual Position on the grid
+float origin[3] = {0.0,0.0,0.0};    //Sensor Position
+bool drawn = 0;                     //Is Character drawn ?
+//---BUTTONS---//
+int btnNext[4]  = {415, 35,465, 85};//Position of the buttons
+int btnPrev[4]  = {415,115,465,165};//
+int btnReset[4] = {415,207,465,257};//
+//---labyrinth---//
+//Size : 16 * 10
+//Square Size : 25 * 25
+bool labyrinth1[160] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ,
+                          1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,1 ,
+                          1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,1 ,
+                          0,0,1,1,1,0,1,1,1,0,1,0,1,0,0,1 ,
+                          1,0,1,0,0,0,0,0,1,0,1,0,0,1,1,1 ,
+                          1,0,0,0,1,0,1,0,0,0,1,1,0,0,0,1 ,
+                          1,1,1,0,1,0,1,0,1,1,0,0,0,1,0,0 ,
+                          1,0,0,0,0,0,0,0,0,0,1,1,0,1,0,1 ,
+                          1,0,1,0,0,1,0,0,1,0,0,0,0,1,0,1 ,
+                          1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
+                        };
+bool labyrinth2[160] = { 1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1 ,
+                          1,0,0,0,1,0,1,0,0,0,0,0,0,0,1,1 ,
+                          1,0,1,0,0,0,1,0,1,0,1,0,1,0,0,1 ,
+                          1,0,1,0,1,0,0,0,1,0,1,1,1,1,0,1 ,
+                          1,0,0,0,1,1,1,1,1,0,0,0,0,0,0,1 ,
+                          1,0,1,1,1,0,0,0,0,0,1,1,0,1,0,1 ,
+                          1,0,0,0,1,0,1,1,1,0,1,0,0,0,0,1 ,
+                          1,0,1,0,0,0,0,0,1,0,1,0,1,1,0,1 ,
+                          1,0,0,0,1,0,1,0,1,0,0,0,0,0,0,1 ,
+                          1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1 
+                        };
 
+
+bool* labyrinths[2] = {labyrinth1, labyrinth2};     // All labyrinths in one tab
 //---PIN SETUP
-MMA7660FC sensor(PB_9,PB_8,SLAVE_ADRESS<<1);
-LCD_DISCO_F746NG lcd;
-DigitalOut myled(LED1);
+MMA7660FC sensor(PB_9,PB_8,SLAVE_ADRESS<<1);        // Init Sensor
+LCD_DISCO_F746NG lcd;                               // Init LCD
+TS_DISCO_F746NG ts;                                 // Init TouchScreen
 
-//---DECLARATION
-void initLCD();
+//---DECLARATION_FUNCTIONS
+void checkPos(int,int);
 void displayAcc(float,float,float);
+void displayCharPos();
 void displayPos(int,int,int);
 void displayOrientation(const char*);
+void drawChar();
 void drawRect(int,int,int,int);
+void drawLabyrinth(int);
+void drawLevel(bool[]);
+void drawOptions();
 void drawUi();
 void drawUiButtons();
 void drawUiStructure();
+void initLCD();
+void updateChar(float,float,float,bool[]);
+void resetPos();
+void nextLvl();
+void prevLvl();
+void isWinning(int);
 
-//---INITIALISATION
-void initLCD() {
-    lcd.Clear(LCD_COLOR_WHITE);
-    lcd.SetBackColor(LCD_COLOR_BLUE);
+//---INITIALISATION_FUNCTIONS
+/** Function checkPos
+  * Checking actual position of a finger on the touchscreen
+  */ 
+void checkPos(int x, int y)
+{
+    if(x > btnReset[0] && y > btnReset[1] && x < btnReset[2] && y < btnReset[3]) {
+        resetPos();
+    } else if(x > btnNext[0] && y > btnNext[1] && x < btnNext[2] && y < btnNext[3]) {
+        nextLvl();
+    } else if(x > btnPrev[0] && y > btnPrev[1] && x < btnPrev[2] && y < btnPrev[3]) {
+        prevLvl();
+    }
+}
+/** Function displayAcc
+  * Displays the actual acceleration of the sensor (not used)
+  */ 
+void displayAcc(float x, float y, float z)
+{
+    uint8_t color = lcd.GetTextColor();
     lcd.SetTextColor(LCD_COLOR_BLACK);
-    wait(0.3);
-}
-void displayAcc(float x, float y, float z) {
     char string[50];
     sprintf(string,"AX = %3.3f",x);
     lcd.DisplayStringAt(0, LINE(5), (uint8_t *)string, CENTER_MODE);
@@ -34,14 +96,57 @@
     lcd.DisplayStringAt(0, LINE(6), (uint8_t *)string, CENTER_MODE);
     sprintf(string,"AZ = %3.3f",z);
     lcd.DisplayStringAt(0, LINE(7), (uint8_t *)string, CENTER_MODE);
+    lcd.SetTextColor(color);
 }
-void displayOrientation(const char *o) {
+/** Function displayCharPos
+  * Displays the actual position of the character (not used)
+  */ 
+void displayCharPos() 
+{
+    uint8_t color = lcd.GetTextColor();
+    lcd.SetTextColor(LCD_COLOR_BLACK);
+    char string[50];
+    sprintf(string,"X = %3d",charac[0]);
+    lcd.DisplayStringAt(0, LINE(8), (uint8_t *)string, CENTER_MODE);
+    sprintf(string,"Y = %3d",charac[1]);
+    lcd.DisplayStringAt(0, LINE(9), (uint8_t *)string, CENTER_MODE);
+    lcd.SetTextColor(color);
+}
+/** Function displayOri
+  * Displays the origin acceleration of the sensor (not used)
+  */ 
+void displayOri()
+{
+    uint8_t color = lcd.GetTextColor();
+    lcd.SetTextColor(LCD_COLOR_BLACK);
+    char string[50];
+    sprintf(string,"AX = %3.3f",origin[0]);
+    lcd.DisplayStringAt(0, LINE(1), (uint8_t *)string, CENTER_MODE);
+    sprintf(string,"AY = %3.3f",origin[1]);
+    lcd.DisplayStringAt(0, LINE(2), (uint8_t *)string, CENTER_MODE);
+    sprintf(string,"AZ = %3.3f",origin[2]);
+    lcd.DisplayStringAt(0, LINE(3), (uint8_t *)string, CENTER_MODE);
+    lcd.SetTextColor(color);
+}
+/** Function displayOrientation
+  * Displays the actual orientation of the sensor (not used)
+  */ 
+void displayOrientation(const char *o)
+{
+    uint8_t color = lcd.GetTextColor();
+    lcd.SetTextColor(LCD_COLOR_BLACK);
     char string[50];
     sprintf(string,"O = %s",o);
     lcd.DisplayStringAt(0, LINE(4), (uint8_t *)string, CENTER_MODE);
-    
+    lcd.SetTextColor(color);
 }
-void displayPos(int x, int y, int z) {
+/** Function displayPos
+  * Displays the actual position of the sensor (not used)
+  */
+void displayPos(int x, int y, int z)
+{
+    uint8_t color = lcd.GetTextColor();
+    lcd.SetTextColor(LCD_COLOR_BLACK);
     char string[50];
     sprintf(string,"X = %03d",x);
     lcd.DisplayStringAt(0, LINE(1), (uint8_t *)string, CENTER_MODE);
@@ -49,50 +154,310 @@
     lcd.DisplayStringAt(0, LINE(2), (uint8_t *)string, CENTER_MODE);
     sprintf(string,"Z = %03d",z);
     lcd.DisplayStringAt(0, LINE(3), (uint8_t *)string, CENTER_MODE);
+    lcd.SetTextColor(color);
 }
-void drawRect(int x1, int y1, int x2, int y2) {
-    lcd.DrawRect(x1, y1, x2-x1, y2-y1);
+/** Function drawChar
+  * Draws the character on the labyrinth
+  */
+void drawChar()
+{
+    if((old_charac[0] != charac[0] || old_charac[1] != charac[1])||(drawn == 0)) {
+        uint8_t color = lcd.GetTextColor();
+        lcd.SetTextColor(LCD_COLOR_WHITE);
+        lcd.FillCircle(old_charac[0]*25+11+12,old_charac[1]*25+10+12,11);
+        lcd.SetTextColor(LCD_COLOR_YELLOW);
+        lcd.FillCircle(charac[0]*25+11+12,charac[1]*25+10+12,11);
+        lcd.SetTextColor(color);
+        old_charac[0] = charac[0];
+        old_charac[1] = charac[1];
+        drawn = 1;
+    }
+}
+/** Function drawLabyrinth
+  * Sets the position of the character and calls drawLevel()
+  */
+void drawLabyrinth(int lvl)
+{
+    switch(lvl) {
+        case 1:
+            drawLevel(labyrinth1);
+            charac[0]= 0;
+            charac[1]= 3;
+            old_charac[0]= 0;
+            old_charac[1]= 3;
+            break;
+        case 2:
+            drawLevel(labyrinth2);
+            charac[0]= 7;
+            charac[1]= 0;
+            old_charac[0]= 7;
+            old_charac[1]= 0;
+            break;
+        default:
+            break;
+    }
 }
-void drawUi() {
+/** Function drawLevel
+  * Displays the labyrinth on the screen
+  */
+void drawLevel(bool labyrinth[])
+{
+    uint8_t color = lcd.GetTextColor();
+    for(int i = 0; i<10; i++) {
+        for(int j = 0; j<16; j++) {
+            if(labyrinth[j+(i*16)] == 1) {
+                lcd.SetTextColor(LCD_COLOR_BLACK);
+                lcd.FillRect(11+(j*25),10+(i*25), 25, 25);
+            } else if(labyrinth[j+(i*16)] == 0) {
+                lcd.SetTextColor(LCD_COLOR_WHITE);
+                lcd.FillRect(11+(j*25),10+(i*25), 25, 25);
+            }
+        }
+    }
+    lcd.SetTextColor(color);
+}
+/** Function drawLevelNbr
+  * Displays the level number on the options menu
+  */
+void drawLevelNbr() 
+{
+    uint8_t color = lcd.GetTextColor();
+    sFONT *font = lcd.GetFont();
+    sFONT f = Font20;
+    char str[50];
+    
+    lcd.SetFont(&f);
+    lcd.SetTextColor(LCD_COLOR_BLACK);
+    sprintf(str,"%d",level);    
+    lcd.DisplayStringAt(440-8, 100-7,(uint8_t *) str, LEFT_MODE);
+    
+    lcd.SetFont(font);    
+    lcd.SetTextColor(color);
+}
+/** Function drawOptions
+  * Displays the option tab
+  */
+void drawOptions() 
+{
+    uint8_t color = lcd.GetTextColor();
+    sFONT *font = lcd.GetFont();
+    sFONT f = Font16;
+    lcd.SetFont(&f);
+    uint8_t str[6] = "Level";
+    lcd.SetTextColor(LCD_COLOR_BLACK);
+    lcd.DisplayStringAt(414, 15, str, LEFT_MODE);
+    lcd.SetFont(font);
+    drawUiButtons();
+    drawLevelNbr();
+    lcd.SetTextColor(color);
+}
+/** Function drawRect
+  * Displays a rectangle on the screen
+  */
+void drawRect(int x1, int y1, int x2, int y2)
+{
+    uint8_t color = lcd.GetTextColor();
+    lcd.SetTextColor(LCD_COLOR_BLACK);
+    lcd.DrawRect(x1, y1, x2-x1, y2-y1);
+    lcd.SetTextColor(color);
+}
+/** Function drawUi
+  * Draws the UI 
+  */
+void drawUi()
+{
     drawUiStructure();
-    drawUiButtons();
+    drawOptions();
 }
-void drawUiButtons() { 
-      lcd.SetTextColor(LCD_COLOR_BLUE);
-    drawRect(415, 15,465, 65);
-    drawRect(415,207,465,257);    
+/** Function drawUiButtons
+  * Draws buttons on the option tab
+  */
+void drawUiButtons()
+{
+    uint8_t color = lcd.GetTextColor();
+    lcd.SetTextColor(LCD_COLOR_BLUE);
+    drawRect(415, 35,465, 85); // Next Level
+    lcd.SetTextColor(LCD_COLOR_BLACK);
+    lcd.DisplayChar(440-8,50,'N');
+    
+    lcd.SetTextColor(LCD_COLOR_BLUE);
+    drawRect(415,115,465,165); // Previous Level
+    lcd.SetTextColor(LCD_COLOR_BLACK);
+    lcd.DisplayChar(440-8,130,'P');
+    
+    lcd.SetTextColor(LCD_COLOR_BLUE);
+    drawRect(415,207,465,257); // Reset Pos
+    lcd.SetTextColor(LCD_COLOR_BLACK);
+    lcd.DisplayChar(440-8,232-10,'R');
+    lcd.SetTextColor(color);
+}
+/** Function drawUiStructure
+  * Draws rectangle on the UI as delimiters
+  */
+void drawUiStructure()
+{
+    uint8_t color = lcd.GetTextColor();
+    lcd.SetTextColor(LCD_COLOR_BLACK);
+    drawRect( 11, 10,411,260);         //Partie labyrinth
+    drawRect(411, 10,470,260);         //Partie Utilisateur
+    lcd.SetTextColor(color);
+}
+/** Function initLCD
+  * Initializes the LCD
+  */
+void initLCD()
+{
+    lcd.Clear(LCD_COLOR_WHITE);
+    //lcd.SetBackColor(LCD_COLOR_BLUE);
+    lcd.SetTextColor(LCD_COLOR_BLACK);
+    wait(0.3);
 }
-void drawUiStructure() {
-      lcd.SetTextColor(LCD_COLOR_BLACK);
-    drawRect( 10, 10,400,262);    
-    drawRect(410, 10,470,262);
+/** Function updateChar
+  * Updates the position of the character if 
+  * - The sensor is in the range
+  * - The character is nearby a white square
+  * - The direction is oriented to a white square
+  * Checks if the player has won the level
+  */
+void updateChar(float ax, float ay, float az, bool lab[])
+{
+    float oldX = origin[0], oldY = origin[1], oldZ = origin[2];
+    
+    //Sensor is bended downwards
+    if ((az >= oldZ+30) || (az <= oldZ-30)) {
+        //Sensor is bended left
+        if (ax <= oldX-30) {
+            if (!(charac[0] <= 0) && (lab[16*charac[1]+charac[0]-1] == 0)) {
+                charac[0]--;
+            }
+        }
+        //Sensor is bended right
+        else if (ax >= oldX+30) {
+            if (!(charac[0] >= 15) && (lab[16*charac[1]+charac[0]+1] == 0)) {
+                charac[0]++;
+            }
+        }
+        //Sensor is bended forward
+        else if (ay <= oldY-30) {
+            if (!(charac[1] <= 0) && (lab[16*charac[1]+charac[0]-16] == 0)) {
+                charac[1]--;
+            }
+        }
+        //Sensor is bended backward
+        else if (ay >= oldX+30) {
+            if (!(charac[1] >= 9) && (lab[16*charac[1]+charac[0]+16] == 0)) {
+                charac[1]++;
+            }
+        }
+    }
+        
+    isWinning(level);
+    //charac[0] = {x}; should be used to update character position on x
+    //charac[1] = {y}; should be used to update character position on y
 }
-
+/** Function resetPos
+  * Reset the original acceleration of the sensor
+  */
+void resetPos()
+{
+    float ax=0,ay=0,az=0;
+    sensor.read_Tilt(&ax,&ay,&az);
+    origin[0] = ax;
+    origin[1] = ay;
+    origin[2] = az;
+}
+/** Function nextLvl
+  * Loads the next level
+  */
+void nextLvl() 
+{
+    if(level < 2)
+        level++;  
+    drawLabyrinth(level);
+    drawLevelNbr();
+    drawn = 0;
+    drawChar();
+}
+/** Function prevLvl
+  * Loads the previous level
+  */
+void prevLvl()
+{
+    if(level > 1)
+        level--;
+    drawLabyrinth(level);
+    drawLevelNbr();
+    drawn = 0;
+    drawChar();
+}
+/** Function isWinning
+  * Checks if the player has won the level
+  */
+void isWinning(int lvl) 
+{
+    switch(lvl) {
+        case 1:
+            if (charac[0]== 15 && charac[1]== 6)
+                nextLvl();
+            break;        
+        case 2:
+            if (charac[0]== 7 && charac[1]== 9)
+                nextLvl();
+            break;
+        default:
+            break;
+    }
+}
 //---MAIN
-int main() {  
-    int data[3] = {0,0,0};
+int main()
+{
+    //Declaration
+    int x, y, i=0;
     float ax=0,ay=0,az=0;
-    const char *orientation;
+    //Initialization
     sensor.init();
     initLCD();
+    ts.Init(lcd.GetXSize(), lcd.GetYSize());
+    TS_StateTypeDef TS_State;
+    //Setting up the UI
     drawUi();
-    
+    drawLabyrinth(level);
+
+    //Setting up the sensor configuration
     sensor.write_reg(0x07,0);
     sensor.write_reg(0x04,0x000);
     sensor.write_reg(0x07,1);
-            
+
+    //Setting original acceleration 
+    resetPos();
+
     while(1) {
         //Getting Values
-        data[0]=sensor.read_x();
-        data[1]=sensor.read_y();
-        data[2]=sensor.read_z();
-        sensor.read_Tilt(&ax,&ay,&az); 
-        orientation=sensor.read_Orientation();       
+        sensor.read_Tilt(&ax,&ay,&az);
+        //Getting touchscreen state
+        ts.GetState(&TS_State);
+        //Getting pos on the touchscreen
+        x = TS_State.touchX[0];
+        y = TS_State.touchY[0];
+
+        //Check Pos
+        if(TS_State.touchDetected>0)
+            checkPos(x,y);
         
+        //If timeout updating character position    
+        if(i > 6) {
+            updateChar(ax,ay,az,labyrinths[level-1]);
+            i = -1;
+        }
+        
+        //---DEBUG
         //Printing Values
-        lcd.SetTextColor(LCD_COLOR_BLACK);
-        displayPos(data[0],data[1],data[2]);  
-        displayAcc(ax,ay,az);
-        displayOrientation(orientation);                 
+        /*displayAcc(ax,ay,az);
+        displayCharPos();
+        displayOri();//*/
+        
+        drawChar();
+        i++;
+        wait_ms(100);
     }
 }