My ELEC2645 joystick project Tetris Game NAME: JIANWEI CHEN SID: 200879849

Dependencies:   N5110 SDFileSystem mbed

Revision:
4:463abe5f5135
Parent:
3:5494a0fb3a33
--- a/main.cpp	Sun May 01 23:09:33 2016 +0000
+++ b/main.cpp	Thu May 05 09:18:01 2016 +0000
@@ -1,577 +1,71 @@
 #include "mbed.h"
 #include "Patterns.h"
 #include "N5110.h"
-
-#define DIRECTION_TOLERANCE 0.05
-
-//VCC, SCE, RST, D/C, MOSI,SCLK, LED
-N5110 lcd(PTE26,PTA0,PTC4,PTD0,PTD2,PTD1,PTC3);
-AnalogIn yPot(PTB2);
-AnalogIn xPot(PTB3);
-DigitalIn button(PTB11);
-Patterns patterns;
-
-Ticker game;
-void game_isr();
-volatile int g_game_flag = 0;
-
-void drawPattern(int type,int rotation,int x,int y,int fill); // draw pattern at (x,y), fill = 0 white, fill = 1 black
-
-void left_collisionDetect();
-int left_collision_flag = 0;
-
-void right_collisionDetect();
-int right_collision_flag = 0;
-
-void bottom_collisionDetect();
-int bottom_collision_flag = 0;
-
-void top_collisionDetect();
-int top_collision_flag = 0;
-
-void rotation_collisionDetect();
-int rotation_collision_flag = 0;
-
-void fastmove_bottom_collisionDetect();
-int fastmove_bottom_collision_flag = 0;
-
-struct Position {
-    float x;
-    float y;
-    int type;
-    int rotation;
-};
-typedef struct Position position;
-
-position pos;
-
-void init_game();
-int typeArray[100];
-int rotationArray[100];
-
-int pattern_buffer[6][6];
-void get_pattern(int type, int rotatin);
-
-void scan();
-int buffer[84][48];
-
-// create enumerated type (0,1,2,3 etc. for direction)
-// could be extended for diagonals etc.
-enum DirectionName {
-    UP,
-    DOWN,
-    LEFT,
-    RIGHT,
-    CENTRE,
-    UNKNOWN
-};
-// struct for Joystick
-typedef struct JoyStick Joystick;
-struct JoyStick {
-    double x;    // current x value
-    double x0;   // 'centred' x value
-    double y;    // current y value
-    double y0;   // 'centred' y value
-    int button; // button state (assume pull-down used, so 1 = pressed, 0 = unpressed)
-    DirectionName direction;  // current direction
-};
-// create struct variable
-Joystick joystick;
-void calibrateJoystick();
-void updateJoystick();
-
-void cancelLine();// if one line is filled, cancel it and add the score
-int score=0;
-
-void finishAnimation();
-
-int xOld;
-int typeCount = 0;
-int nextTypeCount;
+#include "SDFileSystem.h"
+#include "Joystick.h"
+#include "Game.h"
+#include "main.h"
 
 int main()
 {
-    wait(2.0);  // short delay for power to settle
-    lcd.init();
-    lcd.normalMode();      // normal colour mode
-    lcd.setBrightness(1.0); // put LED backlight on 100%
-    init_game();
-    game.attach(&game_isr,0.2);
-    lcd.refresh();
-    calibrateJoystick();
-
-    while (1) {
+    init();
+    while(1) {
+        if(g_menuTimer_flag) {
+            g_menuTimer_flag=0;
 
-        if(g_game_flag==1) {
-            g_game_flag = 0;
-            pos.type = typeArray[typeCount];
-            nextTypeCount=typeCount+1;
-            if (nextTypeCount>99) {
-                nextTypeCount=0;
-            }
-            drawPattern(typeArray[nextTypeCount],0,55,41,1);// draw next pattern
-            if (pos.y >= -5) { // clear previous pattern
-                drawPattern(pos.type,pos.rotation,xOld,pos.y-1,0);
-            }
-            updateJoystick();
-            top_collisionDetect();
-            if (top_collision_flag == 1) {
-                finishAnimation();
+            if (g_button_flag) {// if button pressed, go to next menu according current state and pointer position input
+                g_button_flag=0;
+                state=fsm[state].nextState[pointer_position];
                 lcd.clear();
-                char scoreBuffer[14];
-                sprintf(scoreBuffer,"%d",score);
-                lcd.printString("SCORE IS: ",10,2);
-                lcd.printString(scoreBuffer,35,3);
-                lcd.refresh();
-                break;
-            }
-            switch(joystick.direction) {
-                case UP:
-                    rotation_collisionDetect();
-                    if(rotation_collision_flag == 0) {
-                        pos.rotation++;
-                        if (pos.rotation>3) {
-                            pos.rotation=0;
-                        }
-                        drawPattern(pos.type,pos.rotation,pos.x,pos.y,1);
-                    } else {// if collision
-                        drawPattern(pos.type,pos.rotation,pos.x,pos.y,1);
-                    }
-                    break;
-                case DOWN:
-                    fastmove_bottom_collisionDetect();
-                    if (fastmove_bottom_collision_flag == 0) {
-                        pos.y +=4;
-                        drawPattern(pos.type,pos.rotation,pos.x,pos.y,1);
-                    } else {
-                        drawPattern(pos.type,pos.rotation,pos.x,pos.y,1);
-                    }
-                    break;
-                case RIGHT:
-                    right_collisionDetect();
-                    if( right_collision_flag == 0) {
-                        pos.x +=2;
-                        drawPattern(pos.type,pos.rotation,pos.x,pos.y,1);
-                    } else {
-                        drawPattern(pos.type,pos.rotation,pos.x,pos.y,1);
-                        right_collision_flag = 0;
-                    }
-                    break;
-                case LEFT:
-                    left_collisionDetect();
-                    if( left_collision_flag == 0) {
-                        pos.x -=2;
-                        drawPattern(pos.type,pos.rotation,pos.x,pos.y,1);
-                    } else {
-                        drawPattern(pos.type,pos.rotation,pos.x,pos.y,1);
-                        left_collision_flag = 0;
-                    }
-
-                    break;
-                case CENTRE:
-                    drawPattern(pos.type,pos.rotation,pos.x,pos.y,1);
-                    break;
-                case  UNKNOWN:
-                    drawPattern(pos.type,pos.rotation,pos.x,pos.y,1);
-                    break;
-            }
-
-            xOld = pos.x;
-            bottom_collisionDetect();
-            if (bottom_collision_flag == 0) {
-                pos.y++;
-            } else {
-                drawPattern(pos.type,pos.rotation,pos.x,pos.y,1);// fix pattern
-                cancelLine();
-                pos.x = 10;
-                pos.y = -6;
-                pos.rotation=0;
-                drawPattern(typeArray[nextTypeCount],pos.rotation,55,41,0);// clear the old next pattern
-                typeCount ++;
-                if (typeCount >99) {
-                    typeCount = 0;
-                }
             }
 
-        }
-        lcd.refresh();
-    }
-
-}
-
-void init_game()
-{
-    pos.x = 10;
-    pos.y = -6;
-    pos.rotation=0;
-    for(int i=0; i<=99; i++) {
-        typeArray[i] = rand()%7;
-        rotationArray[i] = rand()%5;
-    }
-    lcd.drawLine(30,0,30,47,1);
-    lcd.printString("Level:",42,0);
-    lcd.printString("easy",42,1);
-    lcd.printString("Score:",42,2);
-    lcd.printString("0",42,3);
-    lcd.printString("Next:",42,4);
-
-}
-
-void get_pattern(int type, int rotation)
-{
-    for(int i=0; i<=5; i++) {
-        for(int j=0; j<=5; j++) {
-            pattern_buffer[i][j] = patterns.getPatterns(type,rotation,j,i);  // return pattern[type][rotation][y][x];
-        }
-    }
-}
-
-void scan()
-{
-    for (int i=0; i<=83; i++) {
-        for (int j=0; j<=47; j++) {
-            if(lcd.getPixel(i,j)) {
-                buffer[i][j] = 1;
-            } else {
-                buffer[i][j] = 0;
-            }
-        }
-    }
-}
-
-
-void drawPattern(int type,int rotation,int x,int y,int fill)
-{
-    get_pattern(type,rotation);
-    for(int i=x; i <= x+5; i++) { // (x,y) is the left top point of a 6*6 square
-        for(int j=y; j <= y+5; j++) {
-            if (j>=0) {
-                if(pattern_buffer[i-x][j-y]==1) {
-                    if (fill==0) {
-                        if (j<=47 && i>=0) {
-                            lcd.clearPixel(i,j);
-                        }
-                    } else if (fill==1) {
-                        if (j<=47 && i>=0) {
-                            lcd.setPixel(i,j);
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
-
-void left_collisionDetect()
-{
-    int left_boundary[6][6];
-    get_pattern(pos.type,pos.rotation);
-
-    // get the left boundary pattern
-    for (int j=0; j<=5; j++) { //
-        for (int i=0; i<=5; i++) {
-            if (pattern_buffer[i][j]==1) {
-                left_boundary[i][j]=1;
-                for(int k=i+1; k<=5; k++) {
-                    left_boundary[k][j] = 0;
-                }
-                break;
-            } else {
-                left_boundary[i][j]=0;
-            }
-        }
-    }
-
-    //check left collision
-    int x = pos.x;
-    int y = pos.y;
-    if (x<0) {
-        left_collision_flag = 1;
-    } else {
-        for(int i=x; i <= x+5; i++) { // (x,y) is the left top point of a 6*6 square
-            for(int j=y; j <= y+5; j++) {
-                if(left_boundary[i-x][j-y]==1) {
-                    if(i == 0) {
-                        left_collision_flag = 1;
-                        break;
-                    } else if (lcd.getPixel(i-1,j)) {
-                        left_collision_flag = 1;
-                        break;
-                    } else {
-                        left_collision_flag = 0;
-                    }
-                }
-            }
-            if (left_collision_flag == 1) {
-                break;
-            }
-        }
-    }
-}
-
-
-void right_collisionDetect()
-{
-    int right_boundary[6][6];
-    get_pattern(pos.type,pos.rotation);
-    // get the left boundary pattern
-    for (int j=0; j<=5; j++) {
-        for (int i=5; i>=0; i--) {
-            if (pattern_buffer[i][j]==1) {
-                right_boundary[i][j]=1;
-                for(int k=i-1; k>=0; k--) {
-                    right_boundary[k][j] = 0;
-                }
-                break;
-            } else {
-                right_boundary[i][j]=0;
+            switch(state) {
+                case 0: // main menu
+                    pointer();
+                    red_led=0;
+                    green_led=0;
+                    lcd.printString("Tetis Game",10,1);
+                    lcd.printString("START",25,3);
+                    lcd.printString("SCORE",25,4);
+                    lcd.refresh();
+                    break;
+                case 1: // game level choosing menu
+                    pointer();
+                    red_led=0;
+                    green_led=0;
+                    lcd.printString("Game Level",10,1);
+                    lcd.printString("EASY",25,3);
+                    lcd.printString("HARD",25,4);
+                    lcd.printString("Back",60,5);
+                    lcd.refresh();
+                    break;
+                case 2: // highest score menu
+                    red_led=0;
+                    green_led=0;
+                    lcd.printString("Highest Score:",1,1);
+                    int top_score;
+                    top_score=read_score_SD();
+                    char score[14];
+                    sprintf(score,"%d",top_score);
+                    lcd.printString(score,30,3);
+                    lcd.printString("Press Button",0,4);
+                    lcd.printString("To Exit",0,5);
+                    lcd.refresh();
+                    break;
+                case 3: // easy game menu
+                    init_game();
+                    game.attach(&game_isr,0.2);
+                    lcd.printString("easy",42,1);
+                    tetis_game();
+                    break;
+                case 4: // hard game menu
+                    init_game();
+                    game.attach(&game_isr,0.1);
+                    lcd.printString("hard",42,1);
+                    tetis_game();
+                    break;
             }
         }
-    }
-
-    //check left collision
-    int x = pos.x;
-    int y = pos.y;
-    for(int i = x; i <= x+5; i++) { // (x,y) is the left top point of a 6*6 square
-        for(int j=y; j <= y+5; j++) {
-            if(right_boundary[i-x][j-y]==1) {
-                if(j>=0) {
-                    if(i >= 29) {
-                        right_collision_flag = 1;
-                        break;
-                    } else if (lcd.getPixel(i+1,j)) {
-                        right_collision_flag = 1;
-                        break;
-                    } else {
-                        right_collision_flag = 0;
-                    }
-                }
-            }
-        }
-        if (right_collision_flag == 1) {
-            break;
-        }
-
-    }
-}
-
-void bottom_collisionDetect()
-{
-    int bot_boundary[6][6];
-    get_pattern(pos.type,pos.rotation);
-    // get the left boundary pattern
-    for (int i=0; i<=5; i++) {
-        for (int j=5; j>=0; j--) {
-            if (pattern_buffer[i][j]==1) {
-                bot_boundary[i][j]=1;
-                for(int k=j-1; k>=0; k--) {
-                    bot_boundary[i][k] = 0;
-                }
-                break;
-            } else {
-                bot_boundary[i][j]=0;
-            }
-        }
-    }
-
-    //check left collision
-    int x = pos.x;
-    int y = pos.y;
-    for(int i = x; i <= x+5; i++) { // (x,y) is the left top point of a 6*6 square
-        for(int j=y+5; j >= y; j--) {
-            if (j>=-1) {
-                if(bot_boundary[i-x][j-y]==1) {
-                    if(j >= 47) {
-                        bottom_collision_flag = 1;
-                        break;
-                    } else if (lcd.getPixel(i,j+1)) {
-                        bottom_collision_flag = 1;
-                        break;
-                    } else {
-                        bottom_collision_flag = 0;
-                    }
-                }
-            } else {
-                bottom_collision_flag = 0;
-            }
-        }
-        if( bottom_collision_flag == 1) {
-            break;
-        }
-    }
-}
-
-void rotation_collisionDetect()
-{
-    int rotation = pos.rotation+1;
-    if (rotation>3) {
-        rotation=0;
-    }
-    get_pattern(pos.type,rotation);
-
-    //check
-    int x = pos.x;
-    int y = pos.y;
-    for(int i = x; i <= x+5; i++) { // (x,y) is the left top point of a 6*6 square
-        for(int j=y; j <= y+5; j++) {
-            if(pattern_buffer[i-x][j-y]==1) {
-                if(i<0) {
-                    rotation_collision_flag = 1;
-                } else if(lcd.getPixel(i,j)) {
-                    rotation_collision_flag = 1;
-                    break;
-                } else {
-                    rotation_collision_flag = 0;
-                }
-            }
-        }
-        if (rotation_collision_flag == 1) {
-            break;
-        }
-    }
-}
-
-void top_collisionDetect()
-{
-    if (pos.y==-6) {
-        bottom_collisionDetect();
-        if (bottom_collision_flag == 1) {
-            top_collision_flag = 1;
-        } else {
-            top_collision_flag = 0;
-        }
+        sleep();
     }
 }
-
-void fastmove_bottom_collisionDetect()
-{
-    int bot_boundary[6][6];
-    get_pattern(pos.type,pos.rotation);
-    // get the left boundary pattern
-    for (int i=0; i<=5; i++) {
-        for (int j=5; j>=0; j--) {
-            if (pattern_buffer[i][j]==1) {
-                bot_boundary[i][j]=1;
-                for(int k=j-1; k>=0; k--) {
-                    bot_boundary[i][k] = 0;
-                }
-                break;
-            } else {
-                bot_boundary[i][j]=0;
-            }
-        }
-    }
-
-    //check left collision
-    int x = pos.x;
-    int y = pos.y;
-    for(int i = x; i <= x+5; i++) { // (x,y) is the left top point of a 6*6 square
-        for(int j=y+5; j >= y; j--) {
-            if (j>=-1) {
-                if(bot_boundary[i-x][j-y]==1) {
-                    if(j >= 42) {
-                        fastmove_bottom_collision_flag = 1;
-                        break;
-                    } else if (lcd.getPixel(i,j+4)) {
-                        fastmove_bottom_collision_flag = 1;
-                        break;
-                    } else {
-                        fastmove_bottom_collision_flag = 0;
-                    }
-                }
-            } else {
-                fastmove_bottom_collision_flag = 0;
-            }
-        }
-        if( fastmove_bottom_collision_flag == 1) {
-            break;
-        }
-    }
-}
-
-void game_isr()
-{
-    g_game_flag = 1;
-}
-
-// read default positions of the joystick to calibrate later readings
-void calibrateJoystick()
-{
-    button.mode(PullDown);
-    // must not move during calibration
-    joystick.x0 = xPot;  // initial positions in the range 0.0 to 1.0 (0.5 if centred exactly)
-    joystick.y0 = yPot;
-}
-
-void updateJoystick()
-{
-    // read current joystick values relative to calibrated values (in range -0.5 to 0.5, 0.0 is centred)
-    joystick.x = xPot - joystick.x0;
-    joystick.y = yPot - joystick.y0;
-    // read button state
-    joystick.button = button;
-
-    // calculate direction depending on x,y values
-    // tolerance allows a little lee-way in case joystick not exactly in the stated direction
-    if ( fabs(joystick.y) < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
-        joystick.direction = CENTRE;
-    } else if ( joystick.y < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
-        joystick.direction = UP;
-    } else if ( joystick.y > DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
-        joystick.direction = DOWN;
-    } else if ( joystick.x < DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) {
-        joystick.direction = RIGHT;
-    } else if ( joystick.x > DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) {
-        joystick.direction = LEFT;
-    } else {
-        joystick.direction = UNKNOWN;
-    }
-
-}
-
-void cancelLine()
-{
-    // int linePattern[30][2]; //the pixel setting for one line(30x2 square)
-    int count;
-    for(int j=0; j<=46; j+=2) {
-        for(int i=0; i<=29; i++) {
-            if (lcd.getPixel(i,j)==0||lcd.getPixel(i,j+1)==0) {
-                count=0;
-                break;
-            } else if (lcd.getPixel(i,j)&&lcd.getPixel(i,j+1)) {
-                count++;
-            }
-        }
-        if(count==30) { // one line is filled
-            count=0;
-            lcd.drawRect(0,j,29,1,2); //clear the line
-            score+=10;  // add the score
-            //print the score
-            char scoreBuffer[14];
-            sprintf(scoreBuffer,"%d",score);
-            lcd.printString(scoreBuffer,42,3);
-            scan();
-            // move the patterns upon the line down for 2 pixels' hight
-            for (int x=0; x<=29; x++) {
-                for (int y=j; y>=0; y--) {
-                    if (buffer[x][y]) {
-                        lcd.clearPixel(x,y);
-                        lcd.setPixel(x,y+2);
-                    }
-                }
-            }
-        }
-    }
-}
-
-void finishAnimation()
-{
-    for (int j=47; j>=0; j--) {
-        lcd.drawRect(0,j,29,1,1);
-        wait(0.05);
-        lcd.refresh();
-    }
-}
-
-
-