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

Dependencies:   N5110 SDFileSystem mbed

Revision:
1:2a758565f691
Parent:
0:12a1972fa0d0
Child:
2:f427089e2bfa
--- a/main.cpp	Sun Apr 17 12:13:34 2016 +0000
+++ b/main.cpp	Mon Apr 25 11:01:19 2016 +0000
@@ -2,19 +2,28 @@
 #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_xMin = 0;
 int left_collision_flag = 0;
 
 void right_collisionDetect();
-int right_xMax = 29;
 int right_collision_flag = 0;
 
+int left_boundary[6][6];
 
 void bottom_collisionDetect();
 int bottom_yMax = 47;
@@ -28,9 +37,11 @@
 };
 typedef struct Position position;
 
-position pos_current;
+position pos;
 
 void init_game();
+int typeArray[100];
+int rotationArray[100];
 
 int pattern_buffer[6][6];
 void get_pattern(int type, int rotatin);
@@ -38,70 +49,134 @@
 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 {
+    float x;    // current x value
+    float x0;   // 'centred' x value
+    float y;    // current y value
+    float 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();
+
 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 50%
-    /*
+    lcd.setBrightness(1.0); // put LED backlight on 100%
     init_game();
-    lcd.clear();
+    game.attach(&game_isr,0.4);
+    lcd.refresh();
 
-    lcd.drawLine(0,16,25,16,1);
-    drawPattern(pos_current.type,pos_current.rotation,pos_current.x,pos_current.y,1);
-    right_collisionDetect();
-    if (right_collision_flag == 1) {
-        lcd.printString("1",0,0);
-    }
-    lcd.drawLine(35,0,35,47,2);
-    lcd.printString("Level:",42,0);
-    lcd.printString("easy",42,1);
-    lcd.printString("Score:",42,2);
-    lcd.printString("100",42,3);
-    lcd.printString("Next:",42,4);
-    wait(0.5);
-    lcd.refresh();*/
-    /*
-        lcd.clear();
+    int xOld;
+    calibrateJoystick();
 
-        drawPattern(0,0,0,0,1);
-        drawPattern(1,0,10,0,1);
-        drawPattern(2,0,20,0,1);
-        drawPattern(3,0,30,0,1);
-        drawPattern(4,0,40,0,1);
-        drawPattern(5,0,50,0,1);
-        drawPattern(6,0,60,0,1);
-        lcd.refresh();
-        */
-    int i =0;
+    int typeCount = 10;
+    int rotationCount = 5;
+
     while (1) {
 
+        if(g_game_flag==1) {
+            g_game_flag = 0;
+            pos.type = typeArray[typeCount];
+            pos.rotation = rotationArray[rotationCount];
+            if (pos.y >= -6) { // clear previous pattern
+                drawPattern(pos.type,pos.rotation,xOld,pos.y-1,0);
+            }
+            updateJoystick();
 
-        drawPattern(0,i,0,0,1);
-        drawPattern(1,i,10,0,1);
-        drawPattern(2,i,20,0,1);
-        drawPattern(3,i,30,0,1);
-        drawPattern(4,i,40,0,1);
-        drawPattern(5,i,50,0,1);
-        drawPattern(6,i,60,0,1);
-        lcd.refresh();      
-        i++;
-        if (i==4) {
-            i=0;
-        }      
-        wait(0.5);
-        lcd.clear();
+            switch(joystick.direction) {
+                case UP:
+                    pos.x +=2;
+                    drawPattern(pos.type,pos.rotation,pos.x,pos.y,1);
+                    break;
+                case DOWN:
+                    pos.y +=4;
+                    drawPattern(pos.type,pos.rotation,pos.x,pos.y,1);
+                    break;
+                case RIGHT:
+                    right_collisionDetect();
+                    /*
+                    for (int i=0; i<=5; i++) {
+                        for (int j=0; j<=5; j++) {
+                            if(right_boundary[i][j] ==1) {
+                                lcd.setPixel(i,j);
+                            }
+                        }
+                    }
+                    */
+                    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);
+                    }
+                    break;
+                case LEFT:
+                    left_collisionDetect();
+                    if( left_collision_flag == 0) {
+                        pos.x -=2;
+                        drawPattern(pos.type,pos.rotation,pos.x,pos.y,1);
+                        //   lcd.printString("0",42,5);
+                    } else {
+                        drawPattern(pos.type,pos.rotation,pos.x,pos.y,1);
+                        //  lcd.printString("1",42,5);
+                    }
+                    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;
+            if (pos.y<42) {
+                pos.y++;
+            } else {
+                pos.y=42;
+            }
+        }
+
+        lcd.refresh();
     }
 
 }
 
 void init_game()
 {
-    pos_current.x = 10;
-    pos_current.y = 10;
-    pos_current.type = 6;
-    pos_current.rotation = 2;
+    pos.x = 10;
+    pos.y = -6;
+
+    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("100",42,3);
+    lcd.printString("Next:",42,4);
+
 }
 
 void get_pattern(int type, int rotation)
@@ -132,11 +207,17 @@
     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(pattern_buffer[i-x][j-y]==1) {
-                if (fill==0) {
-                    lcd.clearPixel(i,j);
-                } else if (fill==1) {
-                    lcd.setPixel(i,j);
+            if (j>=0) {
+                if(pattern_buffer[i-x][j-y]==1) {
+                    if (fill==0) {
+                        if (j<=47 && i>=0 && i <= 29) {
+                            lcd.clearPixel(i,j);
+                        }
+                    } else if (fill==1) {
+                        if (j<=47 && i>=0 && i <= 29) {
+                            lcd.setPixel(i,j);
+                        }
+                    }
                 }
             }
         }
@@ -146,16 +227,17 @@
 void left_collisionDetect()
 {
     scan();
-    get_pattern(pos_current.type,pos_current.rotation);
-    int left_boundary[6][6];
+    get_pattern(pos.type,pos.rotation);
+    // int left_boundary[6][6];
     // get the left boundary pattern
-    for (int j=0; j<=6; j++) { //
-        for (int i=0; i<=6; i++) {
+    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<=6; k++) {
+                for(int k=i+1; k<=5; k++) {
                     left_boundary[k][j] = 0;
                 }
+                break;
             } else {
                 left_boundary[i][j]=0;
             }
@@ -163,39 +245,47 @@
     }
 
     //check left collision
-    int x = pos_current.x;
-    int y = pos_current.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(left_boundary[i-x][j-y]==1) {
-                if(i == 0) {
-                    left_collision_flag = 1;
-                    left_xMin = 0;
-                } else if (buffer[i-1][j] == 1) {
-                    left_collision_flag = 1;
-                    if (i > left_xMin) {
-                        left_xMin = i;
+    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 (buffer[i-1][j]) {
+                        left_collision_flag = 1;
+                        break;
+                    } else {
+                        left_collision_flag = 0;
                     }
                 }
+                if (left_collision_flag == 1) {
+                    break;
+                }
             }
         }
-
     }
 }
 
+
 void right_collisionDetect()
 {
     scan();
-    get_pattern(pos_current.type,pos_current.rotation);
     int right_boundary[6][6];
+    get_pattern(pos.type,pos.rotation);
     // get the left boundary pattern
-    for (int j=0; j<=6; j++) {
-        for (int i=6; i>=0; i--) {
+    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;
             }
@@ -203,21 +293,26 @@
     }
 
     //check left collision
-    int x = pos_current.x;
-    int y = pos_current.y;
+    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(i == 29) {
-                    right_collision_flag = 1;
-                    right_xMax = 29;
-                } else if (buffer[i+1][j] == 1) {
-                    right_collision_flag = 1;
-                    if(i< right_xMax) {
-                        right_xMax = i;
+                if(j>=0) {
+                    if(i >= 29) {
+                        right_collision_flag = 1;
+                        break;
+                    } else if (buffer[i+1][j] == 1) {
+                        right_collision_flag = 1;
+                        break;
+                    } else {
+                        right_collision_flag = 0;
                     }
                 }
             }
+            if (right_collision_flag == 1) {
+                break;
+            }
         }
 
     }
@@ -226,11 +321,11 @@
 void bottom_collisionDetect()
 {
     scan();
-    get_pattern(pos_current.type,pos_current.rotation);
+    get_pattern(pos.type,pos.rotation);
     int bot_boundary[6][6];
     // get the left boundary pattern
-    for (int i=0; i<=6; i++) {
-        for (int j=6; j>=0; j--) {
+    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=i-1; k>=0; k--) {
@@ -243,8 +338,8 @@
     }
 
     //check left collision
-    int x = pos_current.x;
-    int y = pos_current.y;
+    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(bot_boundary[i-x][j-y]==1) {
@@ -256,9 +351,51 @@
                     if(j< bottom_yMax) {
                         bottom_yMax = j;
                     }
+                } else {
+                    right_collision_flag = 0;
                 }
             }
         }
 
     }
+}
+
+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;
+    }
+
 }
\ No newline at end of file