Denis Selimović / Mbed 2 deprecated Tetris

Dependencies:   mbed Tetris

Dependents:   Tetris

Committer:
2019US_DenisSelimovi
Date:
Sat Jun 15 23:11:24 2019 +0000
Revision:
0:59961b55c453
//

Who changed what in which revision?

UserRevisionLine numberNew contents of line
2019US_DenisSelimovi 0:59961b55c453 1 #include "mbed.h"
2019US_DenisSelimovi 0:59961b55c453 2 #include "SPI_TFT_ILI9341.h"
2019US_DenisSelimovi 0:59961b55c453 3 #include "Arial12x12.h"
2019US_DenisSelimovi 0:59961b55c453 4
2019US_DenisSelimovi 0:59961b55c453 5 #define dp23 P0_0
2019US_DenisSelimovi 0:59961b55c453 6
2019US_DenisSelimovi 0:59961b55c453 7 //deklaracija display-a
2019US_DenisSelimovi 0:59961b55c453 8 SPI_TFT_ILI9341 display(dp2, dp1, dp6, dp24, dp23, dp25, "TFT");
2019US_DenisSelimovi 0:59961b55c453 9
2019US_DenisSelimovi 0:59961b55c453 10 //analogni ulazi za joystick
2019US_DenisSelimovi 0:59961b55c453 11 AnalogIn VRx(dp11);
2019US_DenisSelimovi 0:59961b55c453 12 AnalogIn VRy(dp10);
2019US_DenisSelimovi 0:59961b55c453 13 //taster na joysticku za rotaciju
2019US_DenisSelimovi 0:59961b55c453 14 InterruptIn taster(dp9);
2019US_DenisSelimovi 0:59961b55c453 15
2019US_DenisSelimovi 0:59961b55c453 16 AnalogIn random(dp13); //analogni ulaz za generisanje random vrijednosti
2019US_DenisSelimovi 0:59961b55c453 17
2019US_DenisSelimovi 0:59961b55c453 18 //ticker za spustanje figure
2019US_DenisSelimovi 0:59961b55c453 19 //timer za debouncing tastera na joysticku
2019US_DenisSelimovi 0:59961b55c453 20 Ticker game, joystick;
2019US_DenisSelimovi 0:59961b55c453 21 Timer debounceTaster;
2019US_DenisSelimovi 0:59961b55c453 22
2019US_DenisSelimovi 0:59961b55c453 23
2019US_DenisSelimovi 0:59961b55c453 24 unsigned char level = 0; //mora biti tipa usigned char jer inače se može desiti da level bude manji od 0, a i da ne trošimo memoriju
2019US_DenisSelimovi 0:59961b55c453 25 const float delays[3] = {1.2, 1, 0.7}; //svakih koliko se spusti jedan red, ovo provjeriti da li je presporo ili prebrzo, ovisi o levelu
2019US_DenisSelimovi 0:59961b55c453 26 char leftBoundary = 1, rightBoundary = 5, downBoundary = 1, upBoundary = 5;// sada je ovo tipa char
2019US_DenisSelimovi 0:59961b55c453 27 unsigned int score = 0; //stavio sam ovo unsigned int za veći opseg, mada je jako teško da se i int premaši, ali nmvz
2019US_DenisSelimovi 0:59961b55c453 28 bool firstTime = true; //ako je prvi put, figura se crta u Tickeru
2019US_DenisSelimovi 0:59961b55c453 29 bool gameStarted = false;
2019US_DenisSelimovi 0:59961b55c453 30 unsigned char nextFigure = 1; //ovo je sad globalna varijabla, da bi mogli unaprijed generisati sljedeću figuru radi prikaza
2019US_DenisSelimovi 0:59961b55c453 31
2019US_DenisSelimovi 0:59961b55c453 32
2019US_DenisSelimovi 0:59961b55c453 33 //white - no figure
2019US_DenisSelimovi 0:59961b55c453 34 //I - BLUE
2019US_DenisSelimovi 0:59961b55c453 35 //O - YELLOW
2019US_DenisSelimovi 0:59961b55c453 36 //T - PURPLE
2019US_DenisSelimovi 0:59961b55c453 37 //S - GREEN
2019US_DenisSelimovi 0:59961b55c453 38 //Z - RED
2019US_DenisSelimovi 0:59961b55c453 39 //J - MAROON
2019US_DenisSelimovi 0:59961b55c453 40 //L - ORANGE
2019US_DenisSelimovi 0:59961b55c453 41 const int colors[8] = {White, Blue, Yellow, Purple, Green, Red, Maroon, Orange};
2019US_DenisSelimovi 0:59961b55c453 42 const short DIMENSION = 16;
2019US_DenisSelimovi 0:59961b55c453 43 const short DIMENSION_NEXT = 12;
2019US_DenisSelimovi 0:59961b55c453 44 short board[20][10] = {0}; //matrica boja, 0 - 7 indeksi boja
2019US_DenisSelimovi 0:59961b55c453 45
2019US_DenisSelimovi 0:59961b55c453 46 short figuresX[7][4] = {{0,0,0,0}, {0,0,1,1}, {0,1,1,1}, {1,1,0,0}, {0,1,0,1}, {1,1,1,0}, {1,1,1,0}};
2019US_DenisSelimovi 0:59961b55c453 47 short figuresY[7][4] = {{0,1,2,3}, {1,0,0,1}, {1,1,2,0}, {0,1,1,2}, {0,1,1,2}, {2,1,0,0}, {0,1,2,2}};
2019US_DenisSelimovi 0:59961b55c453 48
2019US_DenisSelimovi 0:59961b55c453 49 unsigned int GenerateRandomSeed() {
2019US_DenisSelimovi 0:59961b55c453 50 unsigned int randomNumber = 0;
2019US_DenisSelimovi 0:59961b55c453 51 for(int i = 0; i <= 32; i += 2) {
2019US_DenisSelimovi 0:59961b55c453 52 randomNumber += ((random.read_u16() % 3) << i);
2019US_DenisSelimovi 0:59961b55c453 53 wait_us(10);
2019US_DenisSelimovi 0:59961b55c453 54 }
2019US_DenisSelimovi 0:59961b55c453 55 return randomNumber;
2019US_DenisSelimovi 0:59961b55c453 56 }
2019US_DenisSelimovi 0:59961b55c453 57
2019US_DenisSelimovi 0:59961b55c453 58 void Init() {
2019US_DenisSelimovi 0:59961b55c453 59 //ovo su zajedničke osobine za sve prikaze na display-u
2019US_DenisSelimovi 0:59961b55c453 60 //nikad se ne mijenjaju i pozvat ćemo je jednom prije petlje
2019US_DenisSelimovi 0:59961b55c453 61 display.claim(stdout);
2019US_DenisSelimovi 0:59961b55c453 62 display.set_orientation(2); // 2 ili 0, zavisi kako okrenemo display, provjerit ćemo na labu kako nam je najlakše povezat
2019US_DenisSelimovi 0:59961b55c453 63 display.set_font((unsigned char*) Arial12x12);
2019US_DenisSelimovi 0:59961b55c453 64 }
2019US_DenisSelimovi 0:59961b55c453 65
2019US_DenisSelimovi 0:59961b55c453 66
2019US_DenisSelimovi 0:59961b55c453 67 void ShowScore() {
2019US_DenisSelimovi 0:59961b55c453 68 //pomocna funkcija za prikazivanje score-a
2019US_DenisSelimovi 0:59961b55c453 69 display.fillrect(165, 20, 235, 50, White); //popunimo pravugaonik da obrišemo stari score
2019US_DenisSelimovi 0:59961b55c453 70 display.locate(200, 35); //valjda je na sredini pravougaonika
2019US_DenisSelimovi 0:59961b55c453 71 printf("%d", score);
2019US_DenisSelimovi 0:59961b55c453 72 }
2019US_DenisSelimovi 0:59961b55c453 73
2019US_DenisSelimovi 0:59961b55c453 74 void ShowNextFigure() {
2019US_DenisSelimovi 0:59961b55c453 75 //prikaz sljedeće figure koristeći pomoćnu varijablu nextFigure
2019US_DenisSelimovi 0:59961b55c453 76 display.fillrect(165, 70, 235, 120, White);
2019US_DenisSelimovi 0:59961b55c453 77 int upperLeftX = 176, upperLeftY = 83;
2019US_DenisSelimovi 0:59961b55c453 78 for(int i = 0; i < 4; i++) {
2019US_DenisSelimovi 0:59961b55c453 79 int x = upperLeftX + DIMENSION_NEXT * figuresY[nextFigure - 1][i], y = upperLeftY + DIMENSION_NEXT * figuresX[nextFigure - 1][i];
2019US_DenisSelimovi 0:59961b55c453 80 display.fillrect(x, y, x + DIMENSION_NEXT, y + DIMENSION_NEXT, colors[nextFigure]);
2019US_DenisSelimovi 0:59961b55c453 81 display.rect(x, y, x + DIMENSION_NEXT, y + DIMENSION_NEXT, Black);
2019US_DenisSelimovi 0:59961b55c453 82 }
2019US_DenisSelimovi 0:59961b55c453 83 }
2019US_DenisSelimovi 0:59961b55c453 84
2019US_DenisSelimovi 0:59961b55c453 85 //funkcija za crtanje cursora za odabir levela
2019US_DenisSelimovi 0:59961b55c453 86 void DrawCursor(int color, unsigned char lev) {
2019US_DenisSelimovi 0:59961b55c453 87 display.fillrect(60, (lev + 1) * 100 - 50, 72, (lev + 1) * 100 - 50 + 12, color);
2019US_DenisSelimovi 0:59961b55c453 88 }
2019US_DenisSelimovi 0:59961b55c453 89
2019US_DenisSelimovi 0:59961b55c453 90 void ShowLevelMenu() {
2019US_DenisSelimovi 0:59961b55c453 91 //ovdje inicijalizujemo display
2019US_DenisSelimovi 0:59961b55c453 92 display.cls(); // brišemo prethodno
2019US_DenisSelimovi 0:59961b55c453 93 display.background(Black);
2019US_DenisSelimovi 0:59961b55c453 94 display.foreground(White);
2019US_DenisSelimovi 0:59961b55c453 95 display.locate(80, 50);
2019US_DenisSelimovi 0:59961b55c453 96 printf("LEVEL 1");
2019US_DenisSelimovi 0:59961b55c453 97 display.locate(80, 150);
2019US_DenisSelimovi 0:59961b55c453 98 printf("LEVEL 2");
2019US_DenisSelimovi 0:59961b55c453 99 display.locate(80, 250);
2019US_DenisSelimovi 0:59961b55c453 100 printf("LEVEL 3");
2019US_DenisSelimovi 0:59961b55c453 101 DrawCursor(White, level);
2019US_DenisSelimovi 0:59961b55c453 102 }
2019US_DenisSelimovi 0:59961b55c453 103
2019US_DenisSelimovi 0:59961b55c453 104 void ReadJoystickForLevel(){
2019US_DenisSelimovi 0:59961b55c453 105 unsigned char old = level;
2019US_DenisSelimovi 0:59961b55c453 106 if(VRy < downBoundary / 6.0){
2019US_DenisSelimovi 0:59961b55c453 107 upBoundary = 4;
2019US_DenisSelimovi 0:59961b55c453 108 (level == 0) ? level = 2 : level--;
2019US_DenisSelimovi 0:59961b55c453 109 }
2019US_DenisSelimovi 0:59961b55c453 110 else if(VRy > upBoundary / 6.0){
2019US_DenisSelimovi 0:59961b55c453 111 //ne radi ona prethodna varijanta jer % vraća i negastivni rezultat
2019US_DenisSelimovi 0:59961b55c453 112 //to što ne koristimo unsigned tip ne pomaže jer će doći do overflow-a
2019US_DenisSelimovi 0:59961b55c453 113 downBoundary = 2;
2019US_DenisSelimovi 0:59961b55c453 114 level = (level + 1) % 3;
2019US_DenisSelimovi 0:59961b55c453 115 }
2019US_DenisSelimovi 0:59961b55c453 116 else {
2019US_DenisSelimovi 0:59961b55c453 117 downBoundary = 1;
2019US_DenisSelimovi 0:59961b55c453 118 upBoundary = 5;
2019US_DenisSelimovi 0:59961b55c453 119 }
2019US_DenisSelimovi 0:59961b55c453 120 DrawCursor(Black, old); //na prethodni level popunimo bojom pozadine
2019US_DenisSelimovi 0:59961b55c453 121 DrawCursor(White, level); //na novi level popunimo bijelom bojom - pozadina je crna
2019US_DenisSelimovi 0:59961b55c453 122 //koristio sam fillrect, jer njega svakako moramo koristiti, jer možda budemo morali da brišemo fillcircle iz biblioteke
2019US_DenisSelimovi 0:59961b55c453 123 }
2019US_DenisSelimovi 0:59961b55c453 124
2019US_DenisSelimovi 0:59961b55c453 125 void EndPlay() {
2019US_DenisSelimovi 0:59961b55c453 126 joystick.detach();
2019US_DenisSelimovi 0:59961b55c453 127 score = 0;
2019US_DenisSelimovi 0:59961b55c453 128 firstTime = true;
2019US_DenisSelimovi 0:59961b55c453 129 gameStarted = false;
2019US_DenisSelimovi 0:59961b55c453 130 for(int i = 0; i < 20; i++) {
2019US_DenisSelimovi 0:59961b55c453 131 for(int j = 0; j < 10; j++) {
2019US_DenisSelimovi 0:59961b55c453 132 board[i][j] = 0;
2019US_DenisSelimovi 0:59961b55c453 133 }
2019US_DenisSelimovi 0:59961b55c453 134 }
2019US_DenisSelimovi 0:59961b55c453 135 ShowLevelMenu();
2019US_DenisSelimovi 0:59961b55c453 136 joystick.attach(&ReadJoystickForLevel, 0.3);
2019US_DenisSelimovi 0:59961b55c453 137 }
2019US_DenisSelimovi 0:59961b55c453 138
2019US_DenisSelimovi 0:59961b55c453 139 void StartGame()
2019US_DenisSelimovi 0:59961b55c453 140 {
2019US_DenisSelimovi 0:59961b55c453 141 display.cls(); // brišemo ShowLevelMenu
2019US_DenisSelimovi 0:59961b55c453 142 display.background(White);
2019US_DenisSelimovi 0:59961b55c453 143 display.foreground(Black);
2019US_DenisSelimovi 0:59961b55c453 144 display.fillrect(0, 0, 160, 320, White);
2019US_DenisSelimovi 0:59961b55c453 145 display.fillrect(160, 0, 240, 320, Black); //dio za prikazivanje rezultata će biti crni pravougaonik, a tabla je bijeli
2019US_DenisSelimovi 0:59961b55c453 146 ShowScore();
2019US_DenisSelimovi 0:59961b55c453 147 }
2019US_DenisSelimovi 0:59961b55c453 148
2019US_DenisSelimovi 0:59961b55c453 149 void copyCoordinates(short X[], short Y[], unsigned char index)
2019US_DenisSelimovi 0:59961b55c453 150 {
2019US_DenisSelimovi 0:59961b55c453 151 //umjesto one prošle metode za kopiranje, ova prima index, čisto da nam olakša život
2019US_DenisSelimovi 0:59961b55c453 152 for(int i = 0; i < 4; i++) {
2019US_DenisSelimovi 0:59961b55c453 153 X[i] = figuresX[index][i];
2019US_DenisSelimovi 0:59961b55c453 154 Y[i] = figuresY[index][i];
2019US_DenisSelimovi 0:59961b55c453 155 }
2019US_DenisSelimovi 0:59961b55c453 156 }
2019US_DenisSelimovi 0:59961b55c453 157
2019US_DenisSelimovi 0:59961b55c453 158 bool BottomEdge(int x){
2019US_DenisSelimovi 0:59961b55c453 159 return x > 19;
2019US_DenisSelimovi 0:59961b55c453 160 }
2019US_DenisSelimovi 0:59961b55c453 161
2019US_DenisSelimovi 0:59961b55c453 162 bool LeftEdge(int y){
2019US_DenisSelimovi 0:59961b55c453 163 return y < 0;
2019US_DenisSelimovi 0:59961b55c453 164 }
2019US_DenisSelimovi 0:59961b55c453 165
2019US_DenisSelimovi 0:59961b55c453 166 bool RightEdge(int y){
2019US_DenisSelimovi 0:59961b55c453 167 return y > 9;
2019US_DenisSelimovi 0:59961b55c453 168 }
2019US_DenisSelimovi 0:59961b55c453 169
2019US_DenisSelimovi 0:59961b55c453 170 bool OutOfBounds(int y, int x){
2019US_DenisSelimovi 0:59961b55c453 171 return y < 0 || y > 9 || x > 19;
2019US_DenisSelimovi 0:59961b55c453 172 }
2019US_DenisSelimovi 0:59961b55c453 173
2019US_DenisSelimovi 0:59961b55c453 174 void PutBorders(short x, short y) {
2019US_DenisSelimovi 0:59961b55c453 175 for(int i = x - 1; i <= x + 1; i++) {
2019US_DenisSelimovi 0:59961b55c453 176 for(int j = y - 1; j <= y + 1; j++) {
2019US_DenisSelimovi 0:59961b55c453 177 if(i < 0 || i > 9 || j < 0 || j > 19 || board[j][i] == 0) continue;
2019US_DenisSelimovi 0:59961b55c453 178 display.rect(i * DIMENSION, j * DIMENSION, (i + 1) * DIMENSION, (j + 1) * DIMENSION, Black);
2019US_DenisSelimovi 0:59961b55c453 179 }
2019US_DenisSelimovi 0:59961b55c453 180 }
2019US_DenisSelimovi 0:59961b55c453 181 }
2019US_DenisSelimovi 0:59961b55c453 182
2019US_DenisSelimovi 0:59961b55c453 183 class Tetromino{
2019US_DenisSelimovi 0:59961b55c453 184 private:
2019US_DenisSelimovi 0:59961b55c453 185 short X[4];
2019US_DenisSelimovi 0:59961b55c453 186 short Y[4];
2019US_DenisSelimovi 0:59961b55c453 187 short boardX, boardY;
2019US_DenisSelimovi 0:59961b55c453 188 unsigned char colorIndex;//dodao sam colorIndex zasad, jer nema drugog načina da popunimo matricu sa indeksima boja
2019US_DenisSelimovi 0:59961b55c453 189 //ovo je najbezbolnija varijanta što se memorije tiče
2019US_DenisSelimovi 0:59961b55c453 190 public:
2019US_DenisSelimovi 0:59961b55c453 191 Tetromino(){
2019US_DenisSelimovi 0:59961b55c453 192 unsigned char r = rand() % 7 + 1;
2019US_DenisSelimovi 0:59961b55c453 193 Initialize(r);
2019US_DenisSelimovi 0:59961b55c453 194 }
2019US_DenisSelimovi 0:59961b55c453 195
2019US_DenisSelimovi 0:59961b55c453 196 Tetromino(unsigned char colorIndex) {
2019US_DenisSelimovi 0:59961b55c453 197 Initialize(colorIndex);
2019US_DenisSelimovi 0:59961b55c453 198 }
2019US_DenisSelimovi 0:59961b55c453 199
2019US_DenisSelimovi 0:59961b55c453 200 void Initialize(unsigned char colorIndex) {
2019US_DenisSelimovi 0:59961b55c453 201 Tetromino::colorIndex = colorIndex;
2019US_DenisSelimovi 0:59961b55c453 202 boardX = 0;
2019US_DenisSelimovi 0:59961b55c453 203 boardY = 4; //3,4 ili 5 najbolje da vidimo kad imamo display
2019US_DenisSelimovi 0:59961b55c453 204 copyCoordinates(X, Y, colorIndex - 1);
2019US_DenisSelimovi 0:59961b55c453 205 }
2019US_DenisSelimovi 0:59961b55c453 206
2019US_DenisSelimovi 0:59961b55c453 207 void Rotate(){
2019US_DenisSelimovi 0:59961b55c453 208 short pivotX = X[1], pivotY = Y[1];
2019US_DenisSelimovi 0:59961b55c453 209 //prvi elemnti u matrici su pivoti oko koje rotiramo
2019US_DenisSelimovi 0:59961b55c453 210
2019US_DenisSelimovi 0:59961b55c453 211 short newX[4]; //pozicije blokova nakon rotiranja ako sve bude ok
2019US_DenisSelimovi 0:59961b55c453 212 short newY[4];
2019US_DenisSelimovi 0:59961b55c453 213
2019US_DenisSelimovi 0:59961b55c453 214 for(int i = 0; i < 4; i++){
2019US_DenisSelimovi 0:59961b55c453 215 short tmp = X[i], tmp2 = Y[i];
2019US_DenisSelimovi 0:59961b55c453 216 newX[i] = pivotX + pivotY - tmp2;
2019US_DenisSelimovi 0:59961b55c453 217 newY[i] = tmp + pivotX - pivotY;
2019US_DenisSelimovi 0:59961b55c453 218
2019US_DenisSelimovi 0:59961b55c453 219 if(OutOfBounds(boardY + newY[i], boardX + newX[i]) || board[boardX + newX[i]][boardY + newY[i]] != 0) return;
2019US_DenisSelimovi 0:59961b55c453 220 }
2019US_DenisSelimovi 0:59961b55c453 221 DeleteFigure();
2019US_DenisSelimovi 0:59961b55c453 222 for(int i = 0; i < 4; i++){
2019US_DenisSelimovi 0:59961b55c453 223 X[i] = newX[i];
2019US_DenisSelimovi 0:59961b55c453 224 Y[i] = newY[i];
2019US_DenisSelimovi 0:59961b55c453 225 }
2019US_DenisSelimovi 0:59961b55c453 226 DrawFigure();
2019US_DenisSelimovi 0:59961b55c453 227 }
2019US_DenisSelimovi 0:59961b55c453 228
2019US_DenisSelimovi 0:59961b55c453 229 void DrawFigure() {
2019US_DenisSelimovi 0:59961b55c453 230 for(int i = 0; i < 4; i++) {
2019US_DenisSelimovi 0:59961b55c453 231 //display je deklarisani display logy iz biblioteke one
2019US_DenisSelimovi 0:59961b55c453 232 //računamo gornji lijevi pixel po x i y
2019US_DenisSelimovi 0:59961b55c453 233 //donji desni dobijemo kad dodamo DIMENZIJU
2019US_DenisSelimovi 0:59961b55c453 234 //stavio sam 16 za početak, možemo se opet skontati na labu
2019US_DenisSelimovi 0:59961b55c453 235 //ovo pretpostavlja da nema margina, mogu se lagano dodati uz neku konstantu kao offset
2019US_DenisSelimovi 0:59961b55c453 236 int upperLeftX = (boardX + X[i]) * DIMENSION, upperLeftY = (boardY + Y[i]) * DIMENSION;
2019US_DenisSelimovi 0:59961b55c453 237 display.fillrect( upperLeftY, upperLeftX, upperLeftY + DIMENSION, upperLeftX + DIMENSION, colors[colorIndex]);
2019US_DenisSelimovi 0:59961b55c453 238 //ovo boji granice blokova u crno, možemo skloniti ako ti se ne sviđa
2019US_DenisSelimovi 0:59961b55c453 239 display.rect( upperLeftY, upperLeftX, upperLeftY + DIMENSION, upperLeftX + DIMENSION, Black);
2019US_DenisSelimovi 0:59961b55c453 240 }
2019US_DenisSelimovi 0:59961b55c453 241 }
2019US_DenisSelimovi 0:59961b55c453 242
2019US_DenisSelimovi 0:59961b55c453 243 void DeleteFigure() {
2019US_DenisSelimovi 0:59961b55c453 244 for(int i = 0; i < 4; i++) {
2019US_DenisSelimovi 0:59961b55c453 245 //ista logika kao u DrawFigure, samo popunjavamo sve blokove sa bijelim pravougaonicima
2019US_DenisSelimovi 0:59961b55c453 246 short upperLeftX = (boardX + X[i]) * DIMENSION, upperLeftY = (boardY + Y[i]) * DIMENSION;
2019US_DenisSelimovi 0:59961b55c453 247 display.fillrect( upperLeftY, upperLeftX, upperLeftY + DIMENSION, upperLeftX + DIMENSION, White);
2019US_DenisSelimovi 0:59961b55c453 248 PutBorders(upperLeftY, upperLeftX);
2019US_DenisSelimovi 0:59961b55c453 249 }
2019US_DenisSelimovi 0:59961b55c453 250 }
2019US_DenisSelimovi 0:59961b55c453 251
2019US_DenisSelimovi 0:59961b55c453 252 void OnAttached() {
2019US_DenisSelimovi 0:59961b55c453 253 //metoda se poziva kad figura prestanje da se krece
2019US_DenisSelimovi 0:59961b55c453 254 //popunimo matricu indeksom boje
2019US_DenisSelimovi 0:59961b55c453 255 for(int i = 0; i < 4; i++) {
2019US_DenisSelimovi 0:59961b55c453 256 board[boardX + X[i]][boardY + Y[i]] = colorIndex;
2019US_DenisSelimovi 0:59961b55c453 257 //btw board bi mogao biti niz tipa unsigned char, ali to ćemo vidjet kasnije
2019US_DenisSelimovi 0:59961b55c453 258 }
2019US_DenisSelimovi 0:59961b55c453 259 }
2019US_DenisSelimovi 0:59961b55c453 260
2019US_DenisSelimovi 0:59961b55c453 261 bool MoveDown(char delta = 1){
2019US_DenisSelimovi 0:59961b55c453 262 if(!InCollisionDown(delta)){
2019US_DenisSelimovi 0:59961b55c453 263 DeleteFigure();
2019US_DenisSelimovi 0:59961b55c453 264 boardX+=delta;
2019US_DenisSelimovi 0:59961b55c453 265 DrawFigure();
2019US_DenisSelimovi 0:59961b55c453 266 return true;
2019US_DenisSelimovi 0:59961b55c453 267 }
2019US_DenisSelimovi 0:59961b55c453 268
2019US_DenisSelimovi 0:59961b55c453 269 return false;
2019US_DenisSelimovi 0:59961b55c453 270 }
2019US_DenisSelimovi 0:59961b55c453 271
2019US_DenisSelimovi 0:59961b55c453 272 void MoveLeft(){
2019US_DenisSelimovi 0:59961b55c453 273 if(!InCollisionLeft()){
2019US_DenisSelimovi 0:59961b55c453 274 DeleteFigure();
2019US_DenisSelimovi 0:59961b55c453 275 boardY--;
2019US_DenisSelimovi 0:59961b55c453 276 DrawFigure();
2019US_DenisSelimovi 0:59961b55c453 277 }
2019US_DenisSelimovi 0:59961b55c453 278 }
2019US_DenisSelimovi 0:59961b55c453 279
2019US_DenisSelimovi 0:59961b55c453 280 void MoveRight(){
2019US_DenisSelimovi 0:59961b55c453 281 if(!InCollisionRight()){
2019US_DenisSelimovi 0:59961b55c453 282 DeleteFigure();
2019US_DenisSelimovi 0:59961b55c453 283 boardY++;
2019US_DenisSelimovi 0:59961b55c453 284 DrawFigure();
2019US_DenisSelimovi 0:59961b55c453 285 }
2019US_DenisSelimovi 0:59961b55c453 286 }
2019US_DenisSelimovi 0:59961b55c453 287
2019US_DenisSelimovi 0:59961b55c453 288 void SoftDrop() {
2019US_DenisSelimovi 0:59961b55c453 289 //ovo je funkcija za soft drop
2019US_DenisSelimovi 0:59961b55c453 290 //obrisemo figuru, postavimo novu poziciju dva reda ispod, nacrtamo figuru
2019US_DenisSelimovi 0:59961b55c453 291 DeleteFigure();
2019US_DenisSelimovi 0:59961b55c453 292 MoveDown(2);
2019US_DenisSelimovi 0:59961b55c453 293 DrawFigure();
2019US_DenisSelimovi 0:59961b55c453 294 //treba još vidjeti koje izmjene u tickeru trebaju
2019US_DenisSelimovi 0:59961b55c453 295 score += 2 * (level +1); //prema igrici koju smo igrali, dobije se 14 poena kad se uradi hard drop
2019US_DenisSelimovi 0:59961b55c453 296 ShowScore();
2019US_DenisSelimovi 0:59961b55c453 297 }
2019US_DenisSelimovi 0:59961b55c453 298
2019US_DenisSelimovi 0:59961b55c453 299
2019US_DenisSelimovi 0:59961b55c453 300 bool InCollisionDown(char delta = 1){
2019US_DenisSelimovi 0:59961b55c453 301 int newX, newY; //da bi bilo citljivije
2019US_DenisSelimovi 0:59961b55c453 302
2019US_DenisSelimovi 0:59961b55c453 303 for(int i = 0; i < 4; i++){
2019US_DenisSelimovi 0:59961b55c453 304 newX = boardX + X[i] + delta;
2019US_DenisSelimovi 0:59961b55c453 305 newY = boardY + Y[i];
2019US_DenisSelimovi 0:59961b55c453 306
2019US_DenisSelimovi 0:59961b55c453 307 if(BottomEdge(newX) || board[newX][newY] != 0){
2019US_DenisSelimovi 0:59961b55c453 308 return true;
2019US_DenisSelimovi 0:59961b55c453 309 }
2019US_DenisSelimovi 0:59961b55c453 310 //jedna figura je u koliziji ako
2019US_DenisSelimovi 0:59961b55c453 311 //pozicija na koju zelimo da pomjerimo bilo koji blok dotakne dno ili lijevu ili desnu ivicu ekrana
2019US_DenisSelimovi 0:59961b55c453 312 //ili ako je pozicija na koju zelimo da pomjerimo bilo koji od blokova vec zauzeta a da nije dio figure prije pomijeranja
2019US_DenisSelimovi 0:59961b55c453 313 }
2019US_DenisSelimovi 0:59961b55c453 314
2019US_DenisSelimovi 0:59961b55c453 315 return false;
2019US_DenisSelimovi 0:59961b55c453 316 }
2019US_DenisSelimovi 0:59961b55c453 317
2019US_DenisSelimovi 0:59961b55c453 318 bool InCollisionLeft(){
2019US_DenisSelimovi 0:59961b55c453 319 int newX, newY;
2019US_DenisSelimovi 0:59961b55c453 320
2019US_DenisSelimovi 0:59961b55c453 321 for(int i = 0; i < 4; i++){
2019US_DenisSelimovi 0:59961b55c453 322 newX = boardX + X[i];
2019US_DenisSelimovi 0:59961b55c453 323 newY = boardY + Y[i] - 1;
2019US_DenisSelimovi 0:59961b55c453 324
2019US_DenisSelimovi 0:59961b55c453 325 if(LeftEdge(newY) || board[newX][newY] != 0){
2019US_DenisSelimovi 0:59961b55c453 326 return true;
2019US_DenisSelimovi 0:59961b55c453 327 }
2019US_DenisSelimovi 0:59961b55c453 328 }
2019US_DenisSelimovi 0:59961b55c453 329
2019US_DenisSelimovi 0:59961b55c453 330 return false;
2019US_DenisSelimovi 0:59961b55c453 331 }
2019US_DenisSelimovi 0:59961b55c453 332
2019US_DenisSelimovi 0:59961b55c453 333
2019US_DenisSelimovi 0:59961b55c453 334 bool InCollisionRight(){
2019US_DenisSelimovi 0:59961b55c453 335 int newX, newY;
2019US_DenisSelimovi 0:59961b55c453 336
2019US_DenisSelimovi 0:59961b55c453 337 for(int i = 0; i < 4; i++){
2019US_DenisSelimovi 0:59961b55c453 338 newX = boardX + X[i];
2019US_DenisSelimovi 0:59961b55c453 339 newY = boardY + Y[i] + 1;
2019US_DenisSelimovi 0:59961b55c453 340
2019US_DenisSelimovi 0:59961b55c453 341 if(RightEdge(newY) || board[newX][newY] != 0){
2019US_DenisSelimovi 0:59961b55c453 342 return true;
2019US_DenisSelimovi 0:59961b55c453 343 }
2019US_DenisSelimovi 0:59961b55c453 344 }
2019US_DenisSelimovi 0:59961b55c453 345
2019US_DenisSelimovi 0:59961b55c453 346 return false;
2019US_DenisSelimovi 0:59961b55c453 347 }
2019US_DenisSelimovi 0:59961b55c453 348 };
2019US_DenisSelimovi 0:59961b55c453 349
2019US_DenisSelimovi 0:59961b55c453 350
2019US_DenisSelimovi 0:59961b55c453 351 Tetromino currentTetromino;
2019US_DenisSelimovi 0:59961b55c453 352
2019US_DenisSelimovi 0:59961b55c453 353 void ReadJoystickForFigure() {
2019US_DenisSelimovi 0:59961b55c453 354 if(VRx < leftBoundary / 6.0) {
2019US_DenisSelimovi 0:59961b55c453 355 leftBoundary = 2;
2019US_DenisSelimovi 0:59961b55c453 356 currentTetromino.MoveLeft();
2019US_DenisSelimovi 0:59961b55c453 357 }
2019US_DenisSelimovi 0:59961b55c453 358 else if(VRx > rightBoundary / 6.0) {
2019US_DenisSelimovi 0:59961b55c453 359 rightBoundary = 4;
2019US_DenisSelimovi 0:59961b55c453 360 currentTetromino.MoveRight();
2019US_DenisSelimovi 0:59961b55c453 361 }
2019US_DenisSelimovi 0:59961b55c453 362 else if(VRy < downBoundary / 6.0) {
2019US_DenisSelimovi 0:59961b55c453 363 downBoundary = 2;
2019US_DenisSelimovi 0:59961b55c453 364 }
2019US_DenisSelimovi 0:59961b55c453 365 else if(VRy > upBoundary / 6.0) {
2019US_DenisSelimovi 0:59961b55c453 366 upBoundary = 4;
2019US_DenisSelimovi 0:59961b55c453 367 currentTetromino.SoftDrop();
2019US_DenisSelimovi 0:59961b55c453 368 }
2019US_DenisSelimovi 0:59961b55c453 369 else {
2019US_DenisSelimovi 0:59961b55c453 370 leftBoundary = 1;
2019US_DenisSelimovi 0:59961b55c453 371 rightBoundary = 5;
2019US_DenisSelimovi 0:59961b55c453 372 downBoundary = 1;
2019US_DenisSelimovi 0:59961b55c453 373 upBoundary = 5;
2019US_DenisSelimovi 0:59961b55c453 374 }
2019US_DenisSelimovi 0:59961b55c453 375 }
2019US_DenisSelimovi 0:59961b55c453 376
2019US_DenisSelimovi 0:59961b55c453 377
2019US_DenisSelimovi 0:59961b55c453 378 void CheckLines(short &firstLine, short &numberOfLines)
2019US_DenisSelimovi 0:59961b55c453 379 {
2019US_DenisSelimovi 0:59961b55c453 380 //vraća preko reference prvu liniju koja je popunjena do kraja, kao i takvih linija
2019US_DenisSelimovi 0:59961b55c453 381 firstLine = -1; //postavljen na -1 jer ako nema linija koje treba brisati ispod u UpdateBoard neće se ući u petlju
2019US_DenisSelimovi 0:59961b55c453 382 numberOfLines = 0;
2019US_DenisSelimovi 0:59961b55c453 383 for(int i = 19; i >= 0; i--) {
2019US_DenisSelimovi 0:59961b55c453 384 short temp = 0;
2019US_DenisSelimovi 0:59961b55c453 385 for(int j = 0; j < 10; j++) {
2019US_DenisSelimovi 0:59961b55c453 386 if(board[i][j] == 0) {
2019US_DenisSelimovi 0:59961b55c453 387 if(numberOfLines > 0) return;
2019US_DenisSelimovi 0:59961b55c453 388 break;
2019US_DenisSelimovi 0:59961b55c453 389 }//ako je makar jedna bijela, prekida se brojanje
2019US_DenisSelimovi 0:59961b55c453 390 temp++;
2019US_DenisSelimovi 0:59961b55c453 391 }
2019US_DenisSelimovi 0:59961b55c453 392 if(temp == 10) { //ako je temo došao do 10, niti jedna bijela - puna linija
2019US_DenisSelimovi 0:59961b55c453 393 numberOfLines++;
2019US_DenisSelimovi 0:59961b55c453 394 if(firstLine == -1) firstLine = i; //ovo mijenjamo samo prvi put
2019US_DenisSelimovi 0:59961b55c453 395 }
2019US_DenisSelimovi 0:59961b55c453 396 }
2019US_DenisSelimovi 0:59961b55c453 397 }
2019US_DenisSelimovi 0:59961b55c453 398
2019US_DenisSelimovi 0:59961b55c453 399 unsigned int UpdateScore (short numOfLines){
2019US_DenisSelimovi 0:59961b55c453 400 unsigned int newIncrement = 0;
2019US_DenisSelimovi 0:59961b55c453 401 switch(numOfLines) {
2019US_DenisSelimovi 0:59961b55c453 402 case 1 : newIncrement = 40; break;
2019US_DenisSelimovi 0:59961b55c453 403 case 2 : newIncrement = 100; break;
2019US_DenisSelimovi 0:59961b55c453 404 case 3 : newIncrement = 300; break;
2019US_DenisSelimovi 0:59961b55c453 405 case 4 : newIncrement = 1200; break;
2019US_DenisSelimovi 0:59961b55c453 406 default : newIncrement = 0; break; //update funkcije za score, još sam vratio ovo na 0
2019US_DenisSelimovi 0:59961b55c453 407 }
2019US_DenisSelimovi 0:59961b55c453 408 return newIncrement * (level + 1);
2019US_DenisSelimovi 0:59961b55c453 409 }
2019US_DenisSelimovi 0:59961b55c453 410
2019US_DenisSelimovi 0:59961b55c453 411 void UpdateBoard()
2019US_DenisSelimovi 0:59961b55c453 412 {
2019US_DenisSelimovi 0:59961b55c453 413 short firstLine, numberOfLines;
2019US_DenisSelimovi 0:59961b55c453 414 //pozivamo funkciju
2019US_DenisSelimovi 0:59961b55c453 415 do {
2019US_DenisSelimovi 0:59961b55c453 416 CheckLines(firstLine, numberOfLines);
2019US_DenisSelimovi 0:59961b55c453 417 for(int i = firstLine; i >= numberOfLines; i--) {
2019US_DenisSelimovi 0:59961b55c453 418 for(int j = 0; j < 10; j++) {
2019US_DenisSelimovi 0:59961b55c453 419 board[i][j] = board[i - numberOfLines][j];
2019US_DenisSelimovi 0:59961b55c453 420 board[i - numberOfLines][j] = 0;
2019US_DenisSelimovi 0:59961b55c453 421 short tmp = i - numberOfLines;
2019US_DenisSelimovi 0:59961b55c453 422 display.fillrect( j * DIMENSION,i * DIMENSION, (j + 1) * DIMENSION , (i + 1) * DIMENSION , colors[board[i][j]]); // bojimo novi blok
2019US_DenisSelimovi 0:59961b55c453 423 display.fillrect( j * DIMENSION, tmp * DIMENSION,(j + 1) * DIMENSION, (tmp + 1) * DIMENSION , White);
2019US_DenisSelimovi 0:59961b55c453 424 if(board[i][j] != 0)
2019US_DenisSelimovi 0:59961b55c453 425 display.rect( j * DIMENSION,i * DIMENSION, (j + 1) * DIMENSION , (i + 1) * DIMENSION , Black);
2019US_DenisSelimovi 0:59961b55c453 426 }
2019US_DenisSelimovi 0:59961b55c453 427 }
2019US_DenisSelimovi 0:59961b55c453 428 score += UpdateScore(numberOfLines);
2019US_DenisSelimovi 0:59961b55c453 429 }
2019US_DenisSelimovi 0:59961b55c453 430 while(numberOfLines != 0); //ovdje se mijenja globalna varijabla score
2019US_DenisSelimovi 0:59961b55c453 431 }
2019US_DenisSelimovi 0:59961b55c453 432
2019US_DenisSelimovi 0:59961b55c453 433 bool IsOver() {
2019US_DenisSelimovi 0:59961b55c453 434 for(int i = 0; i < 10; i++) {
2019US_DenisSelimovi 0:59961b55c453 435 if(board[0][i] != 0) return true;
2019US_DenisSelimovi 0:59961b55c453 436 }
2019US_DenisSelimovi 0:59961b55c453 437 return false;
2019US_DenisSelimovi 0:59961b55c453 438 }
2019US_DenisSelimovi 0:59961b55c453 439
2019US_DenisSelimovi 0:59961b55c453 440 void ShowGameOverScreen() {
2019US_DenisSelimovi 0:59961b55c453 441 display.cls();
2019US_DenisSelimovi 0:59961b55c453 442 display.background(Black);
2019US_DenisSelimovi 0:59961b55c453 443 display.foreground(White);
2019US_DenisSelimovi 0:59961b55c453 444 display.locate(50, 120);
2019US_DenisSelimovi 0:59961b55c453 445 printf("GAME OVER");
2019US_DenisSelimovi 0:59961b55c453 446 display.locate(30, 150);
2019US_DenisSelimovi 0:59961b55c453 447 printf("YOUR SCORE IS %d", score);
2019US_DenisSelimovi 0:59961b55c453 448 wait(3); //ovaj prikaz traje 3s (možemo mijenjati) a nakon toga se ponovo prikazuje meni sa levelima
2019US_DenisSelimovi 0:59961b55c453 449 }
2019US_DenisSelimovi 0:59961b55c453 450
2019US_DenisSelimovi 0:59961b55c453 451 void InitGame() {
2019US_DenisSelimovi 0:59961b55c453 452 if(firstTime) {
2019US_DenisSelimovi 0:59961b55c453 453 currentTetromino.DrawFigure();
2019US_DenisSelimovi 0:59961b55c453 454 nextFigure = rand() % 7 + 1;
2019US_DenisSelimovi 0:59961b55c453 455 ShowNextFigure();
2019US_DenisSelimovi 0:59961b55c453 456 firstTime = false;
2019US_DenisSelimovi 0:59961b55c453 457 }
2019US_DenisSelimovi 0:59961b55c453 458 }
2019US_DenisSelimovi 0:59961b55c453 459
2019US_DenisSelimovi 0:59961b55c453 460 void PlayGame(){
2019US_DenisSelimovi 0:59961b55c453 461 InitGame();
2019US_DenisSelimovi 0:59961b55c453 462 if(!currentTetromino.MoveDown()){
2019US_DenisSelimovi 0:59961b55c453 463 currentTetromino.OnAttached();
2019US_DenisSelimovi 0:59961b55c453 464 UpdateBoard();
2019US_DenisSelimovi 0:59961b55c453 465 ShowScore();
2019US_DenisSelimovi 0:59961b55c453 466
2019US_DenisSelimovi 0:59961b55c453 467 currentTetromino = Tetromino(nextFigure);
2019US_DenisSelimovi 0:59961b55c453 468 currentTetromino.DrawFigure();
2019US_DenisSelimovi 0:59961b55c453 469 nextFigure = rand() % 7 + 1;
2019US_DenisSelimovi 0:59961b55c453 470 ShowNextFigure();
2019US_DenisSelimovi 0:59961b55c453 471 if(IsOver()) {
2019US_DenisSelimovi 0:59961b55c453 472 //ako je igra završena brišemo sve sa displey-a, prikazujemo poruku i score
2019US_DenisSelimovi 0:59961b55c453 473 //takođe moramo dettach-at ticker
2019US_DenisSelimovi 0:59961b55c453 474 game.detach();
2019US_DenisSelimovi 0:59961b55c453 475 ShowGameOverScreen(); //prikaz da je kraj igre, ima wait od 3s
2019US_DenisSelimovi 0:59961b55c453 476 EndPlay();
2019US_DenisSelimovi 0:59961b55c453 477 }
2019US_DenisSelimovi 0:59961b55c453 478 }
2019US_DenisSelimovi 0:59961b55c453 479
2019US_DenisSelimovi 0:59961b55c453 480 }
2019US_DenisSelimovi 0:59961b55c453 481
2019US_DenisSelimovi 0:59961b55c453 482 void OnTasterPressed(){
2019US_DenisSelimovi 0:59961b55c453 483 if(debounceTaster.read_ms() > 200) {
2019US_DenisSelimovi 0:59961b55c453 484 if(gameStarted){
2019US_DenisSelimovi 0:59961b55c453 485 currentTetromino.Rotate();
2019US_DenisSelimovi 0:59961b55c453 486 }
2019US_DenisSelimovi 0:59961b55c453 487 else{
2019US_DenisSelimovi 0:59961b55c453 488 joystick.detach();
2019US_DenisSelimovi 0:59961b55c453 489 gameStarted = true;
2019US_DenisSelimovi 0:59961b55c453 490 StartGame(); //pocinje igra, prikazuje se tabla
2019US_DenisSelimovi 0:59961b55c453 491 joystick.attach(&ReadJoystickForFigure, 0.3);
2019US_DenisSelimovi 0:59961b55c453 492 game.attach(&PlayGame, delays[level]); //svakih nekoliko spusta figuru jedan red nize
2019US_DenisSelimovi 0:59961b55c453 493 }
2019US_DenisSelimovi 0:59961b55c453 494 debounceTaster.reset();
2019US_DenisSelimovi 0:59961b55c453 495 }
2019US_DenisSelimovi 0:59961b55c453 496 }
2019US_DenisSelimovi 0:59961b55c453 497
2019US_DenisSelimovi 0:59961b55c453 498 void SetTaster() {
2019US_DenisSelimovi 0:59961b55c453 499 taster.mode(PullUp); //mora se aktivirati pull up otpornik na tasteru joystick-a
2019US_DenisSelimovi 0:59961b55c453 500 taster.fall(&OnTasterPressed);
2019US_DenisSelimovi 0:59961b55c453 501 debounceTaster.reset();
2019US_DenisSelimovi 0:59961b55c453 502 debounceTaster.start();
2019US_DenisSelimovi 0:59961b55c453 503 }
2019US_DenisSelimovi 0:59961b55c453 504
2019US_DenisSelimovi 0:59961b55c453 505 int main() {
2019US_DenisSelimovi 0:59961b55c453 506 srand(GenerateRandomSeed());
2019US_DenisSelimovi 0:59961b55c453 507 Init();
2019US_DenisSelimovi 0:59961b55c453 508 ShowLevelMenu();
2019US_DenisSelimovi 0:59961b55c453 509 joystick.attach(&ReadJoystickForLevel, 0.3);
2019US_DenisSelimovi 0:59961b55c453 510 SetTaster();
2019US_DenisSelimovi 0:59961b55c453 511 while(1);
2019US_DenisSelimovi 0:59961b55c453 512 }