* Remove most unused WIN32 stuff.
[matthijs/ABM2.git] / ABM2 / Playground.cpp
1 #include "Playground.h"\r
2 \r
3 #include "Engine/engine.h"\r
4 #include "Engine/VideoUpdate.h"\r
5 #include "SchemeReader.h"\r
6 \r
7 Playground::Playground(CKernel* kernel) : ITask(kernel) { }\r
8 \r
9 bool Playground::Start()\r
10 {\r
11         // init playing field\r
12         SchemeReader *scheme = new SchemeReader("Data/schemes/BASIC.SCH");\r
13 \r
14         CMMPointer<Sprite> tile_sprite = this->getKernel()->getSpriteManager()->getSprite(SPR_TILE);\r
15         // put in non-destructible blocks\r
16         for (int col=0; col<PLAYGROUND_COLS; col++) \r
17         {\r
18                 for (int row=0; row<PLAYGROUND_ROWS; row++)\r
19                 {\r
20                         int subsprite = -1;\r
21                         switch(scheme->PlayField[row*PLAYGROUND_NUMFIELD_X+col]) {\r
22                                 case BRICK:\r
23                                         subsprite = SPR_SUB_BRICK;\r
24                                         break;\r
25                                 case SOLID:\r
26                                         subsprite = SPR_SUB_SOLID;\r
27                                         break;\r
28                         }\r
29                         if (subsprite != -1)\r
30                                 field[col][row] = new Tile(tile_sprite, subsprite, col, row);\r
31                         else\r
32                                 field[col][row] = NULL;\r
33                 }\r
34         }\r
35 /*\r
36         // put in desctructible blocks with chance 90%\r
37         for (int i=0; i<PLAYGROUND_COLS; i+=2) \r
38                 for (int j=0; j<PLAYGROUND_ROWS; ++j)\r
39                         if ((double)rand()/RAND_MAX <= 0.9) field[i][j] = new Tile(foreground, 0, i, j);\r
40         for (int i=1; i<PLAYGROUND_COLS; i+=2) \r
41                 for (int j=0; j<PLAYGROUND_ROWS; j+=2)\r
42                         if ((double)rand()/RAND_MAX <= 0.9) field[i][j] = new Tile(foreground, 0, i, j);\r
43 */      \r
44         // put in a player\r
45         bomberman = new Bomberman(20, 66);\r
46         if (field[0][0] != NULL)\r
47         {\r
48                 delete field[0][0];\r
49                 field[0][0] = NULL;\r
50         }\r
51         if (field[1][0] != NULL)\r
52         {\r
53                 delete field[1][0];\r
54                 field[1][0] = NULL;\r
55         }\r
56         if (field[0][1] != NULL)\r
57         {\r
58                 delete field[0][1];\r
59                 field[0][1] = NULL;\r
60         }\r
61 \r
62         old_counter = GetTickCount();\r
63         return true;\r
64 }\r
65 \r
66 void Playground::Update()\r
67 {\r
68         CMMPointer<Sprite> s = this->getKernel()->getSpriteManager()->getSprite(SPR_FIELD);\r
69         \r
70         s->blit(0, 0, 1.0, 1.0, 0, 0, COLOUR_RGBA(255, 255, 255, 255));\r
71         for (int i=0; i<PLAYGROUND_COLS; ++i) \r
72         {\r
73                 for (int j=0; j<PLAYGROUND_ROWS; ++j)\r
74                 {\r
75                         if (field[i][j] != NULL) field[i][j]->Draw();\r
76                 }\r
77         }\r
78 \r
79         #ifdef WIN32\r
80         bomberman->Update();\r
81         if (CInputTask::keyDown(DIK_RIGHT)) this->move_right();\r
82         if (CInputTask::keyDown(DIK_LEFT)) this->move_left();\r
83         if (CInputTask::keyDown(DIK_UP)) this->move_up();\r
84         if (CInputTask::keyDown(DIK_DOWN)) this->move_down();\r
85 \r
86 \r
87         d3dspt->End();    // end sprite drawing\r
88 \r
89         // do fps thingie\r
90         RECT rect = {10,10,400,36};\r
91         char buf[105];\r
92         DWORD new_counter = GetTickCount();\r
93         DWORD tmp = new_counter-old_counter;\r
94         double tmp2 = 1 / (double(tmp) / 1000.0f);\r
95         /*      if (tmp == 0)\r
96                 _itoa_s(0, buf, 5, 10);\r
97         else\r
98 */\r
99         //_gcvt_s(buf, 105, tmp2, 4);\r
100         sprintf(buf, "%2.2f", tmp2);\r
101         font->DrawTextA(NULL, (char *)&buf, -1, &rect, DT_LEFT, D3DCOLOR_XRGB(255,255,255));\r
102 \r
103         //draw coordinates\r
104         RECT rect2 = {210,10,300,36};\r
105         sprintf(buf, "(%d, %d)", bomberman->getX(), bomberman->getY());\r
106         font->DrawTextA(NULL, (char *)&buf, -1, &rect2, DT_LEFT, D3DCOLOR_XRGB(255,255,255));\r
107 \r
108         //draw bomberman_array position\r
109         RECT rect3 = {310,10,500,36};\r
110         sprintf(buf, "(%d, %d) - (%d,%d)", bomberman->getFieldCenterX(), bomberman->getFieldCenterY(), bomberman->getOffsetX(), bomberman->getOffsetY());\r
111         font->DrawTextA(NULL, (char *)&buf, -1, &rect3, DT_LEFT, D3DCOLOR_XRGB(255,255,255));\r
112         #endif // WIN32\r
113 \r
114         old_counter = GetTickCount();\r
115 }\r
116 \r
117 void Playground::Stop()\r
118 {\r
119         for (int i=0; i<PLAYGROUND_COLS; ++i) \r
120                 for (int j=0; j<PLAYGROUND_ROWS; ++j)\r
121                         if (field[i][j] != NULL) delete field[i][j];\r
122 \r
123         if (bomberman != NULL) delete bomberman;\r
124 }\r
125 \r
126 void Playground::move_down()\r
127 {\r
128         // first check to stay within the playground\r
129         if ((bomberman->getY() + bomberman->getHeight()) < (PLAYGROUND_BORDER_TOP + FIELD_UNIT_HEIGHT * PLAYGROUND_ROWS))\r
130         { // i can go down\r
131                 int array_x = bomberman->getFieldCenterX();\r
132                 int array_left = array_x-1;\r
133                 int array_right = array_x+1;\r
134                 int array_y = bomberman->getFieldCenterY();\r
135                 int array_below = array_y+1;\r
136 \r
137                 if ((array_below <= PLAYGROUND_ROWS) && (field[array_x][array_below] == NULL) &&\r
138                         (bomberman->getOffsetX() == 0))//center of field\r
139                 {\r
140                         //bomberman->move_to(array_x, array_below);\r
141                         bomberman->move_to_direction(S);\r
142                         return;\r
143                 }\r
144                 //special cases for down-left :P\r
145                 if ((field[array_x][array_below] == NULL) && (bomberman->getOffsetX() == 10) && (bomberman->getOffsetY()%2 == 1))\r
146                 {\r
147                         bomberman->move_to_direction(SW);\r
148                         return;\r
149                 }\r
150                 if ((field[array_x][array_below] == NULL) && (bomberman->getOffsetX() == 12) && (bomberman->getOffsetY() == 0))\r
151                 {\r
152                         bomberman->move_to_direction(SW);\r
153                         return;\r
154                 }\r
155 \r
156                 //directly above (according to getCenterX), offset 0-18, down left\r
157                 if ((field[array_x][array_below] == NULL) &&\r
158                         (bomberman->getOffsetX() >= (FIELD_UNIT_HEIGHT/3)))\r
159                 {\r
160                         bomberman->move_to_direction(SWW);\r
161                         return;\r
162                 }\r
163                 if ((field[array_x][array_below] == NULL) &&\r
164                         (bomberman->getOffsetX() < (FIELD_UNIT_HEIGHT/3)))\r
165                 {\r
166                         bomberman->move_to_direction(SSW);\r
167                         return;\r
168                 }\r
169                 //offset 20-36 = down left\r
170                 if ((field[array_left][array_below] == NULL) && (field[array_x][array_below] != NULL) &&\r
171                         (bomberman->getOffsetX() >= (FIELD_UNIT_WIDTH/2)) && (bomberman->getOffsetX() < FIELD_UNIT_WIDTH-2))\r
172                 {\r
173                         bomberman->move_to_direction(SWW);\r
174                         return;\r
175                 }\r
176                 //offset 4-18 = down right\r
177                 if ((field[array_right][array_below] == NULL) && (field[array_x][array_below] != NULL) && \r
178                         (bomberman->getOffsetX() < (FIELD_UNIT_WIDTH/2)) && (bomberman->getOffsetX() > 2))\r
179                 {\r
180                         bomberman->move_to_direction(SEE);\r
181                         return;\r
182                 }\r
183                 //directly above (according to getCenterX), offset 20-38, down right\r
184                 if ((field[array_x][array_below] == NULL) &&\r
185                         (bomberman->getOffsetX() >= (FIELD_UNIT_WIDTH-FIELD_UNIT_HEIGHT/3)))\r
186                 {\r
187                         bomberman->move_to_direction(SEE);\r
188                         return;\r
189                 }\r
190                 if ((field[array_x][array_below] == NULL))\r
191                 {\r
192                         bomberman->move_to_direction(SSE);\r
193                 }\r
194         }\r
195 }\r
196 \r
197 void Playground::move_up()\r
198 {\r
199         // first check to stay within the playground\r
200         if (bomberman->getY() > PLAYGROUND_BORDER_TOP)\r
201         { // i can go up\r
202                 int array_x = bomberman->getFieldCenterX();\r
203                 int array_left = array_x-1;\r
204                 int array_right = array_x+1;\r
205                 int array_y = bomberman->getFieldCenterY();\r
206                 int array_above = array_y-1;\r
207 \r
208                 if ((array_above == -1) || (field[array_x][array_above] == NULL))\r
209                 {\r
210                         bomberman->move_to(array_x, array_above);\r
211                         return;\r
212                 }\r
213                 if ((field[array_left][array_above] == NULL) && (field[array_x][array_above] != NULL) && \r
214                         (bomberman->getCenterX()-PLAYGROUND_BORDER_LEFT < (array_x*40+20)))//linkerkant van midden\r
215                 {\r
216                         bomberman->move_to(array_left, array_above);\r
217                         return;\r
218                 }\r
219                 if ((field[array_right][array_above] == NULL) && (field[array_x][array_above] != NULL) && \r
220                         (bomberman->getCenterX()-PLAYGROUND_BORDER_LEFT > (array_x*40+20)))//rechts van midden\r
221                 {\r
222                         bomberman->move_to(array_right, array_above);\r
223                         return;\r
224                 }\r
225         }\r
226 }\r
227 \r
228 void Playground::move_left()\r
229 {\r
230         // first check to stay within the playground\r
231         if (bomberman->getX() > PLAYGROUND_BORDER_LEFT)\r
232         { // i can go left\r
233                 int array_x = bomberman->getFieldCenterX();\r
234                 int array_left = array_x-1;\r
235                 int array_y = bomberman->getFieldCenterY();\r
236                 int array_below = array_y+1;\r
237                 int array_above = array_y-1;\r
238 \r
239                 if ((array_left == -1) || (field[array_left][array_y] == NULL))\r
240                 {\r
241                         bomberman->move_to(array_left, array_y);\r
242                         return;\r
243                 }\r
244                 if ((field[array_left][array_above] == NULL) && (field[array_left][array_y] != NULL) && \r
245                         (bomberman->getCenterY()-PLAYGROUND_BORDER_TOP < (array_y*36+18)))\r
246                 {\r
247                         bomberman->move_to(array_left, array_above);\r
248                         return;\r
249                 }\r
250                 if ((field[array_left][array_below] == NULL) && (field[array_left][array_y] != NULL) && \r
251                         (bomberman->getCenterY()-PLAYGROUND_BORDER_TOP > (array_y*36+18)))\r
252                 {\r
253                         bomberman->move_to(array_left, array_below);\r
254                         return;\r
255                 }\r
256         }\r
257 }\r
258 \r
259 void Playground::move_right()\r
260 {\r
261         // first check to stay within the playground\r
262         if ((bomberman->getX() + bomberman->getWidth()) < (20 + 40 * PLAYGROUND_COLS))\r
263         { // i can go right\r
264                 int array_x = bomberman->getFieldCenterX();\r
265                 int array_right = array_x+1;\r
266                 int array_y = bomberman->getFieldCenterY();\r
267                 int array_below = array_y+1;\r
268                 int array_above = array_y-1;\r
269 \r
270                 if ((array_right < PLAYGROUND_COLS) && (field[array_right][array_y] == NULL))\r
271                 {\r
272                         bomberman->move_to(array_right, array_y);\r
273                         return;\r
274                 }\r
275                 if ((field[array_right][array_above] == NULL) && (field[array_right][array_y] != NULL) && (bomberman->getCenterY()-PLAYGROUND_BORDER_TOP < (array_y*36+18)))\r
276                 {\r
277                         bomberman->move_to(array_right, array_above);\r
278                         return;\r
279                 }\r
280                 if ((field[array_right][array_below] == NULL) && (field[array_right][array_y] != NULL) && (bomberman->getCenterY()-PLAYGROUND_BORDER_TOP > (array_y*36+18)))\r
281                 {\r
282                         bomberman->move_to(array_right, array_below);\r
283                         return;\r
284                 }\r
285         }\r
286 }\r
287 \r
288 // =============================================\r
289 // Bomberman class\r
290 // =============================================\r
291 \r
292 Bomberman::Bomberman(int xloc, int yloc)\r
293 {\r
294         #ifdef WIN32\r
295         HRESULT res = D3DXCreateTextureFromFile(d3ddev, L"data/powkick.png", &texture);\r
296         if (res != D3D_OK) texture = NULL;\r
297         #endif // WIN32\r
298         x = xloc;\r
299         y = yloc;\r
300 }\r
301 \r
302 Bomberman::~Bomberman()\r
303 {\r
304         #ifdef WIN32\r
305         if (texture != NULL) texture->Release();\r
306         #endif // WIN32\r
307 }\r
308 \r
309 void Bomberman::Update()\r
310 {\r
311         #ifdef WIN32\r
312         D3DXVECTOR3 center(0.0f, 0.0f, 0.0f);    // center at the upper-left corner\r
313         D3DXVECTOR3 position((FLOAT)x, (FLOAT)y, 0.0f);    // position at 50, 50 with no depth\r
314         RECT rect = {0,0,40,36};\r
315         d3dspt->Draw(texture, &rect, &center, &position, D3DCOLOR_XRGB(255,255,255));\r
316         #endif // WIN32\r
317 }\r
318 \r
319 void Bomberman::move(int xloc, int yloc)\r
320 {\r
321         x += xloc;\r
322         y += yloc;\r
323 }\r
324 \r
325 int Bomberman::getY()\r
326 {\r
327         return y;\r
328 }\r
329 \r
330 int Bomberman::getX()\r
331 {\r
332         return x;\r
333 }\r
334 \r
335 int Bomberman::getHeight()\r
336 {\r
337         return 36;\r
338 }\r
339 \r
340 int Bomberman::getWidth()\r
341 {\r
342         return 40;\r
343 }\r
344 \r
345 int Bomberman::getCenterX()\r
346 {\r
347         return (this->getX()+(FIELD_UNIT_WIDTH/2));\r
348 }\r
349 \r
350 int Bomberman::getCenterY()\r
351 {\r
352         return (this->getY()+(FIELD_UNIT_HEIGHT/2));\r
353 }\r
354 \r
355 int Bomberman::getOffsetX()\r
356 {\r
357         return (this->getX()- PLAYGROUND_BORDER_LEFT) % FIELD_UNIT_WIDTH;\r
358 }\r
359 \r
360 int Bomberman::getOffsetY()\r
361 {\r
362         return (this->getY()- PLAYGROUND_BORDER_TOP) % FIELD_UNIT_HEIGHT;\r
363 }\r
364 \r
365 int Bomberman::getFieldCenterX()\r
366 {\r
367         return (this->getCenterX() - PLAYGROUND_BORDER_LEFT)/FIELD_UNIT_WIDTH;\r
368 }\r
369 \r
370 int Bomberman::getFieldCenterY()\r
371 {\r
372         return (this->getCenterY() - PLAYGROUND_BORDER_TOP)/FIELD_UNIT_HEIGHT;\r
373 }\r
374 \r
375 void Bomberman::move_to(int xloc, int yloc)\r
376 {\r
377         /*\r
378         float center_x = (xloc-1)*40+20+20;\r
379         float center_y = (yloc-1)*36+66+18;\r
380         float dist_x = center_x - this->x;\r
381         float dist_y = center_y - this->y;\r
382 \r
383         double dist = sqrt(dist_x*dist_x + dist_y*dist_y);\r
384         */\r
385         int x_move = (xloc*FIELD_UNIT_WIDTH+PLAYGROUND_BORDER_LEFT) - x;\r
386         int y_move = (yloc*FIELD_UNIT_HEIGHT+PLAYGROUND_BORDER_TOP) - y;\r
387 \r
388         if ((x_move == 0) && (y_move > 0)) this->move(0,2);\r
389         if ((x_move == 0) && (y_move < 0)) this->move(0,-2);\r
390         if ((y_move == 0) && (x_move > 0)) this->move(2,0);\r
391         if ((y_move == 0) && (x_move < 0)) this->move(-2,0);\r
392         if ((x_move < 0) && (y_move < 0)) this->move(-1,-1);\r
393         if ((x_move < 0) && (y_move > 0)) this->move(-1,1);\r
394         if ((x_move > 0) && (y_move < 0)) this->move(1,-1);\r
395         if ((x_move > 0) && (y_move > 0)) this->move(1,1);\r
396 }\r
397 \r
398 void Bomberman::move_to_direction(TMoveDirection dir)\r
399 {\r
400         switch(dir)\r
401         {\r
402                 case N: this->move(0,-2); break;\r
403                 case NNE: this->move(1,-2); break;\r
404                 case NE: this->move(1,-1); break;\r
405                 case NEE: this->move(2,-1); break;\r
406                 case E: this->move(2,0); break;\r
407                 case SEE: this->move(2,1); break;\r
408                 case SE: this->move(1,1); break;\r
409                 case SSE: this->move(1,2); break;\r
410                 case S: this->move(0,2); break;\r
411                 case SSW: this->move(-1,2); break;\r
412                 case SW: this->move(-1,1); break;\r
413                 case SWW: this->move(-2,1); break;\r
414                 case W: this->move(-2,0); break;\r
415                 case NWW: this->move(-2,-1); break;\r
416                 case NW: this->move(-1,-1); break;\r
417                 case NNW: this->move(-1,-2); break;\r
418         }\r
419 }\r
420 \r
421 // =============================================\r
422 // Tile class\r
423 // =============================================\r
424 \r
425 Tile::Tile(const CMMPointer<Sprite> &sprite, int subsprite, int col, int row)\r
426 {\r
427         this->sprite = sprite;\r
428         this->col = col;\r
429         this->row = row;\r
430         this->subsprite = subsprite;\r
431 }\r
432 \r
433 Tile::~Tile()\r
434 {\r
435 }\r
436 void Tile::Draw()\r
437 {\r
438         this->sprite->blit(\r
439                 PLAYGROUND_BORDER_LEFT + this->col * FIELD_UNIT_WIDTH,\r
440                 PLAYGROUND_BORDER_TOP + this->row * FIELD_UNIT_HEIGHT,\r
441                 1.0, 1.0, this->subsprite, 0, COLOUR_RGBA(255, 255, 255, 255)\r
442         );\r
443 }\r
444 \r