My ELEC2645 joystick project Tetris Game NAME: JIANWEI CHEN SID: 200879849
Dependencies: N5110 SDFileSystem mbed
Diff: main.cpp
- 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