天地之灵学习小组
我们学习小组的OpenGL学习笔记 大家一定要互相折磨呀~~
posts - 150,  comments - 156,  trackbacks - 0
它它它它它……我不说啥了,效果图群里发过了,就是那么丑,还是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.0f0.0f0.0f );
 59         break;
 60     case YELLOW:
 61         glColor3f( 1.0f1.0f0.0f );
 62         break;
 63     case BLUE:
 64         glColor3f( 0.0f0.0f1.0f );
 65         break;
 66     case RED:
 67         glColor3f( 1.0f0.0f0.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.0f1.0f1.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(2424, 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+< 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( 522470 );
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.0f0.0f0.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( 5050 );
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 }


FeedBack:
# re: 10月26日_707行代码,比图形学的页数还多5_By PureMilk
2008-10-26 21:11 | 肖赫_王婷婷_王冠_郑燚_孙婷
竟然这么长,今天是没法看了。明天继续....  回复  更多评论
  
# re: 10月26日_707行代码,比图形学的页数还多5_By PureMilk[未登录]
2008-10-26 22:42 | missdeer
在vc中调试RE还是比较方便的,大部分情况RE时,调试器能显示出当时的调用栈,很容易定位  回复  更多评论
  
# re: 10月26日_707行代码,比图形学的页数还多5_By PureMilk[未登录]
2008-10-26 22:46 | missdeer
其实比上一篇没长多少,main里相同的代码写了三次-_-b  回复  更多评论
  
# re: 10月26日_707行代码,比图形学的页数还多5_By PureMilk
2008-10-27 15:24 | 肖赫_王婷婷_王冠_郑燚_孙婷
哈哈哈被你发现啦  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理



<2008年10月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

常用链接

留言簿(6)

随笔分类(149)

随笔档案(150)

同道中人

搜索

  •  

积分与排名

  • 积分 - 46147
  • 排名 - 475

最新随笔

最新评论

阅读排行榜

评论排行榜