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