Emina Smajlovic
/
Tetris
Game
Diff: main.cpp
- Revision:
- 0:71cf58df0deb
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu May 17 13:04:23 2018 +0000 @@ -0,0 +1,530 @@ +#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(); + } +} + +