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

main.cpp

Committer:
IUT_Nicolas_C
Date:
2018-06-12
Revision:
1:f41e3d62e7b2
Parent:
0:9167afeead2e

File content as of revision 1:f41e3d62e7b2:

#include "mbed.h"
#include "TS_DISCO_F746NG.h"
#include "LCD_DISCO_F746NG.h"
#include <MMA7660FC.h>

#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);        // Init Sensor
LCD_DISCO_F746NG lcd;                               // Init LCD
TS_DISCO_F746NG ts;                                 // Init TouchScreen

//---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_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);
    char string[50];
    sprintf(string,"AX = %3.3f",x);
    lcd.DisplayStringAt(0, LINE(5), (uint8_t *)string, CENTER_MODE);
    sprintf(string,"AY = %3.3f",y);
    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);
}
/** 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);
}
/** 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);
    sprintf(string,"Y = %03d",y);
    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);
}
/** 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;
    }
}
/** 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();
    drawOptions();
}
/** 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);
}
/** 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()
{
    //Declaration
    int x, y, i=0;
    float ax=0,ay=0,az=0;
    //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
        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
        /*displayAcc(ax,ay,az);
        displayCharPos();
        displayOri();//*/
        
        drawChar();
        i++;
        wait_ms(100);
    }
}