![](/media/cache/group/default_image.jpg.50x50_q85.jpg)
My ELEC2645 joystick project Tetris Game NAME: JIANWEI CHEN SID: 200879849
Dependencies: N5110 SDFileSystem mbed
main.cpp
- Committer:
- cjw851102
- Date:
- 2016-05-01
- Revision:
- 3:5494a0fb3a33
- Parent:
- 2:f427089e2bfa
- Child:
- 4:463abe5f5135
File content as of revision 3:5494a0fb3a33:
#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; 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) { 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(); 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; } } } //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; } } } 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(); } }