My ELEC2645 joystick project Tetris Game NAME: JIANWEI CHEN SID: 200879849
Dependencies: N5110 SDFileSystem mbed
Diff: main.cpp
- Revision:
- 4:463abe5f5135
- Parent:
- 3:5494a0fb3a33
diff -r 5494a0fb3a33 -r 463abe5f5135 main.cpp --- 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(); - } -} - - -