My ELEC2645 joystick project Tetris Game NAME: JIANWEI CHEN SID: 200879849
Dependencies: N5110 SDFileSystem mbed
main.cpp
- Committer:
- cjw851102
- Date:
- 2016-04-25
- Revision:
- 1:2a758565f691
- Parent:
- 0:12a1972fa0d0
- Child:
- 2:f427089e2bfa
File content as of revision 1:2a758565f691:
#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; int left_boundary[6][6]; void bottom_collisionDetect(); int bottom_yMax = 47; int 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 { 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 100% init_game(); game.attach(&game_isr,0.4); lcd.refresh(); int xOld; calibrateJoystick(); 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(); 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.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) { 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 && i <= 29) { lcd.clearPixel(i,j); } } else if (fill==1) { if (j<=47 && i>=0 && i <= 29) { lcd.setPixel(i,j); } } } } } } } void left_collisionDetect() { scan(); get_pattern(pos.type,pos.rotation); // int left_boundary[6][6]; // 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 (buffer[i-1][j]) { left_collision_flag = 1; break; } else { left_collision_flag = 0; } } if (left_collision_flag == 1) { break; } } } } } void right_collisionDetect() { scan(); 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 (buffer[i+1][j] == 1) { right_collision_flag = 1; break; } else { right_collision_flag = 0; } } } if (right_collision_flag == 1) { break; } } } } void bottom_collisionDetect() { scan(); get_pattern(pos.type,pos.rotation); int bot_boundary[6][6]; // 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=i-1; k>=0; k--) { bot_boundary[i][k] = 0; } } 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; j <= y+5; j++) { if(bot_boundary[i-x][j-y]==1) { if(j == 47) { bottom_collision_flag = 1; bottom_yMax = 47; } else if (buffer[i][j+1] == 1) { right_collision_flag = 1; 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; } }