它它它它它……我不说啥了,效果图群里发过了,就是那么丑,还是RE。我有信心干掉它,靠我自己的力量,一点一点的。
我是一棵自卑的菜,胶州产的三里河大白菜。
1 //需要学会读取bmp格式图片并处理
2
3 /* 作者:PureMilk
4 天地之灵学习小组
5 */
6
7 #include <ctime>
8 #include <cmath>
9 #include <cstdio>
10 #include <GL/glut.h>
11 #include <windows.h>
12
13 static const int WindowWidth = 640; //窗口的宽度和高度
14 static const int WindowHeight = 480;
15
16 int count = 0; //速度计数器,每到一定时间count自增,达到speed,活动药丸就下落
17 int speed = 2000; //speed值越大,下落速度越慢
18 bool dead = false; //是否游戏结束
19
20 GLubyte * RedWorm = NULL; //三个读取三颜色虫子图片的指针,虫子图片是24×24的24位色bmp
21 GLubyte * BlueWorm = NULL;
22 GLubyte * YellowWorm = NULL;
23
24 enum GridType //bottle里的每个格子的类型,什么都没有,有药丸,有虫子和将被消去
25 {
26 NOTHING = 0, CAPSULE, WORM, REMOVE
27 };
28
29 enum Connect //若bottle里是药丸则需要记录它与哪个方向相连
30 {
31 NOT_CONNECTED = 0, LEFT, RIGHT, UP, DOWN
32 };
33
34 enum Color //BLACK就是什么都没有的状态
35 {
36 RED = 0, YELLOW, BLUE, BLACK
37 };
38
39 enum DoctorDirect //活动药丸要移动的方向
40 {
41 DD_NODIRECT = 0, DD_UP, DD_DOWN, DD_LEFT, DD_RIGHT
42 };
43
44 void myCircle( int x, int y, int r ) //我的画填充圆函数,圆心是x,y,半径是r <test OK>
45 {
46 glBegin( GL_TRIANGLE_FAN );
47 for ( GLint i = 0; i < 360; i+=30 )
48 glVertex2i( x+r*cos(i*6.28/360.0), y+r*sin(i*6.28/360.0) );
49 glEnd();
50 }
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 ) //若x,y位置为空,返回true,否则false
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 //**************先画瓶口再画瓶身******
186 //画瓶子的内部,根据b_x,b_y和瓶子的内容物
187 for ( i = 0; i < 16; ++i )
188 {
189 for ( j = 0; j < 8; ++j )
190 {
191 if ( b_grid_type[i][j] == WORM )
192 drawWorm( b_x+j*24, b_y+i*24, b_color[i][j] );
193 else if ( b_grid_type[i][j] == CAPSULE )
194 {
195 drawCapsule( b_x+j*24+12, b_y+i*24+12, 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-12, y-12, x, y+12 );
208 break;
209 case RIGHT:
210 glRectf( x, y-12, x+12, y+12 );
211 break;
212 case UP:
213 glRectf( x-12, y-12, x+12, y );
214 break;
215 case DOWN:
216 glRectf( x-12, y, x+12, y+12 );
217 break;
218 default:
219 break;
220 }
221 //***********画圆并填充*********
222 myCircle( x, y, 12 );
223 }
224
225 void drawWorm( int x, int y, Color color )
226 {
227 GLubyte * Worm = NULL;
228 glRasterPos2i( x, y );
229
230 switch ( color )
231 {
232 case RED:
233 Worm = RedWorm;
234 break;
235 case BLUE:
236 Worm = BlueWorm;
237 break;
238 case YELLOW:
239 Worm = YellowWorm;
240 break;
241 case BLACK:
242 break;
243 }
244
245 if ( Worm != NULL )
246 {
247 glDrawPixels(24, 24, GL_RGB, GL_UNSIGNED_BYTE, Worm);
248 glPolygonStipple(Worm);
249 }
250 }
251
252 Bottle( int level, int xx, int yy )
253 {
254 int i; //vc6这点真恨人
255 b_x = xx;
256 b_y = yy;
257 for ( i = 0; i < 16; ++i )
258 {
259 for ( int j = 0; j < 8; ++j )
260 {
261 b_grid_type[i][j] = NOTHING;
262 b_color[i][j] = BLACK;
263 b_connect[i][j] = NOT_CONNECTED;
264 }
265 }
266 for ( i = 0; i < level*4; ++i )
267 {
268 int x = rand()%16;
269
270 printf( "x = %d\n", x );
271
272
273
274 int y = rand()%8;
275 Color color = (Color)(rand()%3);
276 if ( ok( x, y, color, level ) )
277 {
278 b_grid_type[x][y] = WORM;
279 b_color[x][y] = color;
280 }
281 else
282 --i;
283 }
284 }
285 bool ok( int x, int y, Color color, int level )
286 {
287 if ( level < 15 && x <= 6 ) return false;
288 if ( ((level+1)>>1)+3+x < 16 ) return false;
289 if ( x-2 >= 0 && b_grid_type[x-1][y] == WORM && b_color[x-1][y] == color
290 && b_grid_type[x-2][y] == WORM && b_color[x-2][y] == color ) return false;
291 if ( x+2 < 8 && b_grid_type[x+1][y] == WORM && b_color[x+1][y] == color
292 && b_grid_type[x+2][y] == WORM && b_color[x+2][y] == color ) return false;
293 if ( y+2 < 16 && b_grid_type[x][y+1] == WORM && b_color[x][y+1] == color
294 && b_grid_type[x][y+2] == WORM && b_color[x][y+2] == color ) return false;
295 if ( b_grid_type[x][y-1] == WORM && b_color[x][y-1] == color
296 && b_grid_type[x][y-2] == WORM && b_color[x][y-2] == color ) return false;
297 return true;
298 }
299 };
300
301 static Bottle* bottle = NULL;
302
303 class Doctor
304 {
305 private:
306 int d_x,d_y; //活动药丸(左下角)相对于瓶子的位置,不是像素点
307 bool d_state; //横的false,竖的true
308 Color d_color[2]; //俩药丸的颜色
309 DoctorDirect d_direct;
310 public:
311 Doctor( void )
312 {
313 d_x = 3; d_y = 0;
314 d_state = false;
315 d_direct = DD_NODIRECT;
316 d_color[0] = (Color)(rand()%3);
317 d_color[1] = (Color)(rand()%3);
318 }
319 void drawDoctor( void )
320 {
321 //***************画医生的形象*******************
322 if ( d_state )
323 {
324 bottle->drawCapsule( bottle->getx()+20*d_x+10, bottle->gety()+20*d_y+10, UP );
325 bottle->drawCapsule( bottle->getx()+20*d_x+10, bottle->gety()+20*d_y-10, DOWN );
326 }
327 else
328 {
329 bottle->drawCapsule( bottle->getx()+20*d_x+10, bottle->gety()+20*d_y+10, RIGHT );
330 bottle->drawCapsule( bottle->getx()+20*(d_x+1)+10, bottle->gety()+20*d_y+10, LEFT );
331 }
332 }
333 void move( void )
334 {
335 int i,j;
336 bool tag = true;
337 switch( d_direct )
338 {
339 case DD_DOWN:
340 if ( d_state )
341 {
342 if ( bottle->empty( d_x, d_y+1 ) )
343 {
344 ++d_y;
345 break;
346 }
347 }
348 else
349 {
350 if ( bottle->empty( d_x, d_y+1 ) && bottle->empty( d_x+1, d_y+1 ) )
351 {
352 ++d_y;
353 break;
354 }
355 }
356 /*************这里没写完,预计是个while(true)的循环*********************/
357 while ( tag )
358 {
359 bool flag = true;
360 if ( d_state )
361 {
362 bottle->set( d_color[0], d_x, d_y );
363 if ( d_y-1 != 0 )
364 bottle->set( d_color[1], d_x, d_y-1 );
365 }
366 else
367 {
368 bottle->set( d_color[0], d_x, d_y );
369 bottle->set( d_color[1], d_x+1, d_y );
370 }
371 //先消,不能消break
372 for ( i = 15; i >= 0; --i )
373 {
374 int number = 0;
375 Color corrent = BLACK;
376 for ( j = 0; j < 8; ++j,++number )
377 {
378 if ( bottle->getColor( j, i ) != corrent )
379 {
380 if ( number >= 4 )
381 {
382 int cnt = j-1;
383 while ( number-- )
384 {
385 bottle->setGridType( REMOVE, cnt, i );
386 tag = true;
387 }
388 }
389 else
390 {
391 number = -1;
392 }
393 }
394 }
395 }
396 for ( i = 7; i >= 0; ++i )
397 {
398 int number = 0;
399 Color corrent = BLACK;
400 for ( j = 0; j < 16; ++j,++number )
401 {
402 if ( bottle->getColor( i, j ) != corrent )
403 {
404 if ( number >= 4 )
405 {
406 int cnt = i-1;
407 while ( number-- )
408 {
409 bottle->setGridType( REMOVE, cnt, j );
410 tag = true;
411 }
412 }
413 else
414 {
415 number = -1;
416 }
417 }
418 }
419 }
420 if ( tag )
421 {
422 Sleep( 500 );
423 for ( i = 0; i < 16; ++i )
424 {
425 for ( j = 0; j < 8; ++j )
426 {
427 if ( bottle->getGridType(j, i) == REMOVE )
428 {
429 bottle->setColor( BLACK, j, i );
430 bottle->setGridType( NOTHING, j, i );
431 switch ( bottle->getConnect(j,i) )
432 {
433 case UP:
434 bottle->setConnect( j, i-1 );
435 break;
436 case DOWN:
437 bottle->setConnect( j, i+1 );
438 break;
439 case LEFT:
440 bottle->setConnect( j-1, i );
441 break;
442 case RIGHT:
443 bottle->setConnect( j+1, i );
444 break;
445 default:
446 break;
447 }
448 bottle->setConnect( j, i );
449 }
450 }
451 }
452 }
453
454 if ( tag )
455 {
456 //如果消了,就掉
457 while ( bottle->fall() )
458 Sleep(500);
459 }
460
461 Sleep( 500 );
462 }
463 //凡是落下不管是否消掉都要重置活动药丸位置和颜色
464 d_x = 3; d_y = 0;
465 d_state = false;
466 d_direct = DD_NODIRECT;
467 d_color[0] = (Color)(rand()%3);
468 d_color[1] = (Color)(rand()%3);
469
470 break;
471 case DD_UP:
472 if ( d_state )
473 {
474 if ( bottle->empty( d_x+1, d_y ) ) d_state = false;
475 else if ( bottle->empty( d_x-1, d_y ) ) { --d_x; d_state = false; }
476 }
477 else
478 {
479 if ( bottle->empty( d_x, d_y-1 ) )
480 {
481 d_state = true;
482 Color tmp = d_color[0];
483 d_color[0] = d_color[1];
484 d_color[1] = tmp;
485 }
486 else if ( bottle->empty( d_x+1, d_y-1 ) )
487 {
488 ++d_x;
489 d_state = true;
490 Color tmp = d_color[0];
491 d_color[0] = d_color[1];
492 d_color[1] = tmp;
493 }
494 }
495 break;
496 case DD_LEFT:
497 if ( d_state && bottle->empty( d_x-1, d_y ) && bottle->empty( d_x-1, d_y-1 ) ) --d_x;
498 if ( !d_state && bottle->empty( d_x-1, d_y ) ) --d_x;
499 break;
500 case DD_RIGHT:
501 if ( d_state && bottle->empty( d_x+1, d_y ) && bottle->empty( d_x+1, d_y-1 ) ) --d_x;
502 if ( !d_state && bottle->empty( d_x+1, d_y ) ) --d_x;
503 break;
504 default:
505 break;
506 }
507 }
508 void fall( void )
509 {
510 d_direct = DD_DOWN;
511 move();
512 }
513 void setDirect( DoctorDirect direct )
514 {
515 d_direct = direct;
516 }
517 };
518
519 static Doctor* doctor = NULL;
520
521 void init( void )
522 {
523 bottle = new Bottle( 5, 224, 70 );
524 doctor = new Doctor();
525 }
526
527 void key( unsigned char key_char, int not_use, int not_use_1 )
528 {
529 switch ( key_char )
530 {
531 case 'w':
532 case 'W':
533 doctor->setDirect( DD_UP );
534 break;
535 case 's':
536 case 'S':
537 doctor->setDirect( DD_DOWN );
538 break;
539 case 'a':
540 case 'A':
541 doctor->setDirect( DD_LEFT );
542 break;
543 case 'd':
544 case 'D':
545 doctor->setDirect( DD_RIGHT );
546 break;
547 default:
548 doctor->setDirect( DD_NODIRECT );
549 break;
550 }
551 }
552
553
554 void step( void )
555 {
556 if ( dead )
557 return ;
558 doctor->move();
559 ++count;
560 if ( count == speed )
561 {
562 count = 0;
563 doctor->fall();
564 }
565 }
566
567 void timer( int not_use )
568 {
569 step();
570 glutPostRedisplay();
571 if ( !dead )
572 {
573 glutTimerFunc( 10, timer, 0 );
574 }
575 }
576
577 void drawBG( void )
578 {
579 int i,j;
580 glColor3f( 0.0f, 0.0f, 0.7f );
581 for ( i = 0; i < 32; ++i )
582 {
583 for ( j = 0; j < 30; ++j )
584 {
585 if ( ((i+j)&1) == 0 )
586 glRectf( i*20, j*16, (i+1)*20, (j+1)*16 );
587 }
588 }
589 }
590
591 void draw( void )
592 {
593 drawBG();
594 bottle->drawBottle();
595 doctor->drawDoctor();
596 }
597
598 void display( void )
599 {
600 glClear( GL_COLOR_BUFFER_BIT );
601 draw();
602 glutSwapBuffers();
603 }
604
605 int main( int argc, char * argv[] )
606 {
607 static GLint ImageWidth;
608 static GLint ImageHeight;
609
610 // 打开文件
611 FILE* pFile = fopen("blueworm.bmp", "rb");
612 if( pFile == 0 )
613 exit(0);
614
615 // 读取图象的大小信息
616 fseek(pFile, 0x0012, SEEK_SET);
617 fread(&ImageWidth, sizeof(ImageWidth), 1, pFile);
618 fread(&ImageHeight, sizeof(ImageHeight), 1, pFile);
619
620 // 计算像素数据长度
621 int PixelLength = ImageWidth * 3;
622 while( PixelLength % 4 != 0 )
623 ++PixelLength;
624 PixelLength *= ImageHeight;
625
626 // 读取像素数据
627 BlueWorm = (GLubyte*)malloc(PixelLength);
628 if( BlueWorm == 0 )
629 exit(0);
630
631 fseek(pFile, 54, SEEK_SET);
632 fread(BlueWorm, PixelLength, 1, pFile);
633
634 fclose(pFile);
635
636 pFile = fopen("redworm.bmp", "rb");
637 if( pFile == 0 )
638 exit(0);
639
640 // 读取图象的大小信息
641 fseek(pFile, 0x0012, SEEK_SET);
642 fread(&ImageWidth, sizeof(ImageWidth), 1, pFile);
643 fread(&ImageHeight, sizeof(ImageHeight), 1, pFile);
644
645 // 计算像素数据长度
646 PixelLength = ImageWidth * 3;
647 while( PixelLength % 4 != 0 )
648 ++PixelLength;
649 PixelLength *= ImageHeight;
650
651 // 读取像素数据
652 RedWorm = (GLubyte*)malloc(PixelLength);
653 if( RedWorm == 0 )
654 exit(0);
655
656 fseek(pFile, 54, SEEK_SET);
657 fread(RedWorm, PixelLength, 1, pFile);
658
659 fclose(pFile);
660
661
662 pFile = fopen("yellowworm.bmp", "rb");
663 if( pFile == 0 )
664 exit(0);
665
666 // 读取图象的大小信息
667 fseek(pFile, 0x0012, SEEK_SET);
668 fread(&ImageWidth, sizeof(ImageWidth), 1, pFile);
669 fread(&ImageHeight, sizeof(ImageHeight), 1, pFile);
670
671 // 计算像素数据长度
672 PixelLength = ImageWidth * 3;
673 while( PixelLength % 4 != 0 )
674 ++PixelLength;
675 PixelLength *= ImageHeight;
676
677 // 读取像素数据
678 YellowWorm = (GLubyte*)malloc(PixelLength);
679 if( YellowWorm == 0 )
680 exit(0);
681
682 fseek(pFile, 54, SEEK_SET);
683 fread(YellowWorm, PixelLength, 1, pFile);
684
685
686
687 // 关闭文件
688 fclose(pFile);
689
690
691
692 srand( GetTickCount() );
693 init();
694
695 glutInit( &argc, argv );
696 glutInitDisplayMode( GLUT_RGBA|GLUT_DOUBLE );
697 glutInitWindowPosition( 50, 50 );
698 glutInitWindowSize( WindowWidth, WindowHeight );
699 glutCreateWindow( "Dr Mario By PureMilk" );
700 glutDisplayFunc( display );
701 glutKeyboardFunc( key );
702 glutTimerFunc( 10, timer, 0 );
703 gluOrtho2D( 0, WindowWidth, WindowHeight, 0 );
704 glutMainLoop();
705
706 return 0;
707 }