
Simple tetris game to show usage of C12832 LCD.
Embed:
(wiki syntax)
Show/hide line numbers
mtrix.h
00001 #ifndef MBED_MTRIS_MAIN_HEADER_H 00002 #define MBED_MTRIS_MAIN_HEADER_H 00003 00004 #include <string> 00005 #include <utility> 00006 00007 #define LCD_W 8 00008 #define LCD_H 24 00009 #define BRICK_SIZE_X 4 00010 #define BRICK_SIZE_Y 4 00011 00012 /* QUBE 00013 .... .... .... .... 00014 .##. .##. .##. .##. 00015 .##. .##. .##. .##. 00016 .... .... .... .... 00017 */ 00018 #define BRICK_QUBE_1 {0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0} 00019 #define BRICK_QUBE_2 {0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0} 00020 #define BRICK_QUBE_3 {0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0} 00021 #define BRICK_QUBE_4 {0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0} 00022 00023 /* T-agon 00024 .... .... .... .... 00025 .#.. #... .... .#.. 00026 ###. ##.. ###. ##.. 00027 .... #... .#.. .#.. 00028 */ 00029 #define BRICK_T_1 {0,0,0,0,0,1,0,0,1,1,1,0,0,0,0,0} 00030 #define BRICK_T_2 {0,0,0,0,1,0,0,0,1,1,0,0,1,0,0,0} 00031 #define BRICK_T_3 {0,0,0,0,0,0,0,0,1,1,1,0,0,1,0,0} 00032 #define BRICK_T_4 {0,0,0,0,0,1,0,0,1,1,0,0,0,1,0,0} 00033 00034 /* L-agon 00035 #... .... .... .... 00036 #... ###. ##.. ..#. 00037 ##.. #... .#.. ###. 00038 .... .... .#.. .... 00039 */ 00040 #define BRICK_L_1 {1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0} 00041 #define BRICK_L_2 {0,0,0,0,1,1,1,0,1,0,0,0,0,0,0,0} 00042 #define BRICK_L_3 {0,0,0,0,1,1,0,0,0,1,0,0,0,1,0,0} 00043 #define BRICK_L_4 {0,0,0,0,0,0,1,0,1,1,1,0,0,0,0,0} 00044 00045 /* I-agon 00046 .#.. .... .#.. .... 00047 .#.. #### .#.. #### 00048 .#.. .... .#.. .... 00049 .#.. .... .#.. .... 00050 */ 00051 #define BRICK_I_1 {0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0} 00052 #define BRICK_I_2 {0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0} 00053 #define BRICK_I_3 {0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0} 00054 #define BRICK_I_4 {0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0} 00055 00056 00057 /* +-agon 00058 .#.. .#.. .#.. .#.. 00059 ###. ###. ###. ###. 00060 .#.. .#.. .#.. .#.. 00061 .... .... .... .... 00062 */ 00063 #define BRICK_P_1 {0,1,0,0,1,1,1,0,0,1,0,0,0,0,0,0} 00064 #define BRICK_P_2 {0,1,0,0,1,1,1,0,0,1,0,0,0,0,0,0} 00065 #define BRICK_P_3 {0,1,0,0,1,1,1,0,0,1,0,0,0,0,0,0} 00066 #define BRICK_P_4 {0,1,0,0,1,1,1,0,0,1,0,0,0,0,0,0} 00067 00068 /* *-agon 00069 .... .... .... .... 00070 .#.. .#.. .#.. .#.. 00071 .... .... .... .... 00072 .... .... .... .... 00073 */ 00074 #define BRICK_S_1 {0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0} 00075 #define BRICK_S_2 {0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0} 00076 #define BRICK_S_3 {0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0} 00077 #define BRICK_S_4 {0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0} 00078 00079 /* 4-agon 00080 #... .... #... .... 00081 ##.. .##. ##.. .##. 00082 .#.. ##.. .#.. ##.. 00083 .... .... .... .... 00084 */ 00085 #define BRICK_4_1 {1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0} 00086 #define BRICK_4_2 {0,0,0,0,0,1,1,0,1,1,0,0,0,0,0,0} 00087 #define BRICK_4_3 {1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0} 00088 #define BRICK_4_4 {0,0,0,0,0,1,1,0,1,1,0,0,0,0,0,0} 00089 00090 #define MTRIX_BRICOK_COUNT 7 00091 00092 template <class T> 00093 class MBEDtrisBrick 00094 { 00095 public: 00096 typedef T brick_pattern[BRICK_SIZE_X][BRICK_SIZE_Y]; 00097 00098 MBEDtrisBrick::MBEDtrisBrick() 00099 { 00100 brick_index = 0; 00101 brick_rotate_index = 0; 00102 } 00103 00104 char getcell(int posx, int posy) 00105 { 00106 static T brick[MTRIX_BRICOK_COUNT][4][BRICK_SIZE_X][BRICK_SIZE_Y] = 00107 { 00108 {BRICK_QUBE_1, BRICK_QUBE_2, BRICK_QUBE_3, BRICK_QUBE_4}, 00109 {BRICK_T_1, BRICK_T_2, BRICK_T_3, BRICK_T_4}, 00110 {BRICK_L_1, BRICK_L_2, BRICK_L_3, BRICK_L_4}, 00111 {BRICK_I_1, BRICK_I_2, BRICK_I_3, BRICK_I_4}, 00112 {BRICK_P_1, BRICK_P_2, BRICK_P_3, BRICK_P_4}, 00113 {BRICK_S_1, BRICK_S_2, BRICK_S_3, BRICK_S_4}, 00114 {BRICK_4_1, BRICK_4_2, BRICK_4_3, BRICK_4_4} 00115 }; 00116 00117 return brick[brick_index][brick_rotate_index][posx][posy]; 00118 } 00119 00120 int rotate_next() { return brick_rotate_index = (brick_rotate_index + 1) % 4; } 00121 int rotate_prev() { return brick_rotate_index = (brick_rotate_index == 0) ? 3 : brick_rotate_index - 1; } 00122 00123 int brick_next() { return brick_index = (brick_index + 1) % MTRIX_BRICOK_COUNT; } 00124 int brick_prev() { return brick_index = (brick_index == 0) ? (MTRIX_BRICOK_COUNT - 1) : brick_rotate_index - 1; } 00125 00126 protected: 00127 int brick_index; 00128 int brick_rotate_index; 00129 }; 00130 00131 00132 template <class T> 00133 class MBEDtrisTheGame 00134 { 00135 public: 00136 MBEDtrisTheGame::MBEDtrisTheGame() 00137 { 00138 fill_matrix(0); 00139 } 00140 00141 void set_new_brick_pos() 00142 { 00143 int g_brick_pos_x = (LCD_W) / 2; 00144 int g_brick_pos_y = 0; 00145 } 00146 00147 void fill_matrix(char pattern) 00148 { 00149 for (int x = 0; x < LCD_W; x++) 00150 { 00151 for (int y = 0; y < LCD_H; y++) 00152 { 00153 lcd_matrix[x][y] = pattern; 00154 } 00155 } 00156 } 00157 00158 public: 00159 bool detect_brick_bottom_collision(int offset_x, int offset_y); 00160 bool detect_brick_collision(int offset_x, int offset_y); 00161 bool detect_brick_side_collision(int offset_x, int offset_y); 00162 bool append_brick_to_matrix(); 00163 00164 bool try_move_left(); 00165 bool try_move_right(); 00166 bool try_move_down(); 00167 bool try_rotate(); 00168 00169 void move_brick_left(int offset = 1) { g_brick_pos_x -= offset; } 00170 void move_brick_right(int offset = 1) { g_brick_pos_x += offset; } 00171 void move_brick_up(int offset = 1) { g_brick_pos_y -= offset; } 00172 void move_brick_down(int offset = 1) { try_move_down(); } 00173 00174 T get_matrix_cell(int pos_x, int pos_y) { return lcd_matrix[pos_x][pos_y]; } 00175 T get_brick_cell(int pos_x, int pos_y) { return brick.getcell(pos_x, pos_y); } 00176 std::pair<int, int> get_brick_pos() { return std::make_pair(g_brick_pos_x, g_brick_pos_y); } 00177 00178 protected: 00179 // Brick in use 00180 MBEDtrisBrick<T> brick; 00181 00182 // Display with solid elements 00183 T lcd_matrix[LCD_W][LCD_H]; 00184 00185 // Curent brick screen posiotion 00186 int g_brick_pos_x; 00187 int g_brick_pos_y; 00188 }; 00189 00190 template <class T> 00191 bool MBEDtrisTheGame<T>::detect_brick_bottom_collision(int offset_x, int offset_y) 00192 { 00193 for (int x = 0; x < BRICK_SIZE_X; x++) 00194 { 00195 for (int y = 0; y < BRICK_SIZE_Y; y++) 00196 { 00197 if (brick.getcell(x, y) && (g_brick_pos_y + offset_y + y >= LCD_H)) 00198 { 00199 return true; 00200 } 00201 } 00202 } 00203 return false; 00204 } 00205 00206 template <class T> 00207 bool MBEDtrisTheGame<T>::detect_brick_collision(int offset_x, int offset_y) 00208 { 00209 for (int x = 0; x < BRICK_SIZE_X; x++) 00210 { 00211 for (int y = 0; y < BRICK_SIZE_Y; y++) 00212 { 00213 if (brick.getcell(x, y) && lcd_matrix[g_brick_pos_x + offset_x + x][g_brick_pos_y + offset_y + y]) 00214 { 00215 return true; 00216 } 00217 } 00218 } 00219 return false; 00220 } 00221 00222 template <class T> 00223 bool MBEDtrisTheGame<T>::detect_brick_side_collision(int offset_x, int offset_y) 00224 { 00225 for (int x = 0; x < BRICK_SIZE_X; x++) 00226 { 00227 for (int y = 0; y < BRICK_SIZE_Y; y++) 00228 { 00229 if (brick.getcell(x, y) && g_brick_pos_x + offset_x + x < 0) 00230 { 00231 return true; 00232 } 00233 if (brick.getcell(x, y) && (g_brick_pos_x + offset_x + x >= LCD_W)) 00234 { 00235 return true; 00236 } 00237 } 00238 } 00239 return false; 00240 } 00241 00242 template <class T> 00243 bool MBEDtrisTheGame<T>::append_brick_to_matrix() 00244 { 00245 for (int x = 0; x < BRICK_SIZE_X; x++) 00246 { 00247 for (int y = 0; y < BRICK_SIZE_Y; y++) 00248 { 00249 if (brick.getcell(x, y)) 00250 { 00251 lcd_matrix[g_brick_pos_x + x][g_brick_pos_y + y] = brick.getcell(x, y); 00252 } 00253 } 00254 } 00255 return true; 00256 } 00257 00258 template <class T> 00259 bool MBEDtrisTheGame<T>::try_move_left() 00260 { 00261 bool collision_size = detect_brick_side_collision(-1, 0); 00262 bool collision_brick = detect_brick_collision(-1, 0); 00263 if (!collision_size && !collision_brick) 00264 { 00265 g_brick_pos_x--; 00266 return true; 00267 } 00268 return false; 00269 } 00270 00271 template <class T> 00272 bool MBEDtrisTheGame<T>::try_move_right() 00273 { 00274 bool collision_size = detect_brick_side_collision(1, 0); 00275 bool collision_brick = detect_brick_collision(1, 0); 00276 if (!collision_size && !collision_brick) 00277 { 00278 g_brick_pos_x++; 00279 return true; 00280 } 00281 return false; 00282 } 00283 00284 template <class T> 00285 bool MBEDtrisTheGame<T>::try_move_down() 00286 { 00287 bool brick_collision = detect_brick_collision(0, 1); 00288 bool brick_bottom_collision = detect_brick_bottom_collision(0, 1); 00289 00290 if (brick_collision || brick_bottom_collision) 00291 { 00292 append_brick_to_matrix(); 00293 // Create new brick 00294 brick.brick_next(); 00295 g_brick_pos_x = (LCD_W - BRICK_SIZE_X) / 2; 00296 g_brick_pos_y = 0; 00297 return false; 00298 } 00299 g_brick_pos_y++; 00300 return true; 00301 } 00302 00303 template <class T> 00304 bool MBEDtrisTheGame<T>::try_rotate() 00305 { 00306 brick.rotate_next(); 00307 bool brick_collision = detect_brick_collision(0, 1); 00308 bool brick_bottom_collision = detect_brick_bottom_collision(0, 1); 00309 bool brick_side_collision = detect_brick_side_collision(0, 0); 00310 00311 if (brick_collision || brick_bottom_collision || brick_side_collision) 00312 { 00313 brick.rotate_prev(); 00314 return false; 00315 } 00316 return true; 00317 } 00318 00319 #endif
Generated on Mon Aug 8 2022 11:39:29 by
