Emina Smajlovic
/
Tetris
Game
main.cpp
- Committer:
- 2016us_eminasmajlovi
- Date:
- 2018-05-17
- Revision:
- 0:71cf58df0deb
File content as of revision 0:71cf58df0deb:
#include "mbed.h" #include "N5110.h" #include "Joystick.h" #define dp23 P0_0 N5110 lcd(dp4,dp24,dp23,dp25,dp2,dp6,dp18); DigitalIn button(dp9); int score; /** Flag to show left hand side conllision of pattern @note flag = 0 - there is no collision on the left @note flag = 1 - there is collision on the left */ int left_collision_flag = 0; /** Flag to show right hand side conllision of pattern @note flag = 0 - there is no collision @note flag = 1 - there is collision */ int right_collision_flag = 0; /** Flag to show bottom conllision of pattern @note flag = 0 - there is no collision @note flag = 1 - there is collision */ int bottom_collision_flag = 0; /** Flag to show top conllision of pattern @note flag = 0 - there is no collision @note flag = 1 - there is collision */ int top_collision_flag = 0; /** Flag to show if there is pixels set on the 4 pixels distance away from the bottom of pattern @brief if flag = 0, user can pull joystick down to make pattern falling faster @note flag = 0 - there is no collision @note flag = 1 - there is collision */ int fastmove_bottom_collision_flag = 0; /** Flag to show if allow patterns to rotate @note flag = 0 - allow @note flag = 1 - not allow */ int rotation_collision_flag = 0; int pattern_buffer[12][12]; int xOld; int igra = 0; void Pocetak() { lcd.clear(); lcd.printString("Tetris", 10, 0); lcd.printString("-START-", 10, 3); } void nacrtajOblik(int tip, int rotacija, int x, int y) { switch(tip) { case 0: //L if (rotacija == 0) { lcd.drawRect(x, y, 4, 4, 1); lcd.drawRect(x, y+4, 4, 4, 1); lcd.drawRect(x, y+8, 4, 4, 1); lcd.drawRect(x+4, y+8, 4, 4, 1);} else if (rotacija == 1) { lcd.drawRect(x+1, y+1, 3, 3, 1); lcd.drawRect(x+5, y+1, 3, 3, 1); lcd.drawRect(x+9, y+1, 3, 3, 1); lcd.drawRect(x+1, y+5, 3, 3, 1);} else if (rotacija == 2) { lcd.drawRect(x, y, 3, 3, 1); lcd.drawRect(x+4, y, 3, 3, 1); lcd.drawRect(x+4, y+4, 3, 3, 1); lcd.drawRect(x+4, y+8, 3, 3, 1);} else { lcd.drawRect(x+1, y+5, 3, 3, 1); lcd.drawRect(x+5, y+5, 3, 3, 1); lcd.drawRect(x+9, y+5, 3, 3, 1); lcd.drawRect(x+9, y+1, 3, 3, 1);} break; case 1: //O lcd.drawRect(x, y, 4, 4, 1); lcd.drawRect(x, y+4, 4, 4, 1); lcd.drawRect(x+4, y, 4, 4, 1); lcd.drawRect(x+4, y+4, 4, 4, 1); break; } } void obrisiNextOblik() { lcd.drawRect(0,0,12,12,2); } struct Position { float x; float y; int type; int rotation; }; Position pos; int stariTip; void init_game() { //int random = rand()%2; nacrtajOblik(0, 1, 0, 0); //stariTip = random; lcd.drawRect(15, 0, 6, 48, 1); lcd.drawRect(58, 0, 6, 48, 1); lcd.printString("0", 66, 2); lcd.printString("N:", 0, 3); lcd.printString("S:", 66, 0); } bool buttonPressedInGame() { if(button == 0) return true; else return false; } void get_pattern(int tip, int rotacija){ for(int i=pos.x; i<12; i++) { for(int j=pos.y; j<12; j++) { if(lcd.getPixel(i,j) == 0) pattern_buffer[i][j] = 0; else pattern_buffer[i][j] = 1; } } } void left_collisionDetect() { int left_boundary[12][12]; get_pattern(pos.type,pos.rotation); for (int j=0; j<=11; j++) { // for (int i=0; i<=11; i++) { if (pattern_buffer[i][j]==1) { left_boundary[i][j]=1; for(int k=i+1; k<=11; 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<21) { //for all the pattern, when x<0, pattern is on the most LHS of screen left_collision_flag = 1; } else { //check the pixel status away from left boundary for one pixel distance for(int i=x; i <= x+11; i++) { // (x,y) is the left top point of a 6*6 square for(int j=y; j <= y+11; j++) { if(left_boundary[i-x][j-y]==1) { if(i == 0) { // pattern at most LHS of screen left_collision_flag = 1; break; // don't need to check the other pixels at same x, jump out of inner for loop } else if (lcd.getPixel(i-1,j)) { //check one pixel away from left boundary left_collision_flag = 1; break; } else { left_collision_flag = 0; } } } if (left_collision_flag == 1) { break;// jump out of inner for loop } } } } void right_collisionDetect() { int right_boundary[12][12]; get_pattern(pos.type,pos.rotation); for (int j=0; j<=11; j++) { for (int i=11; 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 right collision int x = pos.x; int y = pos.y; for(int i = x; i <= x+11; i++) { // (x,y) is the left top point of a 6*6 square for(int j=y; j <= y+11; j++) { if(right_boundary[i-x][j-y]==1) { if(j>=0) { if(i >= 57) { // most RHS of gaming screen right_collision_flag = 1; break; } else if (lcd.getPixel(i+1,j)) {//check the pixel status away from right boundary for one pixel distance right_collision_flag = 1; break; } else { right_collision_flag = 0; } } } } if (right_collision_flag == 1) { break; } } } void bottom_collisionDetect() { int bot_boundary[12][12]; get_pattern(pos.type,pos.rotation); for (int i=0; i<=11; i++) { for (int j=11; 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 bottom collision int x = pos.x; int y = pos.y; for(int i = x; i <= x+11; i++) { //check from left for(int j=y+11; j >= y; j--) { //check from bottom if (j>=-1) { //start check when pattern fall in the screen if(bot_boundary[i-x][j-y]==1) { if(j >= 47) { // pattern at bottom bottom_collision_flag = 1; break; // jump out of inner for loop } else if (lcd.getPixel(i,j+1)) {//check the pixel status away from bottom boundary for one pixel distance bottom_collision_flag = 1; break; } else { bottom_collision_flag = 0; } } } else { //at bottom of screen bottom_collision_flag = 0; } } if( bottom_collision_flag == 1) { break; // jump out of inner for loop } } } void rotation_collisionDetect() { int rotation = pos.rotation+1; if (rotation>3) { rotation=0; } get_pattern(pos.type,rotation); //check pixel status of upcoming rotation int x = pos.x; int y = pos.y; for(int i = x; i <= x+11; i++) { // (x,y) is the left top point of a 6*6 square for(int j=y; j <= y+11; j++) { if(pattern_buffer[i-x][j-y]==1) { if(i<0) { // out of LHS screen rotation_collision_flag = 1; } else if(lcd.getPixel(i,j)) { // there is pixel set rotation_collision_flag = 1; break; //jump out of inner for loop } else { rotation_collision_flag = 0; } } } if (rotation_collision_flag == 1) { break; //jump out of inner for loop } } } void top_collisionDetect() { if (pos.y==-12) { //pattern is about to fall bottom_collisionDetect(); if (bottom_collision_flag == 1) { //if can't fall top_collision_flag = 1; // top collision } else { top_collision_flag = 0; } } } void fastmove_bottom_collisionDetect() { int bot_boundary[12][12]; get_pattern(pos.type,pos.rotation); // get the bottom boundary pattern for (int i=0; i<=11; i++) { for (int j=11; 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 bottom collision for 4 pixel distance away from bottom boundary int x = pos.x; int y = pos.y; for(int i = x; i <= x+11; i++) { // (x,y) is the left top point of a 6*6 square for(int j=y+11; j >= y; j--) { if (j>=-1) { if(bot_boundary[i-x][j-y]==1) { if(j >= 42) { // pattern is about to fall on the bottom fastmove_bottom_collision_flag = 1; break; } else if (lcd.getPixel(i,j+4)) {//check bottom collision for 4 pixel distance away from bottom boundary 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 cancelLine() { // int linePattern[30][2]; //the pixel setting for one line(30x2 square) int count; // count setting pixels two by two for(int j=1; j<=47; j+=4) { for(int i=22; i<=57; i+=4) { if (lcd.getPixel(i,j)==0) { // there is clear pixel count=0; break; } else if (lcd.getPixel(i,j)) { count++; } } if(count==9) { // one line is filled count=0; // reset the variable count lcd.drawRect(21,j,37,4,2); //clear the line score+=1; // add the score //update the score char scoreBuffer[14]; sprintf(scoreBuffer,"%d",score); lcd.printString(scoreBuffer,42,3); int xp, yp; for (int x=21; x<=56; x+=4) { for (int y=j; y>=0; y-=4) { if (lcd.getPixel(x,y-4) == 0) { xp = x; yp = y; for(int k=xp; k <xp+4; k++) { for(int l=yp; l<yp+4; l++){ lcd.clearPixel(k, l); }} } else { lcd.drawRect(x, y, 3, 3, 1); } } } } } } void brisiStariDio(int x, int y) { for(int i=x; i<x+12; i++) { for(int j=y; j<y+12; j++) { if(pattern_buffer[i-x][j-y] == 0) lcd.clearPixel(i, j); } } lcd.refresh(); } void Tetris() { bool kraj = false; while(1) { if (igra == 0) igra = 1; kraj = buttonPressedInGame(); //check if user press button and get the decision if(kraj) { // exit game break; //jump out of while loop } lcd.printString("OK", 0, 4); pos.type = 1; //get the pattern type obrisiNextOblik(); nacrtajOblik(pos.type,0,1,1); //wait_ms(1000);// draw next pattern on the left hand side of screen if (pos.y >= -11) { // when pattern start falling, clear previous pattern obrisiNextOblik(); } lcd.printString("OK", 0, 5); updateJoystick(); //get the joystick direction top_collisionDetect(); // check if current pattern touch the top if (top_collision_flag == 1) { // if touch the top, finish the game //finishAnimation(); //finish animation lcd.clear(); char scoreBuffer[14]; sprintf(scoreBuffer,"%d",score); lcd.printString("SCORE IS: ",10,2); lcd.printString(scoreBuffer,35,4); lcd.refresh(); wait(3.0); lcd.clear(); //state=0; // back to the main menu break; } //move patterns according to joystick direction switch(joystick.direction) { case UP: // rotation rotation_collision_flag = 0; rotation_collisionDetect(); // check if allow rotation if(rotation_collision_flag == 0) { // allow rotation pos.rotation++; if (pos.rotation>3) { pos.rotation=0; } nacrtajOblik(pos.type,pos.rotation,pos.x,pos.y); } else {// not allow rotation nacrtajOblik(pos.type,pos.rotation,pos.x,pos.y); } break; case DOWN: // faster moving down fastmove_bottom_collision_flag = 0; fastmove_bottom_collisionDetect(); if (fastmove_bottom_collision_flag == 0) {// allow faster move pos.y +=8; // move pattern down by 4 pixels distance nacrtajOblik(pos.type,pos.rotation,pos.x,pos.y); } else { nacrtajOblik(pos.type,pos.rotation,pos.x,pos.y); } break; case RIGHT: // move right right_collision_flag = 0; right_collisionDetect(); // detect right collision if( right_collision_flag == 0) { // allow move right pos.x +=4; nacrtajOblik(pos.type,pos.rotation,pos.x,pos.y); } else { // not allow move right nacrtajOblik(pos.type,pos.rotation,pos.x,pos.y); right_collision_flag = 0; } break; case LEFT: //move left left_collision_flag = 0; left_collisionDetect(); // detect left collision if( left_collision_flag == 0) {// allow move left pos.x -=4; nacrtajOblik(pos.type,pos.rotation,pos.x,pos.y); } else { // not allow move left nacrtajOblik(pos.type,pos.rotation,pos.x,pos.y); left_collision_flag = 0; } break; } xOld = pos.x; //store previous pattern x co-codinate bottom_collisionDetect(); // bottom collision detect if (bottom_collision_flag == 0) { // no collision //brisiStariDio(pos.x, pos.y); pos.y+=4; // keep moving pattern down wait_ms(1000); } else { // bottom collision nacrtajOblik(pos.type,pos.rotation,pos.x,pos.y); // fix pattern cancelLine(); // check filled lines and add score pos.x = 35; // new pattern will fall from the centre pos.y = -12; pos.rotation=0; nacrtajOblik(pos.type, pos.rotation, pos.x, pos.y); obrisiNextOblik(); } brisiStariDio(pos.x, pos.y); lcd.refresh(); } sleep(); // go to sleep mode unless ticker interupt } int main() { while(1) { lcd.init(); // initialise lcd lcd.normalMode(); // normal colour mode lcd.setBrightness(1.0); // put LED backlight on 100% button.mode(PullUp); Pocetak(); wait_ms(1000); lcd.clear(); init_game(); Tetris(); } }