1 //需要虫子的二值图,瓶口的二值图,医生的彩色图,bmp格式
2 //需要学会读取bmp格式图片并处理
3 //move函数的代码,预计50行左右
4
5 /* 作者:PureMilk
6 天地之灵学习小组
7 */
8
9 #include <GL/glut.h>
10 #include <ctime>
11 #include <cstdlib>
12 #include <cmath>
13 #include <cstdio>
14 #include <windows.h>
15
16 static const int WindowWidth = 640;
17 static const int WindowHeight = 480;
18
19 int count = 0;
20 int speed = 8;
21 bool dead = false;
22
23 static GLubyte Worm[72]; //我猜它8位一对齐?
24
25 enum GridType
26 {
27 NOTHING, CAPSULE, WORM, REMOVE
28 };
29
30 enum Connect
31 {
32 NOT_CONNECTED, LEFT, RIGHT, UP, DOWN
33 };
34
35 enum Color
36 {
37 BLACK, YELLOW, BLUE, RED
38 };
39
40 enum DoctorDirect
41 {
42 DD_NODIRECT, DD_UP, DD_DOWN, DD_LEFT, DD_RIGHT
43 };
44
45 void myCircle( int x, int y, int r )
46 {
47 glBegin( GL_TRIANGLE_FAN );
48 for ( int i = 0; i < 360; i+=60 )
49 glVertex2i( x+r*cos(i/360.0), y+r*sin(i/360.0) );
50 glEnd();
51 }
52
53 void _setColor( Color color )
54 {
55 switch (color)
56 {
57 case BLACK:
58 glColor3f( 0.0f, 0.0f, 0.0f );
59 break;
60 case YELLOW:
61 glColor3f( 1.0f, 1.0f, 0.0f );
62 break;
63 case BLUE:
64 glColor3f( 0.0f, 0.0f, 1.0f );
65 break;
66 case RED:
67 glColor3f( 1.0f, 0.0f, 0.0f );
68 break;
69 default:
70 break;
71 }
72 };
73
74
75 class Bottle
76 {
77 private:
78 int b_x,b_y; //bottle可以容纳药丸的最左上角位置
79 GridType b_grid_type[16][8]; //每个格子20像素长宽
80 Color b_color[16][8];
81 Connect b_connect[16][8];
82 public:
83 int getx( void )
84 {
85 return b_x;
86 }
87 int gety( void )
88 {
89 return b_y;
90 }
91 bool empty( int x, int y )
92 {
93 if ( x<0 || x>=8 || y<0 || y>=16 ) return false;
94 if ( b_grid_type[y][x] == NOTHING ) return true;
95 return false;
96 }
97 void set( Color color, int x, int y )
98 {
99 b_grid_type[y][x] = CAPSULE;
100 b_color[y][x] = color;
101 }
102 void setGridType( GridType grid_type, int x, int y )
103 {
104 b_grid_type[y][x] = grid_type;
105 }
106 void setColor( Color color, int x, int y )
107 {
108 b_color[y][x] = color;
109 }
110 void setConnect( int x, int y )
111 {
112 b_connect[y][x] = NOT_CONNECTED;
113 }
114 GridType getGridType( int x, int y )
115 {
116 return b_grid_type[y][x];
117 }
118 Color getColor( int x, int y )
119 {
120 return b_color[y][x];
121 }
122 Connect getConnect( int x, int y )
123 {
124 return b_connect[y][x];
125 }
126 bool fall( void )
127 {
128 int i, j;
129 bool flag = false;
130 for ( i = 15; i >0; --i )
131 {
132 for ( j = 0; j <8; ++j )
133 {
134 if ( b_grid_type[j][i] == NOTHING && b_grid_type[j][i-1] == CAPSULE )
135 {
136 switch ( b_connect[j][i-1] )
137 {
138 case UP:
139 b_grid_type[j][i] = CAPSULE;
140 b_color[j][i] = b_color[j][i-1];
141 b_connect[j][i] = UP;
142
143 b_color[j][i-1] = b_color[j][i-2];
144 b_connect[j][i-1] = DOWN;
145
146 b_grid_type[j][i-2] = NOTHING;
147 b_color[j][i-2] = BLACK;
148 b_connect[j][i] = NOT_CONNECTED;
149 flag = true;
150 break;
151 case RIGHT:
152 if ( b_grid_type[j+1][i] == NOTHING )
153 {
154 b_grid_type[j][i] = CAPSULE;
155 b_color[j][i] = b_color[j][i-1];
156 b_connect[j][i] = RIGHT;
157
158 b_grid_type[j+1][i] = CAPSULE;
159 b_color[j+1][i] = b_color[j+1][i-1];
160 b_connect[j+1][i] = LEFT;
161
162 b_grid_type[j][i-1] = NOTHING;
163 b_color[j][i-1] = BLACK;
164 b_connect[j][i-1] = NOT_CONNECTED;
165
166 b_grid_type[j+1][i-1] = NOTHING;
167 b_color[j+1][i-1] = BLACK;
168 b_connect[j+1][i-1] = NOT_CONNECTED;
169 flag = true;
170 }
171 break;
172 default:
173 break;
174 }
175 }
176 }
177 }
178 return flag;
179 }
180 void drawBottle( void )
181 {
182 int i,j;
183 glColor3f( 0.0f, 1.0f, 1.0f );//青色
184 //**************先画瓶口再画瓶身******
185 //画瓶子的内部,根据b_x,b_y和瓶子的内容物
186 for ( i = 0; i < 16; ++i )
187 {
188 for ( j = 0; j < 8; ++j )
189 {
190 _setColor( b_color[i][j] );
191 if ( b_grid_type[i][j] == WORM )
192 drawWorm( b_x+i*20, b_y+j*20 );
193 else if ( b_grid_type[i][j] == CAPSULE )
194 {
195 drawCapsule( b_x+i*20+10, b_y+i*20+10, b_connect[i][j] );
196 }
197 }
198 }
199 }
200
201 void drawCapsule( int x, int y, Connect connect )
202 {
203 //将相连的部分画上
204 switch ( connect )
205 {
206 case LEFT:
207 glRectf( x-10, y-10, x, y+10 );
208 break;
209 case RIGHT:
210 glRectf( x, y-10, x+10, y+10 );
211 break;
212 case UP:
213 glRectf( x-10, y-10, x+10, y );
214 break;
215 case DOWN:
216 glRectf( x-10, y, x+10, y+10 );
217 break;
218 default:
219 break;
220 }
221 //***********画圆并填充*********
222 myCircle( x, y, 10 );
223 }
224
225 void drawWorm( int x, int y )
226 {
227 glEnable(GL_POLYGON_STIPPLE);
228 glPolygonStipple(Worm);
229 glRectf( x, y, x+20, y+20 ); // 绘制一个有镂空效果的正方形
230 glDisable(GL_POLYGON_STIPPLE);
231 }
232
233 Bottle( int level, int xx, int yy )
234 {
235 int i; //vc6这点真恨人
236 b_x = xx;
237 b_y = yy;
238 for ( i = 0; i < 16; ++i )
239 {
240 for ( int j = 0; j < 8; ++j )
241 {
242 b_grid_type[i][j] = NOTHING;
243 b_color[i][j] = BLACK;
244 b_connect[i][j] = NOT_CONNECTED;
245 }
246 }
247 for ( i = 0; i < level*4; ++i )
248 {
249 int x = rand()%16;
250 int y = rand()%8;
251 Color color = (Color)(rand()%3);
252 if ( ok( x, y, color, level ) )
253 {
254 b_grid_type[x][y] = WORM;
255 b_color[x][y] = color;
256 }
257 else
258 --i;
259 }
260 }
261 bool ok( int x, int y, Color color, int level )
262 {
263 if ( level < 15 && x <= 6 ) return false;
264 if ( ((level+1)>>1)+3+x < 16 ) return false;
265 if ( x-2 >= 0 && b_grid_type[x-1][y] == WORM && b_color[x-1][y] == color
266 && b_grid_type[x-2][y] == WORM && b_color[x-2][y] == color ) return false;
267 if ( x+2 < 8 && b_grid_type[x+1][y] == WORM && b_color[x+1][y] == color
268 && b_grid_type[x+2][y] == WORM && b_color[x+2][y] == color ) return false;
269 if ( y+2 < 16 && b_grid_type[x][y+1] == WORM && b_color[x][y+1] == color
270 && b_grid_type[x][y+2] == WORM && b_color[x][y+2] == color ) return false;
271 if ( b_grid_type[x][y-1] == WORM && b_color[x][y-1] == color
272 && b_grid_type[x][y-2] == WORM && b_color[x][y-2] == color ) return false;
273 return true;
274 }
275 };
276
277 static Bottle* bottle = NULL;
278
279 class Doctor
280 {
281 private:
282 int d_x,d_y; //活动药丸(左下角)相对于瓶子的位置,不是像素点
283 bool d_state; //横的false,竖的true
284 Color d_color[2]; //俩药丸的颜色
285 DoctorDirect d_direct;
286 public:
287 Doctor( void )
288 {
289 d_x = 3; d_y = 0;
290 d_state = false;
291 d_direct = DD_NODIRECT;
292 d_color[0] = (Color)(rand()%3);
293 d_color[1] = (Color)(rand()%3);
294 }
295 void drawDoctor( void )
296 {
297 //***************画医生的形象*******************
298 if ( d_state )
299 {
300 bottle->drawCapsule( bottle->getx()+20*d_x+10, bottle->gety()+20*d_y+10, UP );
301 bottle->drawCapsule( bottle->getx()+20*d_x+10, bottle->gety()+20*d_y-10, DOWN );
302 }
303 else
304 {
305 bottle->drawCapsule( bottle->getx()+20*d_x+10, bottle->gety()+20*d_y+10, RIGHT );
306 bottle->drawCapsule( bottle->getx()+20*(d_x+1)+10, bottle->gety()+20*d_y+10, LEFT );
307 }
308 }
309 void move( void )
310 {
311 int i,j;
312 bool tag = true;
313 switch( d_direct )
314 {
315 case DD_DOWN:
316 if ( d_state )
317 {
318 if ( bottle->empty( d_x, d_y+1 ) )
319 {
320 ++d_y;
321 break;
322 }
323 }
324 else
325 {
326 if ( bottle->empty( d_x, d_y+1 ) && bottle->empty( d_x+1, d_y+1 ) )
327 {
328 ++d_y;
329 break;
330 }
331 }
332 /*************这里没写完,预计是个while(true)的循环*********************/
333 while ( tag )
334 {
335 bool flag = true;
336 if ( d_state )
337 {
338 bottle->set( d_color[0], d_x, d_y );
339 if ( d_y-1 != 0 )
340 bottle->set( d_color[1], d_x, d_y-1 );
341 }
342 else
343 {
344 bottle->set( d_color[0], d_x, d_y );
345 bottle->set( d_color[1], d_x+1, d_y );
346 }
347 //先消,不能消break
348 for ( i = 15; i >= 0; --i )
349 {
350 int number = 0;
351 Color corrent = BLACK;
352 for ( j = 0; j < 8; ++j,++number )
353 {
354 if ( bottle->getColor( j, i ) != corrent )
355 {
356 if ( number >= 4 )
357 {
358 int cnt = j-1;
359 while ( number-- )
360 {
361 bottle->setGridType( REMOVE, cnt, i );
362 tag = true;
363 }
364 }
365 else
366 {
367 number = -1;
368 }
369 }
370 }
371 }
372 for ( i = 7; i >= 0; ++i )
373 {
374 int number = 0;
375 Color corrent = BLACK;
376 for ( j = 0; j < 16; ++j,++number )
377 {
378 if ( bottle->getColor( i, j ) != corrent )
379 {
380 if ( number >= 4 )
381 {
382 int cnt = i-1;
383 while ( number-- )
384 {
385 bottle->setGridType( REMOVE, cnt, j );
386 tag = true;
387 }
388 }
389 else
390 {
391 number = -1;
392 }
393 }
394 }
395 }
396 if ( tag )
397 {
398 Sleep( 500 );
399 for ( i = 0; i < 16; ++i )
400 {
401 for ( j = 0; j < 8; ++j )
402 {
403 if ( bottle->getGridType(j, i) == REMOVE )
404 {
405 bottle->setColor( BLACK, j, i );
406 bottle->setGridType( NOTHING, j, i );
407 switch ( bottle->getConnect(j,i) )
408 {
409 case UP:
410 bottle->setConnect( j, i-1 );
411 break;
412 case DOWN:
413 bottle->setConnect( j, i+1 );
414 break;
415 case LEFT:
416 bottle->setConnect( j-1, i );
417 break;
418 case RIGHT:
419 bottle->setConnect( j+1, i );
420 break;
421 default:
422 break;
423 }
424 bottle->setConnect( j, i );
425 }
426 }
427 }
428 }
429
430 if ( tag )
431 {
432 //如果消了,就掉
433 while ( bottle->fall() )
434 Sleep(500);
435 }
436
437 Sleep( 500 );
438 }
439 //凡是落下不管是否消掉都要重置活动药丸位置和颜色
440 d_x = 3; d_y = 0;
441 d_state = false;
442 d_direct = DD_NODIRECT;
443 d_color[0] = (Color)(rand()%3);
444 d_color[1] = (Color)(rand()%3);
445
446 break;
447 case DD_UP:
448 if ( d_state )
449 {
450 if ( bottle->empty( d_x+1, d_y ) ) d_state = false;
451 else if ( bottle->empty( d_x-1, d_y ) ) { --d_x; d_state = false; }
452 }
453 else
454 {
455 if ( bottle->empty( d_x, d_y-1 ) )
456 {
457 d_state = true;
458 Color tmp = d_color[0];
459 d_color[0] = d_color[1];
460 d_color[1] = tmp;
461 }
462 else if ( bottle->empty( d_x+1, d_y-1 ) )
463 {
464 ++d_x;
465 d_state = true;
466 Color tmp = d_color[0];
467 d_color[0] = d_color[1];
468 d_color[1] = tmp;
469 }
470 }
471 break;
472 case DD_LEFT:
473 if ( d_state && bottle->empty( d_x-1, d_y ) && bottle->empty( d_x-1, d_y-1 ) ) --d_x;
474 if ( !d_state && bottle->empty( d_x-1, d_y ) ) --d_x;
475 break;
476 case DD_RIGHT:
477 if ( d_state && bottle->empty( d_x+1, d_y ) && bottle->empty( d_x+1, d_y-1 ) ) --d_x;
478 if ( !d_state && bottle->empty( d_x+1, d_y ) ) --d_x;
479 break;
480 default:
481 break;
482 }
483 }
484 void fall( void )
485 {
486 d_direct = DD_DOWN;
487 move();
488 }
489 void setDirect( DoctorDirect direct )
490 {
491 d_direct = direct;
492 }
493 };
494
495 static Doctor* doctor = NULL;
496
497 void init( void )
498 {
499 bottle = new Bottle( 3, 320, 160 );
500 doctor = new Doctor();
501 }
502
503 void key( unsigned char key_char, int not_use, int not_use_1 )
504 {
505 switch ( key_char )
506 {
507 case 'w':
508 case 'W':
509 doctor->setDirect( DD_UP );
510 break;
511 case 's':
512 case 'S':
513 doctor->setDirect( DD_DOWN );
514 break;
515 case 'a':
516 case 'A':
517 doctor->setDirect( DD_LEFT );
518 break;
519 case 'd':
520 case 'D':
521 doctor->setDirect( DD_RIGHT );
522 break;
523 default:
524 doctor->setDirect( DD_NODIRECT );
525 break;
526 }
527 }
528
529
530 void step( void )
531 {
532 if ( dead ) return ;
533 doctor->move();
534 ++count; if ( count == speed ) { count = 0; doctor->fall(); }
535 }
536
537 void timer( int not_use )
538 {
539 step();
540 glutPostRedisplay();
541 if ( !dead )
542 {
543 glutTimerFunc( 1000/speed, timer, 0 );
544 }
545 }
546
547 void drawBG( void )
548 {
549 int i,j;
550 glColor3f( 0.0f, 0.0f, 0.7f );
551 for ( i = 0; i < 32; ++i )
552 {
553 for ( j = 0; j < 30; ++j )
554 {
555 if ( ((i+j)&1) == 0 )
556 glRectf( i*20, j*16, (i+1)*20, (j+1)*16 );
557 }
558 }
559 }
560
561 void draw( void )
562 {
563 drawBG();
564 bottle->drawBottle();
565 doctor->drawDoctor();
566 }
567
568 void display( void )
569 {
570 glClear( GL_COLOR_BUFFER_BIT );
571 draw();
572 glutSwapBuffers();
573 }
574
575 int main( int argc, char * argv[] )
576 {
577 FILE *fp;
578 fp = fopen("worm.bmp", "rb");
579 if( !fp ) //如果没读取成功
580 exit(0);
581 if( fseek(fp, -(int)sizeof(Worm), SEEK_END) )//这是什么?
582 exit(0);
583 if( !fread( Worm, sizeof(Worm), 1, fp ) )
584 exit(0);
585 fclose(fp);
586
587 srand( (unsigned int)time(NULL) );
588 glutInit( &argc, argv );
589 glutInitDisplayMode( GLUT_RGBA|GLUT_DOUBLE );
590 glutInitWindowPosition( 50, 50 );
591 glutInitWindowSize( WindowWidth, WindowHeight );
592 glutCreateWindow( "Dr Mario By PureMilk" );
593 glutDisplayFunc( display );
594 glutKeyboardFunc( key );
595 glutTimerFunc( 1000/speed, timer, 0 );
596 gluOrtho2D( 0, WindowWidth, WindowHeight, 0 );
597 glutMainLoop();
598
599 return 0;
600 }
今晚上科研基地面试,那俩说不来就不来,就我和许多俩人面俩人有啥可面的晕死。现实和理想的差距啊。
赶紧的把日志写了。
原以为move函数50行就能搞定,写着写着发现问题还挺多,我真是低估了这个游戏的逻辑部分,竟然敢一个函数处理所有的问题,我罪恶的面向过程开始原形毕露。而且消去和落下明显是bottle里的问题,我竟然把它拿到doctor类里来,真是闲着没事儿找事。
除了医生没画,瓶口没画以外,算是写完了,和我预期的一样,是RE,遇到问题即将关闭,vc的单步调试好像遇到了glut的函数就变得特别奇怪。唔,要好好研究一下。代码总计596行,添几行注释添作600整吧呵呵。殿下这次可别再运行我代码了,声明哈,没弄完呢。