Rev 4481 | Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1805 | yogev_ezra | 1 | // |
2 | |||
3 | #include "kosSyst.h" |
||
4 | #include "KosFile.h" |
||
5 | #include "gfxdef.h" |
||
6 | #include "gameWnd.h" |
||
7 | #include "mcarray.h" |
||
8 | #include "lang.h" |
||
9 | |||
10 | // |
||
11 | #define EMPTY_PLACE 0 |
||
12 | |||
13 | #define LEVEL_PROGRESS_LEFT (132+1) |
||
14 | #define LEVEL_PROGRESS_TOP (388+21) |
||
15 | #define LEVEL_PROGRESS_HEIGHT 4 |
||
16 | #define LEVEL_PROGRESS_WIDTH 329 |
||
17 | #define LEVEL_PROGRESS_COLOUR 0xDF2933 |
||
18 | |||
19 | #define BONUS_SOMEBLOCK_TOP (120+21) |
||
20 | #define BONUS_SOMEBLOCK_LEFT (46+1) |
||
21 | #define BONUS_FREEBLOCK_TOP (163+21) |
||
22 | #define BONUS_FREEBLOCK_LEFT (9+1) |
||
23 | #define BONUS_DIAGBLOCK_TOP (213+21) |
||
24 | #define BONUS_DIAGBLOCK_LEFT (48+1) |
||
25 | #define BONUS_PROGRESS_HEIGHT 37 |
||
26 | #define BONUS_PROGRESS_WIDTH 4 |
||
27 | |||
28 | #define LEVEL_SCORE_BASE 50 |
||
29 | |||
30 | // |
||
31 | CKosBitmap gameFace; |
||
32 | CKosBitmap gameBlocks; |
||
33 | CKosBitmap gameNumbers; |
||
34 | CKosBitmap gameBlocksZ[4]; |
||
35 | // |
||
36 | CFishka *fishki[blocksNum]; |
||
37 | |||
38 | // |
||
39 | char *gameWndTitle; |
||
40 | #if LANG == RUS |
||
41 | char gameWndTitle1[] = "” а ® ¦¤св ⥡п :)"; |
||
42 | char gameWndTitle2[] = "Ќг ў®в..."; |
||
43 | char gameOverText[] = "„ «миҐ ¤®а®ЈЁ Ґв!"; |
||
44 | #else |
||
45 | char gameWndTitle1[] = "Pharaoh waits for you :)"; |
||
46 | char gameWndTitle2[] = "Well..."; |
||
47 | char gameOverText[] = "No further way!"; |
||
48 | #endif |
||
49 | // |
||
50 | Word gcx, gcy; |
||
51 | // |
||
52 | #define mapSize 8 |
||
53 | // |
||
54 | // |
||
55 | #define blocksLeft (134+2) |
||
56 | #define blocksTop (43+22) |
||
57 | // |
||
58 | #define blockTypesNum 10 |
||
59 | // |
||
60 | Byte gameMap[mapSize * mapSize]; |
||
61 | // уровень |
||
62 | int gameLevel; |
||
63 | // |
||
64 | int maxGameLevel; |
||
65 | int startGameLevel; |
||
66 | // счёт |
||
67 | Dword playerScore; |
||
68 | // счётчик добавленных блоков |
||
69 | int insertedBlocksCount; |
||
70 | // количество блоков для перехода на следующий уровень |
||
71 | int levelBlocksLimit; |
||
72 | // номер выделенного блока |
||
73 | int selectedBlock; |
||
74 | // прибавление шага для индикатора прохождения уровня * 1024 |
||
75 | int levelProgressStep; |
||
76 | // занчение индикатора прохождения уровня |
||
77 | int levelProgressCount; |
||
78 | // блоки для удаления |
||
79 | struct sRemoveBlock |
||
80 | { |
||
81 | short int ndx; |
||
82 | short int value; |
||
83 | sRemoveBlock() |
||
84 | { |
||
85 | this->ndx = 0; |
||
86 | this->value = 0; |
||
87 | }; |
||
88 | sRemoveBlock( int pNdx, int pValue ) |
||
89 | { |
||
90 | this->ndx = pNdx; |
||
91 | this->value = pValue; |
||
92 | }; |
||
93 | }; |
||
94 | bool operator == ( const sRemoveBlock &b1, const sRemoveBlock &b2 ) |
||
95 | { |
||
96 | return b1.ndx == b2.ndx; |
||
97 | }; |
||
98 | MCArray |
||
99 | // падающие блоки |
||
100 | MCArray |
||
101 | // |
||
102 | bool mouseButtonDisabled; |
||
103 | // |
||
104 | bool freezeBonuses = false; |
||
105 | // |
||
106 | int bonusSomeBlockProgressStep; |
||
107 | int bonusSomeBlockProgressCount; |
||
108 | // |
||
109 | int bonusFreeBlockProgressStep; |
||
110 | int bonusFreeBlockProgressCount; |
||
111 | // |
||
112 | int bonusDiagBlockProgressStep; |
||
113 | int bonusDiagBlockProgressCount; |
||
114 | |||
115 | |||
116 | |||
117 | #define SELECTED_BLOCK_NONE -1 |
||
118 | |||
119 | // бонус включен |
||
120 | int bonusSomeBlock; |
||
121 | // счётчик блоков для бонуса |
||
122 | int bonusSomeBlockCount; |
||
123 | // количество блоков, которое надо убрать, чтобы получить бонус |
||
124 | int bonusSomeBlockEdge; |
||
125 | #define BONUS_SOMEBLOCK_SELECTED -2 |
||
126 | // |
||
127 | bool bonusFreeBlock; |
||
128 | int bonusFreeBlockCount; |
||
129 | int bonusFreeBlockEdge; |
||
130 | #define BONUS_FREEBLOCK_SELECTED -3 |
||
131 | // |
||
132 | int bonusDiagBlock; |
||
133 | int bonusDiagBlockCount; |
||
134 | int bonusDiagBlockEdge; |
||
135 | #define BONUS_DIAGBLOCK_SELECTED -4 |
||
136 | // |
||
137 | void drawScore(); |
||
138 | // отобразить блоки бонусов |
||
139 | void drawBonuses(); |
||
140 | // |
||
141 | void drawLevelNum(); |
||
142 | // |
||
143 | void fadeOutBlocks(); |
||
144 | // |
||
145 | void fallDownBlocks(); |
||
146 | |||
147 | |||
148 | void ClearGameMeters() |
||
149 | { |
||
150 | // индикатор прохождение уровня |
||
151 | kos_DrawBar( |
||
152 | LEVEL_PROGRESS_LEFT, |
||
153 | LEVEL_PROGRESS_TOP, |
||
154 | LEVEL_PROGRESS_WIDTH, |
||
155 | LEVEL_PROGRESS_HEIGHT, |
||
156 | |||
157 | ); |
||
158 | // индикаторы бонусов |
||
159 | // some |
||
160 | kos_DrawBar( |
||
161 | 33+1, |
||
162 | 118+21, |
||
163 | BONUS_PROGRESS_WIDTH, |
||
164 | BONUS_PROGRESS_HEIGHT, |
||
165 | |||
166 | ); |
||
167 | // free |
||
168 | kos_DrawBar( |
||
169 | 58+1, |
||
170 | 166+21, |
||
171 | BONUS_PROGRESS_WIDTH, |
||
172 | BONUS_PROGRESS_HEIGHT, |
||
173 | |||
174 | ); |
||
175 | // diag |
||
176 | kos_DrawBar( |
||
177 | 37+1, |
||
178 | 213+21, |
||
179 | BONUS_PROGRESS_WIDTH, |
||
180 | BONUS_PROGRESS_HEIGHT, |
||
181 | |||
182 | ); |
||
183 | } |
||
184 | |||
185 | |||
186 | // |
||
187 | void drawGameMeters() |
||
188 | { |
||
189 | // |
||
190 | ClearGameMeters(); |
||
191 | // индикатор прохождение уровня |
||
192 | kos_DrawBar( |
||
193 | LEVEL_PROGRESS_LEFT, |
||
194 | LEVEL_PROGRESS_TOP, |
||
195 | levelProgressCount, |
||
196 | LEVEL_PROGRESS_HEIGHT, |
||
197 | LEVEL_PROGRESS_COLOUR |
||
198 | ); |
||
199 | // |
||
200 | if ( bonusSomeBlockProgressCount > 0 ) |
||
201 | // some |
||
202 | kos_DrawBar( |
||
203 | 33+1, |
||
204 | 118+21+BONUS_PROGRESS_HEIGHT-bonusSomeBlockProgressCount, |
||
205 | BONUS_PROGRESS_WIDTH, |
||
206 | bonusSomeBlockProgressCount, |
||
207 | LEVEL_PROGRESS_COLOUR |
||
208 | ); |
||
209 | // |
||
210 | if ( bonusFreeBlockProgressCount > 0 ) |
||
211 | // free |
||
212 | kos_DrawBar( |
||
213 | 58+1, |
||
214 | 166+21+BONUS_PROGRESS_HEIGHT-bonusFreeBlockProgressCount, |
||
215 | BONUS_PROGRESS_WIDTH, |
||
216 | bonusFreeBlockProgressCount, |
||
217 | LEVEL_PROGRESS_COLOUR |
||
218 | ); |
||
219 | // |
||
220 | if ( bonusDiagBlockProgressCount > 0 ) |
||
221 | // diag |
||
222 | kos_DrawBar( |
||
223 | 37+1, |
||
224 | 213+21+BONUS_PROGRESS_HEIGHT-bonusDiagBlockProgressCount, |
||
225 | BONUS_PROGRESS_WIDTH, |
||
226 | bonusDiagBlockProgressCount, |
||
227 | LEVEL_PROGRESS_COLOUR |
||
228 | ); |
||
229 | } |
||
230 | |||
231 | |||
232 | //////////////////////////////////////////////////////////////////////////////// |
||
233 | void SetLevelVariables() |
||
234 | { |
||
235 | selectedBlock = -1; |
||
236 | levelBlocksLimit = ( gameLevel > 5 ) ? LEVEL_SCORE_BASE * ( gameLevel + 1 ) : LEVEL_SCORE_BASE * ( 11 - gameLevel ); |
||
237 | insertedBlocksCount = 0; |
||
238 | // |
||
239 | levelProgressCount = 0; |
||
240 | levelProgressStep = ( LEVEL_PROGRESS_WIDTH * 1024 ) / levelBlocksLimit; |
||
241 | // |
||
242 | bonusSomeBlockEdge = levelBlocksLimit / 4; |
||
243 | bonusFreeBlockEdge = levelBlocksLimit / 3; |
||
244 | bonusDiagBlockEdge = levelBlocksLimit / 2; |
||
245 | // |
||
246 | bonusSomeBlockProgressStep = ( BONUS_PROGRESS_HEIGHT * 1024 ) / bonusSomeBlockEdge; |
||
247 | bonusSomeBlockProgressCount = ( ( ( bonusSomeBlockCount > bonusSomeBlockEdge ) ? bonusSomeBlockEdge : bonusSomeBlockCount ) * bonusSomeBlockProgressStep ) / 1024; |
||
248 | // |
||
249 | bonusFreeBlockProgressStep = ( BONUS_PROGRESS_HEIGHT * 1024 ) / bonusFreeBlockEdge; |
||
250 | bonusFreeBlockProgressCount = ( ( ( bonusFreeBlockCount > bonusFreeBlockEdge ) ? bonusFreeBlockEdge : bonusFreeBlockCount ) * bonusFreeBlockProgressStep ) / 1024; |
||
251 | // |
||
252 | bonusDiagBlockProgressStep = ( BONUS_PROGRESS_HEIGHT * 1024 ) / bonusDiagBlockEdge; |
||
253 | bonusDiagBlockProgressCount = ( ( ( bonusDiagBlockCount > bonusDiagBlockEdge ) ? bonusDiagBlockEdge : bonusDiagBlockCount ) * bonusDiagBlockProgressStep ) / 1024; |
||
254 | } |
||
255 | |||
256 | |||
257 | // |
||
258 | int GetScoreByBlocks( int blocksCount ) |
||
259 | { |
||
260 | int limit, update, i, j, acc; |
||
261 | |||
262 | // |
||
263 | if ( blocksCount < 3 ) return 0; |
||
264 | // |
||
265 | limit = 20 * blocksNum * gameLevel; |
||
266 | // |
||
267 | update = gameLevel; |
||
268 | acc = 1; |
||
269 | // |
||
270 | j = blocksCount - 3; |
||
271 | // |
||
272 | for ( i = 0; i < j; i++ ) |
||
273 | { |
||
274 | // |
||
275 | acc *= gameLevel + 1; |
||
276 | // |
||
277 | if ( ( update + acc ) > limit ) return limit; |
||
278 | } |
||
279 | // |
||
280 | return update + acc; |
||
281 | } |
||
282 | |||
283 | |||
284 | |||
285 | // |
||
286 | int insertNewBlocks() |
||
287 | { |
||
288 | int i, j, k, ndx, result, btn; |
||
289 | |||
290 | // |
||
291 | toFallList.Clear(); |
||
292 | // |
||
293 | result = 0; |
||
294 | // |
||
295 | btn = gameLevel > 5 ? blockTypesNum : 5 + gameLevel; |
||
296 | // |
||
297 | ndx = ( mapSize * mapSize ) - mapSize; |
||
298 | // |
||
299 | for ( i = 0; i < mapSize; i++ ) |
||
300 | { |
||
301 | for ( j = 0; j < mapSize; j++ ) |
||
302 | { |
||
303 | // |
||
304 | k = ndx + i - ( j * mapSize ); |
||
305 | // |
||
306 | if ( gameMap[k] == EMPTY_PLACE ) |
||
307 | { |
||
308 | // |
||
309 | for ( ; j < (mapSize-1); j++ ) |
||
310 | { |
||
311 | // |
||
312 | gameMap[k] = gameMap[k-mapSize]; |
||
313 | toFallList.AddExclusive( k ); |
||
314 | k -= mapSize; |
||
315 | } |
||
316 | // |
||
317 | gameMap[i] = ( rtlRand() % btn ) + 1; |
||
318 | toFallList.AddExclusive( i ); |
||
319 | // |
||
320 | result++; |
||
321 | // |
||
322 | break; |
||
323 | } |
||
324 | } |
||
325 | } |
||
326 | // |
||
327 | insertedBlocksCount += result; |
||
328 | // |
||
329 | return result; |
||
330 | } |
||
331 | |||
332 | |||
333 | // поиск цепочек блоков для удаления, удаление блоков |
||
334 | // возвращает приращение счёта игрока |
||
335 | int findBlockLines() |
||
336 | { |
||
337 | int x, y, ndx; |
||
338 | int removeCount = 0; |
||
339 | |||
340 | // очистим список для записи результатов |
||
341 | toRemoveList.Clear(); |
||
342 | // |
||
343 | for ( y = 0; y < mapSize; y++ ) |
||
344 | { |
||
345 | // |
||
346 | for ( x = 0; x < mapSize; x++ ) |
||
347 | { |
||
348 | // |
||
349 | ndx = x + ( y * mapSize ); |
||
350 | // |
||
351 | if ( gameMap[ndx] == EMPTY_PLACE ) continue; |
||
352 | // проверяем горизонтальную цепочку |
||
353 | if ( x < (mapSize - 2) ) |
||
354 | { |
||
355 | // |
||
356 | if ( |
||
357 | ( gameMap[ndx] == gameMap[ndx+1] && gameMap[ndx] == gameMap[ndx+2] ) |
||
358 | || ( BONUS_FREE_BLOCK == gameMap[ndx] && gameMap[ndx+1] == gameMap[ndx+2] ) |
||
359 | || ( gameMap[ndx] == gameMap[ndx+1] && BONUS_FREE_BLOCK == gameMap[ndx+2] ) |
||
360 | || ( gameMap[ndx] == gameMap[ndx+2] && BONUS_FREE_BLOCK == gameMap[ndx+1] ) |
||
361 | ) |
||
362 | { |
||
363 | // нашли цепочку, запомним |
||
364 | toRemoveList.AddExclusive( sRemoveBlock( ndx, gameMap[ndx] ) ); |
||
365 | toRemoveList.AddExclusive( sRemoveBlock( ndx+1, gameMap[ndx+1] ) ); |
||
366 | toRemoveList.AddExclusive( sRemoveBlock( ndx+2, gameMap[ndx+2] ) ); |
||
367 | } |
||
368 | } |
||
369 | // проверяем вертикальную цепочку |
||
370 | if ( y < (mapSize - 2) ) |
||
371 | { |
||
372 | // |
||
373 | if ( |
||
374 | ( gameMap[ndx] == gameMap[ndx+mapSize] && gameMap[ndx] == gameMap[ndx+mapSize+mapSize] ) |
||
375 | || ( BONUS_FREE_BLOCK == gameMap[ndx] && gameMap[ndx+mapSize] == gameMap[ndx+mapSize+mapSize] ) |
||
376 | || ( gameMap[ndx] == gameMap[ndx+mapSize] && BONUS_FREE_BLOCK == gameMap[ndx+mapSize+mapSize] ) |
||
377 | || ( gameMap[ndx] == gameMap[ndx+mapSize+mapSize] && BONUS_FREE_BLOCK == gameMap[ndx+mapSize] ) |
||
378 | ) |
||
379 | { |
||
380 | // нашли цепочку, запомним |
||
381 | toRemoveList.AddExclusive( sRemoveBlock( ndx, gameMap[ndx] ) ); |
||
382 | toRemoveList.AddExclusive( sRemoveBlock( ndx+mapSize, gameMap[ndx+mapSize] ) ); |
||
383 | toRemoveList.AddExclusive( sRemoveBlock( ndx+mapSize+mapSize, gameMap[ndx+mapSize+mapSize] ) ); |
||
384 | } |
||
385 | } |
||
386 | } |
||
387 | } |
||
388 | // |
||
389 | return toRemoveList.GetCount(); |
||
390 | } |
||
391 | |||
392 | |||
393 | // проверка на невозможность собрать какую-нибудь линию |
||
394 | bool checkGameOut() |
||
395 | { |
||
396 | int x, y, ndx; |
||
397 | |||
398 | // |
||
399 | ndx = 0; |
||
400 | // |
||
401 | for ( y = 0; y < mapSize; y++ ) |
||
402 | { |
||
403 | // |
||
404 | for ( x = 0; x < mapSize; x++ ) |
||
405 | { |
||
406 | // проверяем горизонтальные цепочки из двух символов |
||
407 | if ( x < (mapSize - 1) ) |
||
408 | { |
||
409 | // |
||
410 | if ( gameMap[ndx] == gameMap[ndx+1] ) |
||
411 | { |
||
412 | // нашли цепочку из двух блоков |
||
413 | // проверка бонусов |
||
414 | if ( bonusSomeBlock == gameMap[ndx] ) return false; |
||
415 | if ( bonusFreeBlock ) return false; |
||
416 | // проверка обычных перестановок |
||
417 | if ( y > 0 ) |
||
418 | { |
||
419 | // |
||
420 | if ( x > 0 ) |
||
421 | { |
||
422 | // |
||
423 | if ( gameMap[ndx-mapSize-1] == gameMap[ndx] ) return false; |
||
424 | } |
||
425 | // |
||
426 | if ( x < (mapSize - 2) ) |
||
427 | { |
||
428 | // |
||
429 | if ( gameMap[ndx-mapSize+2] == gameMap[ndx] ) return false; |
||
430 | } |
||
431 | } |
||
432 | // |
||
433 | if ( x > 1 ) |
||
434 | { |
||
435 | // |
||
436 | if ( gameMap[ndx-2] == gameMap[ndx] ) return false; |
||
437 | } |
||
438 | // |
||
439 | if ( x < (mapSize - 3) ) |
||
440 | { |
||
441 | // |
||
442 | if ( gameMap[ndx+3] == gameMap[ndx] ) return false; |
||
443 | } |
||
444 | // |
||
445 | if ( y < (mapSize - 1) ) |
||
446 | { |
||
447 | // |
||
448 | if ( x > 0 ) |
||
449 | { |
||
450 | // |
||
451 | if ( gameMap[ndx+mapSize-1] == gameMap[ndx] ) return false; |
||
452 | } |
||
453 | // |
||
454 | if ( x < (mapSize - 2) ) |
||
455 | { |
||
456 | // |
||
457 | if ( gameMap[ndx+mapSize+2] == gameMap[ndx] ) return false; |
||
458 | } |
||
459 | } |
||
460 | // проверка диагональных перестановок |
||
461 | if ( bonusDiagBlock > 0 ) |
||
462 | { |
||
463 | // |
||
464 | if ( y > 0 ) |
||
465 | { |
||
466 | // |
||
467 | if ( x > 1 ) |
||
468 | { |
||
469 | // |
||
470 | if ( gameMap[ndx-mapSize-2] == gameMap[ndx] ) return false; |
||
471 | } |
||
472 | // |
||
473 | if ( gameMap[ndx-mapSize] == gameMap[ndx] ) return false; |
||
474 | // |
||
475 | if ( x < (mapSize - 2) ) |
||
476 | { |
||
477 | // |
||
478 | if ( gameMap[ndx-mapSize+1] == gameMap[ndx] ) return false; |
||
479 | } |
||
480 | // |
||
481 | if ( x < (mapSize - 3) ) |
||
482 | { |
||
483 | // |
||
484 | if ( gameMap[ndx-mapSize+3] == gameMap[ndx] ) return false; |
||
485 | } |
||
486 | } |
||
487 | // |
||
488 | if ( y < (mapSize - 1) ) |
||
489 | { |
||
490 | // |
||
491 | if ( x > 1 ) |
||
492 | { |
||
493 | // |
||
494 | if ( gameMap[ndx+mapSize-2] == gameMap[ndx] ) return false; |
||
495 | } |
||
496 | // |
||
497 | if ( gameMap[ndx+mapSize] == gameMap[ndx] ) return false; |
||
498 | // |
||
499 | if ( x < (mapSize - 2) ) |
||
500 | { |
||
501 | // |
||
502 | if ( gameMap[ndx+mapSize+1] == gameMap[ndx] ) return false; |
||
503 | } |
||
504 | // |
||
505 | if ( x < (mapSize - 3) ) |
||
506 | { |
||
507 | // |
||
508 | if ( gameMap[ndx+mapSize+3] == gameMap[ndx] ) return false; |
||
509 | } |
||
510 | } |
||
511 | } // закончена проверка диагональных перестановок |
||
512 | } |
||
513 | } |
||
514 | // проверяем горизонтальные цепочки из двух блоков с промежутком |
||
515 | if ( x < (mapSize - 2) ) |
||
516 | { |
||
517 | // |
||
518 | if ( gameMap[ndx] == gameMap[ndx+2] ) |
||
519 | { |
||
520 | // нашли два блока с промежутком |
||
521 | // проверка бонусов |
||
522 | if ( bonusSomeBlock == gameMap[ndx] ) return false; |
||
523 | if ( bonusFreeBlock ) return false; |
||
524 | // |
||
525 | if ( y > 0 ) |
||
526 | { |
||
527 | // |
||
528 | if ( gameMap[ndx-mapSize+1] == gameMap[ndx] ) return false; |
||
529 | } |
||
530 | // |
||
531 | if ( y < (mapSize-1) ) |
||
532 | { |
||
533 | // |
||
534 | if ( gameMap[ndx+mapSize+1] == gameMap[ndx] ) return false; |
||
535 | } |
||
536 | // проверка диагональных перестановок |
||
537 | if ( bonusDiagBlock > 0 ) |
||
538 | { |
||
539 | // |
||
540 | if ( y > 0 ) |
||
541 | { |
||
542 | // |
||
543 | if ( gameMap[ndx-mapSize] == gameMap[ndx] ) return false; |
||
544 | // |
||
545 | if ( gameMap[ndx-mapSize+2] == gameMap[ndx] ) return false; |
||
546 | } |
||
547 | // |
||
548 | if ( y < (mapSize-1) ) |
||
549 | { |
||
550 | // |
||
551 | if ( gameMap[ndx+mapSize] == gameMap[ndx] ) return false; |
||
552 | // |
||
553 | if ( gameMap[ndx+mapSize+2] == gameMap[ndx] ) return false; |
||
554 | } |
||
555 | } |
||
556 | } |
||
557 | } |
||
558 | // проверяем вертикальные цепочки из двух символов |
||
559 | if ( y < (mapSize - 1) ) |
||
560 | { |
||
561 | // |
||
562 | if ( gameMap[ndx] == gameMap[ndx+mapSize] ) |
||
563 | { |
||
564 | // нашли цепочку из двух блоков |
||
565 | // проверка бонусов |
||
566 | if ( bonusSomeBlock == gameMap[ndx] ) return false; |
||
567 | if ( bonusFreeBlock ) return false; |
||
568 | // |
||
569 | if ( x > 0 ) |
||
570 | { |
||
571 | // |
||
572 | if ( y > 0 ) |
||
573 | { |
||
574 | // |
||
575 | if ( gameMap[ndx-1-mapSize] == gameMap[ndx] ) return false; |
||
576 | } |
||
577 | // |
||
578 | if ( y < (mapSize - 2) ) |
||
579 | { |
||
580 | // |
||
581 | if ( gameMap[ndx-1+(2*mapSize)] == gameMap[ndx] ) return false; |
||
582 | } |
||
583 | } |
||
584 | // |
||
585 | if ( y > 1 ) |
||
586 | { |
||
587 | // |
||
588 | if ( gameMap[ndx-(2*mapSize)] == gameMap[ndx] ) return false; |
||
589 | } |
||
590 | // |
||
591 | if ( y < (mapSize - 3) ) |
||
592 | { |
||
593 | // |
||
594 | if ( gameMap[ndx+(3*mapSize)] == gameMap[ndx] ) return false; |
||
595 | } |
||
596 | // |
||
597 | if ( x < (mapSize - 1) ) |
||
598 | { |
||
599 | // |
||
600 | if ( y > 0 ) |
||
601 | { |
||
602 | // |
||
603 | if ( gameMap[ndx+1-mapSize] == gameMap[ndx] ) return false; |
||
604 | } |
||
605 | // |
||
606 | if ( y < (mapSize - 2) ) |
||
607 | { |
||
608 | // |
||
609 | if ( gameMap[ndx+1+(2*mapSize)] == gameMap[ndx] ) return false; |
||
610 | } |
||
611 | } |
||
612 | // проверка диагональных перестановок |
||
613 | if ( bonusDiagBlock > 0 ) |
||
614 | { |
||
615 | // |
||
616 | if ( x > 0 ) |
||
617 | { |
||
618 | // |
||
619 | if ( y > 1 ) |
||
620 | { |
||
621 | // |
||
622 | if ( gameMap[ndx-1-(2*mapSize)] == gameMap[ndx] ) return false; |
||
623 | } |
||
624 | // |
||
625 | if ( gameMap[ndx-1] == gameMap[ndx] ) return false; |
||
626 | // |
||
627 | if ( y < (mapSize - 2) ) |
||
628 | { |
||
629 | // |
||
630 | if ( gameMap[ndx-1+mapSize] == gameMap[ndx] ) return false; |
||
631 | } |
||
632 | // |
||
633 | if ( y < (mapSize - 3) ) |
||
634 | { |
||
635 | // |
||
636 | if ( gameMap[ndx-1+(3*mapSize)] == gameMap[ndx] ) return false; |
||
637 | } |
||
638 | } |
||
639 | // |
||
640 | if ( x < (mapSize - 1) ) |
||
641 | { |
||
642 | // |
||
643 | if ( y > 1 ) |
||
644 | { |
||
645 | // |
||
646 | if ( gameMap[ndx+1-(2*mapSize)] == gameMap[ndx] ) return false; |
||
647 | } |
||
648 | // |
||
649 | if ( gameMap[ndx+1] == gameMap[ndx] ) return false; |
||
650 | // |
||
651 | if ( y < (mapSize - 2) ) |
||
652 | { |
||
653 | // |
||
654 | if ( gameMap[ndx+1+mapSize] == gameMap[ndx] ) return false; |
||
655 | } |
||
656 | // |
||
657 | if ( y < (mapSize - 3) ) |
||
658 | { |
||
659 | // |
||
660 | if ( gameMap[ndx+1+(3*mapSize)] == gameMap[ndx] ) return false; |
||
661 | } |
||
662 | } |
||
663 | } // закончена проверка диагональных перестановок |
||
664 | } |
||
665 | } |
||
666 | // проверяем вертикальные цепочки из двух блоков с промежутком |
||
667 | if ( y < (mapSize - 2) ) |
||
668 | { |
||
669 | // |
||
670 | if ( gameMap[ndx] == gameMap[ndx+(2*mapSize)] ) |
||
671 | { |
||
672 | // нашли два блока с промежутком |
||
673 | // проверка бонусов |
||
674 | if ( bonusSomeBlock == gameMap[ndx] ) return false; |
||
675 | if ( bonusFreeBlock ) return false; |
||
676 | // |
||
677 | if ( x > 0 ) |
||
678 | { |
||
679 | // |
||
680 | if ( gameMap[ndx-1+mapSize] == gameMap[ndx] ) return false; |
||
681 | } |
||
682 | // |
||
683 | if ( x < (mapSize-1) ) |
||
684 | { |
||
685 | // |
||
686 | if ( gameMap[ndx+1+mapSize] == gameMap[ndx] ) return false; |
||
687 | } |
||
688 | // проверка диагональных перестановок |
||
689 | if ( bonusDiagBlock > 0 ) |
||
690 | { |
||
691 | // |
||
692 | if ( x > 0 ) |
||
693 | { |
||
694 | // |
||
695 | if ( gameMap[ndx-1] == gameMap[ndx] ) return false; |
||
696 | // |
||
697 | if ( gameMap[ndx-1+(2*mapSize)] == gameMap[ndx] ) return false; |
||
698 | } |
||
699 | // |
||
700 | if ( x < (mapSize-1) ) |
||
701 | { |
||
702 | // |
||
703 | if ( gameMap[ndx+1] == gameMap[ndx] ) return false; |
||
704 | // |
||
705 | if ( gameMap[ndx+1+(2*mapSize)] == gameMap[ndx] ) return false; |
||
706 | } |
||
707 | } |
||
708 | } |
||
709 | } |
||
710 | // |
||
711 | ndx++; |
||
712 | } |
||
713 | } |
||
714 | // |
||
715 | gameWndTitle = gameWndTitle2; |
||
716 | // |
||
717 | return true; |
||
718 | } |
||
719 | |||
720 | |||
721 | // |
||
722 | bool exterminateLines() |
||
723 | { |
||
724 | int deletedBlocks, btn, i, j; |
||
725 | bool needRedrawBonus = false; |
||
726 | |||
727 | // |
||
728 | btn = gameLevel > 5 ? blockTypesNum : 5 + gameLevel; |
||
729 | // |
||
730 | playerScore += GetScoreByBlocks( deletedBlocks = findBlockLines() ); |
||
731 | // |
||
732 | if ( ! freezeBonuses ) |
||
733 | { |
||
734 | // |
||
735 | if ( gameLevel >= 2 && bonusSomeBlock <= 0 ) bonusSomeBlockCount += deletedBlocks; |
||
736 | if ( gameLevel >= 3 && !bonusFreeBlock ) bonusFreeBlockCount += deletedBlocks; |
||
737 | if ( gameLevel >= 4 && bonusDiagBlock <= 0 ) bonusDiagBlockCount += deletedBlocks; |
||
738 | // первый бонус |
||
739 | if ( |
||
740 | ( bonusSomeBlockCount >= bonusSomeBlockEdge || ( gameLevel >= 2 && deletedBlocks >= 4 ) ) |
||
741 | && bonusSomeBlock <= 0 |
||
742 | ) |
||
743 | { |
||
744 | bonusSomeBlock = ( rtlRand() % btn ) + 1; |
||
745 | needRedrawBonus = true; |
||
746 | if ( bonusSomeBlockCount >= bonusSomeBlockEdge ) bonusSomeBlockCount = 0; |
||
747 | } |
||
748 | if ( bonusSomeBlockCount >= bonusSomeBlockEdge ) bonusSomeBlockCount = 0; |
||
749 | // второй бонус |
||
750 | if ( bonusFreeBlockCount >= bonusFreeBlockEdge || ( gameLevel >=3 && deletedBlocks >= 5 ) ) |
||
751 | { |
||
752 | bonusFreeBlock = true; |
||
753 | needRedrawBonus = true; |
||
754 | if ( bonusFreeBlockCount >= bonusFreeBlockEdge ) bonusFreeBlockCount = 0; |
||
755 | } |
||
756 | if ( bonusFreeBlockCount >= bonusFreeBlockEdge ) bonusFreeBlockCount = 0; |
||
757 | // третий бонус |
||
758 | if ( bonusDiagBlockCount >= bonusDiagBlockEdge || ( gameLevel >= 4 && deletedBlocks >= 6 ) ) |
||
759 | { |
||
760 | bonusDiagBlock = 3; |
||
761 | needRedrawBonus = true; |
||
762 | if ( bonusDiagBlockCount >= bonusDiagBlockEdge ) bonusDiagBlockCount = 0; |
||
763 | } |
||
764 | if ( bonusDiagBlockCount >= bonusDiagBlockEdge ) bonusDiagBlockCount = 0; |
||
765 | // |
||
766 | bonusSomeBlockProgressCount = ( ( ( bonusSomeBlockCount > bonusSomeBlockEdge ) ? bonusSomeBlockEdge : bonusSomeBlockCount ) * bonusSomeBlockProgressStep ) / 1024; |
||
767 | // |
||
768 | bonusFreeBlockProgressCount = ( ( ( bonusFreeBlockCount > bonusFreeBlockEdge ) ? bonusFreeBlockEdge : bonusFreeBlockCount ) * bonusFreeBlockProgressStep ) / 1024; |
||
769 | // |
||
770 | bonusDiagBlockProgressCount = ( ( ( bonusDiagBlockCount > bonusDiagBlockEdge ) ? bonusDiagBlockEdge : bonusDiagBlockCount ) * bonusDiagBlockProgressStep ) / 1024; |
||
771 | // |
||
772 | if ( needRedrawBonus ) drawBonuses(); |
||
773 | } |
||
774 | // |
||
775 | j = toRemoveList.GetCount(); |
||
776 | // |
||
777 | for ( i = 0; i < j; i++ ) |
||
778 | { |
||
779 | gameMap[toRemoveList[i].ndx] = EMPTY_PLACE; |
||
780 | } |
||
781 | // |
||
782 | return toRemoveList.GetCount() > 0; |
||
783 | } |
||
784 | |||
785 | |||
786 | // заполнение игрового поля случайной комбинацией блоков |
||
787 | void initGameMap() |
||
788 | { |
||
789 | int i, localScore, localInserted, btn; |
||
790 | |||
791 | // |
||
792 | btn = gameLevel > 5 ? blockTypesNum : 5 + gameLevel; |
||
793 | // |
||
794 | for ( i = 0; i < (mapSize * mapSize); i++ ) |
||
795 | { |
||
796 | gameMap[i] = ( rtlRand() % btn ) + 1; |
||
797 | } |
||
798 | // |
||
799 | localScore = playerScore; |
||
800 | localInserted = insertedBlocksCount; |
||
801 | // |
||
802 | freezeBonuses = true; |
||
803 | // |
||
804 | while ( exterminateLines() ) |
||
805 | { |
||
806 | while ( insertNewBlocks() > 0 ); |
||
807 | } |
||
808 | // |
||
809 | freezeBonuses = false; |
||
810 | // |
||
811 | playerScore = localScore; |
||
812 | insertedBlocksCount = localInserted; |
||
813 | } |
||
814 | |||
815 | |||
816 | // отобразить блоки бонусов |
||
817 | void drawBonuses() |
||
818 | { |
||
819 | // |
||
820 | kos_PutImage( |
||
821 | selectedBlock != BONUS_SOMEBLOCK_SELECTED ? |
||
822 | fishki[bonusSomeBlock]->GetBits() : |
||
823 | fishki[bonusSomeBlock]->GetHighlightedBits(), |
||
824 | blockSize, blockSize, |
||
825 | BONUS_SOMEBLOCK_LEFT, BONUS_SOMEBLOCK_TOP |
||
826 | ); |
||
827 | // |
||
828 | kos_PutImage( |
||
829 | bonusFreeBlock ? |
||
830 | ( |
||
831 | selectedBlock != BONUS_FREEBLOCK_SELECTED ? |
||
832 | fishki[BONUS_FREE_BLOCK]->GetBits() : |
||
833 | fishki[BONUS_FREE_BLOCK]->GetHighlightedBits() |
||
834 | ) : |
||
835 | fishki[0]->GetBits(), |
||
836 | blockSize, blockSize, |
||
837 | BONUS_FREEBLOCK_LEFT, BONUS_FREEBLOCK_TOP |
||
838 | ); |
||
839 | // |
||
840 | kos_PutImage( |
||
841 | bonusDiagBlock > 0 ? |
||
842 | fishki[bonusDiagBlock+BONUS_DIAG_BLOCK-1]->GetBits() : |
||
843 | fishki[0]->GetBits(), |
||
844 | blockSize, blockSize, |
||
845 | BONUS_DIAGBLOCK_LEFT, BONUS_DIAGBLOCK_TOP |
||
846 | ); |
||
847 | } |
||
848 | |||
849 | |||
850 | // отобразить игровое поле |
||
851 | void drawGameMap() |
||
852 | { |
||
853 | int i, j, ndx; |
||
854 | |||
855 | // |
||
856 | for ( i = 0; i < mapSize; i++ ) |
||
857 | { |
||
858 | // |
||
859 | for ( j = 0; j < mapSize; j++ ) |
||
860 | { |
||
861 | // |
||
862 | ndx = (i*mapSize) + j; |
||
863 | // |
||
864 | kos_PutImage( |
||
865 | ndx != selectedBlock ? |
||
866 | fishki[gameMap[ndx]]->GetBits() : |
||
867 | fishki[gameMap[ndx]]->GetHighlightedBits(), |
||
868 | blockSize, blockSize, |
||
869 | (j * blockSize) + blocksLeft, |
||
870 | (i * blockSize) + blocksTop |
||
871 | ); |
||
872 | } |
||
873 | } |
||
874 | } |
||
875 | |||
876 | |||
877 | // координаты курсора "мыши" |
||
878 | int mX, mY; |
||
879 | |||
880 | // проверка на нажатие левой кнопки "мыши" |
||
881 | bool mouseLButtonDown() |
||
882 | { |
||
883 | static bool isDown = false; |
||
884 | Dword buttons; |
||
885 | |||
886 | // |
||
887 | kos_GetMouseState( buttons, mX, mY ); |
||
888 | // |
||
889 | if ( mouseButtonDisabled ) return false; |
||
890 | // |
||
891 | if ( ( buttons & 1 ) ) |
||
892 | { |
||
893 | if ( isDown ) |
||
894 | return false; |
||
895 | else |
||
896 | { |
||
897 | isDown = true; |
||
898 | return true; |
||
899 | } |
||
900 | } |
||
901 | else |
||
902 | { |
||
903 | if ( isDown ) |
||
904 | { |
||
905 | isDown = false; |
||
906 | } |
||
907 | return false; |
||
908 | } |
||
909 | } |
||
910 | |||
911 | // |
||
912 | void flipTwoBlocks( int ndx1, int ndx2 ) |
||
913 | { |
||
914 | Word blX, blY, selX, selY; |
||
915 | Byte fishCode; |
||
916 | |||
917 | // |
||
918 | blX = ( ndx1 % mapSize ) * blockSize + blocksLeft; |
||
919 | blY = ( ndx1 / mapSize ) * blockSize + blocksTop; |
||
920 | selX = ( ndx2 % mapSize ) * blockSize + blocksLeft; |
||
921 | selY = ( ndx2 / mapSize ) * blockSize + blocksTop; |
||
922 | // переставим блоки местами |
||
923 | fishCode = gameMap[ndx1]; |
||
924 | gameMap[ndx1] = gameMap[ndx2]; |
||
925 | gameMap[ndx2] = fishCode; |
||
926 | // изображение блока |
||
927 | kos_PutImage( |
||
928 | fishki[gameMap[ndx1]]->GetBits(), |
||
929 | blockSize, blockSize, |
||
930 | blX, |
||
931 | blY |
||
932 | ); |
||
933 | // изображение блока |
||
934 | kos_PutImage( |
||
935 | fishki[gameMap[ndx2]]->GetBits(), |
||
936 | blockSize, blockSize, |
||
937 | selX, |
||
938 | selY |
||
939 | ); |
||
940 | } |
||
941 | |||
942 | |||
943 | // игровой процесс |
||
944 | int GameLoop() |
||
945 | { |
||
946 | int result, ndx, blX, blY, selX, selY, ddX, ddY, nSel; |
||
947 | Byte keyCode, mCode; |
||
948 | bool needDecBonus; |
||
949 | Dword buttonID; |
||
950 | |||
951 | // |
||
952 | gameWndTitle = gameWndTitle1; |
||
953 | gameFace.GetSize( gcx, gcy ); |
||
954 | gameLevel = startGameLevel; |
||
955 | playerScore = 0; |
||
956 | bonusSomeBlock = 0; |
||
957 | bonusFreeBlock = false; |
||
958 | bonusDiagBlock = 0; |
||
959 | bonusSomeBlockCount = 0; |
||
960 | bonusFreeBlockCount = 0; |
||
961 | bonusDiagBlockCount = 0; |
||
962 | bonusSomeBlockProgressCount = 0; |
||
963 | bonusFreeBlockProgressCount = 0; |
||
964 | bonusDiagBlockProgressCount = 0; |
||
965 | SetLevelVariables(); |
||
966 | mouseButtonDisabled = false; |
||
967 | initGameMap(); |
||
968 | // |
||
969 | kos_ChangeWindow( -1, -1, gcx + 1, gcy + 21 ); |
||
970 | // |
||
971 | for ( result = GM_NONE; result == GM_NONE; ) |
||
972 | { |
||
973 | switch( kos_WaitForEvent() ) |
||
974 | { |
||
975 | // надо полностью перерисовать окно |
||
976 | case 1: |
||
977 | DrawGameWindow(); |
||
978 | break; |
||
979 | |||
980 | // клавиатура |
||
981 | case 2: |
||
982 | if ( kos_GetKey( keyCode ) ) |
||
983 | { |
||
984 | // |
||
985 | switch ( keyCode ) |
||
986 | { |
||
987 | case 0x1B: |
||
988 | result = GM_ABORT; |
||
989 | break; |
||
990 | |||
991 | default: |
||
992 | break; |
||
993 | } |
||
994 | } |
||
995 | break; |
||
996 | |||
997 | // кнопки |
||
998 | case 3: |
||
999 | if ( kos_GetButtonID( buttonID ) ) |
||
1000 | { |
||
1001 | switch ( buttonID ) |
||
1002 | { |
||
1003 | case 0xA: |
||
1004 | result = GM_ABORT; |
||
1005 | break; |
||
1006 | |||
1007 | default: |
||
1008 | break; |
||
1009 | } |
||
1010 | } |
||
1011 | |||
1012 | // событие от мыши |
||
1013 | case 6: |
||
1014 | // нажатие левой кнопки? |
||
1015 | if ( mouseLButtonDown() ) |
||
1016 | { |
||
1017 | // считаем координаты относително игрового поля |
||
1018 | blX = mX - blocksLeft; |
||
1019 | blY = mY - blocksTop; |
||
1020 | // попало в игровое поле? |
||
1021 | if ( blX >= 0 && blX < (mapSize * blockSize) |
||
1022 | && blY >= 0 && blY < (mapSize * blockSize) ) |
||
1023 | { |
||
1024 | // получаем координаты в блоках |
||
1025 | blX /= blockSize; |
||
1026 | blY /= blockSize; |
||
1027 | // получаем номер блока на карте |
||
1028 | ndx = blX + ( blY * mapSize ); |
||
1029 | // ещё одна проверка, чтобы не вылезти за пределы карты |
||
1030 | if ( ndx >= 0 && ndx < (mapSize * mapSize) ) |
||
1031 | { |
||
1032 | // начинаем перерисовку |
||
1033 | kos_WindowRedrawStatus( WRS_BEGIN ); |
||
1034 | // если не было выбранного блока |
||
1035 | if ( selectedBlock == SELECTED_BLOCK_NONE ) |
||
1036 | { |
||
1037 | // запомним выделенный блок |
||
1038 | selectedBlock = ndx; |
||
1039 | // отметим блок на игровом поле |
||
1040 | kos_PutImage( |
||
1041 | fishki[gameMap[selectedBlock]]->GetHighlightedBits(), |
||
1042 | blockSize, blockSize, |
||
1043 | ( selectedBlock % mapSize ) * blockSize + blocksLeft, |
||
1044 | ( selectedBlock / mapSize ) * blockSize + blocksTop |
||
1045 | ); |
||
1046 | } |
||
1047 | else // помеченный блок уже есть |
||
1048 | { |
||
1049 | if ( selectedBlock >= 0 ) |
||
1050 | { |
||
1051 | // координаты помеченного блока |
||
1052 | selX = selectedBlock % mapSize; |
||
1053 | selY = selectedBlock / mapSize; |
||
1054 | // был выбран другой блок? |
||
1055 | if ( ndx != selectedBlock ) |
||
1056 | { |
||
1057 | // считаем разность координат двух блоков |
||
1058 | ddX = selX - blX; |
||
1059 | ddY = selY - blY; |
||
1060 | needDecBonus = ( bonusDiagBlock > 0 && abs(ddX) == 1 && abs(ddY) == 1 ); |
||
1061 | // если это соседний блок |
||
1062 | if ( |
||
1063 | ( abs(ddX) == 1 && ddY == 0 ) |
||
1064 | || ( abs(ddY) == 1 && ddX == 0 ) |
||
1065 | || needDecBonus |
||
1066 | ) |
||
1067 | { |
||
1068 | // переставим блоки местами |
||
1069 | flipTwoBlocks( ndx, selectedBlock ); |
||
1070 | // |
||
1071 | kos_Pause( 16 ); |
||
1072 | // |
||
1073 | if ( findBlockLines() > 0 ) |
||
1074 | { |
||
1075 | // |
||
1076 | if ( needDecBonus ) |
||
1077 | { |
||
1078 | // |
||
1079 | --bonusDiagBlock; |
||
1080 | // |
||
1081 | drawBonuses(); |
||
1082 | } |
||
1083 | // снимаем пометку с блока |
||
1084 | selectedBlock = SELECTED_BLOCK_NONE; |
||
1085 | // |
||
1086 | while ( exterminateLines() ) |
||
1087 | { |
||
1088 | // |
||
1089 | fadeOutBlocks(); |
||
1090 | // |
||
1091 | //drawGameMap(); |
||
1092 | //drawScore(); |
||
1093 | // |
||
1094 | //kos_Pause( 25 ); |
||
1095 | // |
||
1096 | while ( insertNewBlocks() > 0 ) |
||
1097 | { |
||
1098 | // |
||
1099 | fallDownBlocks(); |
||
1100 | // |
||
1101 | //drawGameMap(); |
||
1102 | //kos_Pause( 30 ); |
||
1103 | } |
||
1104 | } |
||
1105 | // |
||
1106 | drawScore(); |
||
1107 | // |
||
1108 | levelProgressCount = ( ( ( insertedBlocksCount > levelBlocksLimit ) ? levelBlocksLimit : insertedBlocksCount ) * levelProgressStep ) / 1024; |
||
1109 | // |
||
1110 | drawGameMeters(); |
||
1111 | // |
||
1112 | if ( insertedBlocksCount > levelBlocksLimit ) |
||
1113 | { |
||
1114 | kos_Pause( 50 ); |
||
1115 | gameLevel++; |
||
1116 | SetLevelVariables(); |
||
1117 | // |
||
1118 | //initGameMap(); |
||
1119 | // |
||
1120 | //DrawGameWindow(); |
||
1121 | // |
||
1122 | drawGameMeters(); |
||
1123 | drawLevelNum(); |
||
1124 | } |
||
1125 | else |
||
1126 | // |
||
1127 | if ( mouseButtonDisabled = checkGameOut() ) |
||
1128 | { |
||
1129 | // |
||
1130 | DrawGameWindow(); |
||
1131 | } |
||
1132 | } |
||
1133 | else |
||
1134 | { |
||
1135 | // не получается линии, блоки ставим на место |
||
1136 | flipTwoBlocks( ndx, selectedBlock ); |
||
1137 | // снимаем пометку с блока |
||
1138 | selectedBlock = SELECTED_BLOCK_NONE; |
||
1139 | } |
||
1140 | } |
||
1141 | else // выбран несоседний блок |
||
1142 | { |
||
1143 | // перестим маркер |
||
1144 | kos_PutImage( |
||
1145 | fishki[gameMap[selectedBlock]]->GetBits(), |
||
1146 | blockSize, blockSize, |
||
1147 | selX * blockSize + blocksLeft, |
||
1148 | selY * blockSize + blocksTop |
||
1149 | ); |
||
1150 | // пометим выбранный блок |
||
1151 | selectedBlock = ndx; |
||
1152 | // на игровом поле |
||
1153 | kos_PutImage( |
||
1154 | fishki[gameMap[selectedBlock]]->GetHighlightedBits(), |
||
1155 | blockSize, blockSize, |
||
1156 | blX * blockSize + blocksLeft, |
||
1157 | blY * blockSize + blocksTop |
||
1158 | ); |
||
1159 | } |
||
1160 | } |
||
1161 | else // выбран тот же блок |
||
1162 | { |
||
1163 | // снимаем пометку |
||
1164 | kos_PutImage( |
||
1165 | fishki[gameMap[selectedBlock]]->GetBits(), |
||
1166 | blockSize, blockSize, |
||
1167 | selX * blockSize + blocksLeft, |
||
1168 | selY * blockSize + blocksTop |
||
1169 | ); |
||
1170 | // |
||
1171 | selectedBlock = SELECTED_BLOCK_NONE; |
||
1172 | } |
||
1173 | } |
||
1174 | else |
||
1175 | // ткнули в блок при выбранном бонусе |
||
1176 | { |
||
1177 | // |
||
1178 | mCode = gameMap[ndx]; |
||
1179 | // |
||
1180 | switch ( selectedBlock ) |
||
1181 | { |
||
1182 | case BONUS_SOMEBLOCK_SELECTED: |
||
1183 | gameMap[ndx] = bonusSomeBlock; |
||
1184 | break; |
||
1185 | |||
1186 | case BONUS_FREEBLOCK_SELECTED: |
||
1187 | gameMap[ndx] = BONUS_FREE_BLOCK; |
||
1188 | break; |
||
1189 | |||
1190 | default: |
||
1191 | break; |
||
1192 | } |
||
1193 | // |
||
1194 | if ( findBlockLines() > 0 ) |
||
1195 | { |
||
1196 | // убираем использованный бонус |
||
1197 | switch ( selectedBlock ) |
||
1198 | { |
||
1199 | case BONUS_SOMEBLOCK_SELECTED: |
||
1200 | bonusSomeBlock = 0; |
||
1201 | break; |
||
1202 | |||
1203 | case BONUS_FREEBLOCK_SELECTED: |
||
1204 | bonusFreeBlock = false; |
||
1205 | break; |
||
1206 | |||
1207 | default: |
||
1208 | break; |
||
1209 | } |
||
1210 | // на экране тоже |
||
1211 | drawBonuses(); |
||
1212 | drawGameMap(); |
||
1213 | kos_Pause( 16 ); |
||
1214 | // убираем блоки |
||
1215 | // снимаем пометку с блока |
||
1216 | selectedBlock = SELECTED_BLOCK_NONE; |
||
1217 | // |
||
1218 | while ( exterminateLines() ) |
||
1219 | { |
||
1220 | // |
||
1221 | fadeOutBlocks(); |
||
1222 | // |
||
1223 | //drawGameMap(); |
||
1224 | //drawScore(); |
||
1225 | // |
||
1226 | //kos_Pause( 25 ); |
||
1227 | // |
||
1228 | while ( insertNewBlocks() > 0 ) |
||
1229 | { |
||
1230 | // |
||
1231 | fallDownBlocks(); |
||
1232 | // |
||
1233 | //drawGameMap(); |
||
1234 | //kos_Pause( 30 ); |
||
1235 | } |
||
1236 | } |
||
1237 | // |
||
1238 | drawScore(); |
||
1239 | // |
||
1240 | levelProgressCount = ( ( ( insertedBlocksCount > levelBlocksLimit ) ? levelBlocksLimit : insertedBlocksCount ) * levelProgressStep ) / 1024; |
||
1241 | // |
||
1242 | drawGameMeters(); |
||
1243 | // |
||
1244 | if ( insertedBlocksCount > levelBlocksLimit ) |
||
1245 | { |
||
1246 | kos_Pause( 50 ); |
||
1247 | gameLevel++; |
||
1248 | SetLevelVariables(); |
||
1249 | // |
||
1250 | //initGameMap(); |
||
1251 | // |
||
1252 | //DrawGameWindow(); |
||
1253 | // |
||
1254 | drawGameMeters(); |
||
1255 | drawLevelNum(); |
||
1256 | } |
||
1257 | else |
||
1258 | // |
||
1259 | mouseButtonDisabled = checkGameOut(); |
||
1260 | } |
||
1261 | else |
||
1262 | // бонус здесь неприменим |
||
1263 | { |
||
1264 | // вернём взад |
||
1265 | gameMap[ndx] = mCode; |
||
1266 | // пометим блок |
||
1267 | selectedBlock = ndx; |
||
1268 | // на игровом поле |
||
1269 | kos_PutImage( |
||
1270 | fishki[gameMap[selectedBlock]]->GetHighlightedBits(), |
||
1271 | blockSize, blockSize, |
||
1272 | blX * blockSize + blocksLeft, |
||
1273 | blY * blockSize + blocksTop |
||
1274 | ); |
||
1275 | // уберём пометку с бонуса |
||
1276 | drawBonuses(); |
||
1277 | } |
||
1278 | } |
||
1279 | } |
||
1280 | // определим кнопку |
||
1281 | kos_DefineButton( |
||
1282 | 444+1, 2+21, |
||
1283 | 54, 20, |
||
1284 | 0x6000000A, |
||
1285 | |||
1286 | ); |
||
1287 | // завершаем перерисовку |
||
1288 | kos_WindowRedrawStatus( WRS_END ); |
||
1289 | } |
||
1290 | } |
||
1291 | else |
||
1292 | // проверим попадание в бонусы |
||
1293 | { |
||
1294 | nSel = 0; |
||
1295 | // |
||
1296 | if ( mX >= BONUS_SOMEBLOCK_LEFT && (mX - BONUS_SOMEBLOCK_LEFT) <= blockSize |
||
1297 | && mY >= BONUS_SOMEBLOCK_TOP && (mY - BONUS_SOMEBLOCK_TOP ) <= blockSize ) |
||
1298 | { |
||
1299 | // |
||
1300 | nSel = BONUS_SOMEBLOCK_SELECTED; |
||
1301 | } |
||
1302 | // |
||
1303 | if ( mX >= BONUS_FREEBLOCK_LEFT && (mX - BONUS_FREEBLOCK_LEFT) <= blockSize |
||
1304 | && mY >= BONUS_FREEBLOCK_TOP && (mY - BONUS_FREEBLOCK_TOP ) <= blockSize ) |
||
1305 | { |
||
1306 | // |
||
1307 | nSel = BONUS_FREEBLOCK_SELECTED; |
||
1308 | } |
||
1309 | // |
||
1310 | if ( mX >= BONUS_DIAGBLOCK_LEFT && (mX - BONUS_DIAGBLOCK_LEFT) <= blockSize |
||
1311 | && mY >= BONUS_DIAGBLOCK_TOP && (mY - BONUS_DIAGBLOCK_TOP ) <= blockSize ) |
||
1312 | { |
||
1313 | // |
||
1314 | nSel = BONUS_DIAGBLOCK_SELECTED; |
||
1315 | } |
||
1316 | // |
||
1317 | if ( nSel != 0 ) |
||
1318 | { |
||
1319 | // |
||
1320 | if ( selectedBlock > 0 ) |
||
1321 | { |
||
1322 | // снимаем пометку |
||
1323 | kos_PutImage( |
||
1324 | fishki[gameMap[selectedBlock]]->GetBits(), |
||
1325 | blockSize, blockSize, |
||
1326 | (selectedBlock % mapSize) * blockSize + blocksLeft, |
||
1327 | (selectedBlock / mapSize) * blockSize + blocksTop |
||
1328 | ); |
||
1329 | } |
||
1330 | // |
||
1331 | if ( selectedBlock != nSel ) |
||
1332 | selectedBlock = nSel; |
||
1333 | else |
||
1334 | selectedBlock = SELECTED_BLOCK_NONE; |
||
1335 | // |
||
1336 | drawBonuses(); |
||
1337 | } |
||
1338 | } |
||
1339 | |||
1340 | } |
||
1341 | // |
||
1342 | break; |
||
1343 | |||
1344 | default: |
||
1345 | break; |
||
1346 | } |
||
1347 | } |
||
1348 | // отменим кнопку |
||
1349 | kos_DefineButton( |
||
1350 | 0, 0, |
||
1351 | 0, 0, |
||
1352 | 0x8000000A, |
||
1353 | |||
1354 | ); |
||
1355 | // |
||
1356 | if ( gameLevel > maxGameLevel ) maxGameLevel = gameLevel; |
||
1357 | // |
||
1358 | return result; |
||
1359 | } |
||
1360 | |||
1361 | // |
||
1362 | void drawLevelNum() |
||
1363 | { |
||
1364 | Word startX; |
||
1365 | |||
1366 | // |
||
1367 | if ( gameLevel > 9 ) |
||
1368 | { |
||
1369 | // |
||
1370 | startX = LEVEL_LEFT; |
||
1371 | // |
||
1372 | kos_PutImage( |
||
1373 | gameNumbers.GetBits() + ( ( gameLevel / 10 ) * NUM_WIDTH * NUM_HEIGHT ), |
||
1374 | NUM_WIDTH, NUM_HEIGHT, |
||
1375 | startX, LEVEL_TOP |
||
1376 | ); |
||
1377 | // |
||
1378 | startX += NUM_WIDTH; |
||
1379 | } |
||
1380 | else |
||
1381 | { |
||
1382 | // |
||
1383 | startX = LEVEL_LEFT + ( (LEVEL_WIDTH - NUM_WIDTH) / 2 ); |
||
1384 | } |
||
1385 | // |
||
1386 | kos_PutImage( |
||
1387 | gameNumbers.GetBits() + ( ( gameLevel % 10 ) * NUM_WIDTH * NUM_HEIGHT ), |
||
1388 | NUM_WIDTH, NUM_HEIGHT, |
||
1389 | startX, LEVEL_TOP |
||
1390 | ); |
||
1391 | } |
||
1392 | |||
1393 | // |
||
1394 | void drawScore() |
||
1395 | { |
||
1396 | Word startX; |
||
1397 | int i, j; |
||
1398 | char strNum[8]; |
||
1399 | |||
1400 | // число в текстовом виде |
||
1401 | sprintf( strNum, "%U", playerScore ); |
||
1402 | // |
||
1403 | j = strlen( strNum ); |
||
1404 | // |
||
1405 | startX = SCORE_LEFT + ( ( SCORE_WIDTH - ( NUM_WIDTH * j ) ) / 2 ); |
||
1406 | // |
||
1407 | for ( i = 0; i < j; i++ ) |
||
1408 | { |
||
1409 | // |
||
1410 | kos_PutImage( |
||
1411 | gameNumbers.GetBits() + ( ( strNum[i] - '0' ) * NUM_WIDTH * NUM_HEIGHT ), |
||
1412 | NUM_WIDTH, NUM_HEIGHT, |
||
1413 | startX, SCORE_TOP |
||
1414 | ); |
||
1415 | // |
||
1416 | startX += NUM_WIDTH; |
||
1417 | } |
||
1418 | } |
||
1419 | |||
1420 | |||
1421 | // |
||
1422 | void DrawGameWindow() |
||
1423 | { |
||
1424 | // |
||
1425 | kos_WindowRedrawStatus( WRS_BEGIN ); |
||
1426 | // окно |
||
1427 | kos_DefineAndDrawWindow( |
||
1428 | WNDLEFT, WNDTOP, |
||
1429 | gcx + 1, gcy + 21, |
||
1430 | 0, 0x0, |
||
1431 | 0, WNDHEADCOLOUR, |
||
1432 | WNDHEADCOLOUR |
||
1433 | ); |
||
1434 | // заголовок окна |
||
1435 | kos_WriteTextToWindow( |
||
1436 | 4, 7, |
||
1437 | 0x10, WNDTITLECOLOUR, |
||
1438 | gameWndTitle, strlen(gameWndTitle) |
||
1439 | ); |
||
1440 | // |
||
1441 | gameFace.Draw( 1, 21 ); |
||
1442 | drawGameMap(); |
||
1443 | drawGameMeters(); |
||
1444 | drawBonuses(); |
||
1445 | // номер уровня |
||
1446 | drawLevelNum(); |
||
1447 | drawScore(); |
||
1448 | // |
||
1449 | if ( mouseButtonDisabled ) |
||
1450 | { |
||
1451 | // |
||
1452 | kos_DrawBar( |
||
1453 | ( gcx + 1 - 160 ) / 2, ( gcy + 21 - 32 ) / 2, |
||
1454 | 160, 32, |
||
1455 | 0x2383B3 |
||
1456 | ); |
||
1457 | // |
||
1458 | kos_WriteTextToWindow( |
||
1459 | ( gcx + 1 - sizeof( gameOverText ) * 6 ) / 2, ( gcy + 21 - 9 ) / 2, |
||
1460 | 0x0, 0xF7F7F7, |
||
1461 | gameOverText, |
||
1462 | sizeof( gameOverText ) |
||
1463 | ); |
||
1464 | } |
||
1465 | // определим кнопку |
||
1466 | kos_DefineButton( |
||
1467 | 444+1, 2+21, |
||
1468 | 54, 20, |
||
1469 | 0x6000000A, |
||
1470 | |||
1471 | ); |
||
1472 | // |
||
1473 | kos_WindowRedrawStatus( WRS_END ); |
||
1474 | } |
||
1475 | |||
1476 | |||
1477 | // |
||
1478 | void fadeOutBlocks() |
||
1479 | { |
||
1480 | int i, j, k, ndx, x, y; |
||
1481 | |||
1482 | // |
||
1483 | j = toRemoveList.GetCount(); |
||
1484 | // |
||
1485 | for ( k = 0; k < 4; k++ ) |
||
1486 | { |
||
1487 | // |
||
1488 | __asm{ |
||
1489 | push eax |
||
1490 | push ebx |
||
1491 | mov eax, 18 |
||
1492 | mov ebx, 14 |
||
1493 | int 0x40 |
||
1494 | pop eax |
||
1495 | pop ebx |
||
1496 | } |
||
1497 | // |
||
1498 | for ( i = 0; i < j; i++ ) |
||
1499 | { |
||
1500 | // |
||
1501 | ndx = toRemoveList[i].ndx; |
||
1502 | y = ndx / mapSize; |
||
1503 | x = ndx % mapSize; |
||
1504 | // |
||
1505 | kos_PutImage( |
||
1506 | gameBlocksZ[k].GetBits() + ( (toRemoveList[i].value - 1) * blockSize * blockSize ), |
||
1507 | blockSize, blockSize, |
||
1508 | (x * blockSize) + blocksLeft, |
||
1509 | (y * blockSize) + blocksTop |
||
1510 | ); |
||
1511 | } |
||
1512 | // |
||
1513 | kos_Pause( 3 ); |
||
1514 | } |
||
1515 | //clear |
||
1516 | for ( i = 0; i < j; i++ ) |
||
1517 | { |
||
1518 | // |
||
1519 | ndx = toRemoveList[i].ndx; |
||
1520 | y = ndx / mapSize; |
||
1521 | x = ndx % mapSize; |
||
1522 | // |
||
1523 | kos_DrawBar( |
||
1524 | (x * blockSize) + blocksLeft, |
||
1525 | (y * blockSize) + blocksTop, |
||
1526 | blockSize, blockSize, 0 |
||
1527 | ); |
||
1528 | } |
||
1529 | // |
||
1530 | kos_Pause( 16 ); |
||
1531 | } |
||
1532 | |||
1533 | |||
1534 | // |
||
1535 | void fallDownBlocks() |
||
1536 | { |
||
1537 | int i, j, k, ndx, x, y, height, offset; |
||
1538 | |||
1539 | // |
||
1540 | j = toFallList.GetCount(); |
||
1541 | // |
||
1542 | for ( k = 1; k <= blockSize; k += 2 ) |
||
1543 | { |
||
1544 | // |
||
1545 | __asm{ |
||
1546 | push eax |
||
1547 | push ebx |
||
1548 | mov eax, 18 |
||
1549 | mov ebx, 14 |
||
1550 | int 0x40 |
||
1551 | pop eax |
||
1552 | pop ebx |
||
1553 | } |
||
1554 | // |
||
1555 | for ( i = 0; i < j; i++ ) |
||
1556 | { |
||
1557 | // |
||
1558 | ndx = toFallList[i]; |
||
1559 | // |
||
1560 | y = ( ( ( ndx / mapSize ) - 1 ) * blockSize ) + k; |
||
1561 | if ( y < 0 ) |
||
1562 | { |
||
1563 | y = 0; |
||
1564 | height = k; |
||
1565 | offset = blockSize - k; |
||
1566 | } |
||
1567 | else |
||
1568 | { |
||
1569 | offset = 0; |
||
1570 | height = blockSize; |
||
1571 | } |
||
1572 | // |
||
1573 | x = ( ndx % mapSize ) * blockSize; |
||
1574 | // |
||
1575 | kos_PutImage( |
||
1576 | fishki[gameMap[ndx]]->GetBits() + ( offset * blockSize ), |
||
1577 | blockSize, height, |
||
1578 | x + blocksLeft, |
||
1579 | y + blocksTop |
||
1580 | ); |
||
1581 | } |
||
1582 | // |
||
1583 | kos_Pause( 1 ); |
||
1584 | } |
||
1585 | }>>=>>>>>=>=>=>=>=>=>>>>>>>>=>=>=>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> |