看WIndows游戏编程大师技巧,中有这么一个范例,不过是只有3个自动移动的机器人,8位显示模式

然后自己手痒,就改成这样了,32位显示模式 读取32位图,加入角色控制,以及×××发射

这玩意。真要算时间的话,也蛮久的了。11年开始写。然后遇到某些原因,停了下来,然后最近这周又开始写,终于写出来了

期间遇到很多难处,基本无人可问,全凭自己研究,实在不容易啊,所以放上网,等有需要的人参考下吧

代码是VC6写的,VS2010的自己改下就行了。不会改的就下个VC6吧- -

编译代码前记得安装DX9.0 SDK 

工程记得添加资源Microsoft DirectX SDK (March 2009)\Lib\x86\ ddraw.lib

ESC 退出

方向键-> 移动

长按A 开枪

 蛋疼的网站,代码要分成3块才能发上来。。

 

图片上传还限大小。。。只能传别的网站

演示:

点击打开GIF动态演示

 

 

 

都是我自己的博客来的....当时因为这里太蛋疼的限制。才发那边的

 

 
    
  1. // INCLUDES ///   
  2.    
  3. #define WIN32_LEAN_AND_MEAN  // just say no to MFC   
  4.    
  5. #define INITGUID   
  6.    
  7. #include    // include important windows stuff   
  8. #include     
  9. #include    
  10. #include  // include important C/C++ stuff   
  11. #include    
  12. #include    
  13. #include    
  14. #include    
  15. #include    
  16. #include    
  17. #include     
  18. #include    
  19. #include    
  20. #include    
  21.    
  22. #include  // include directdraw   
  23. #include    
  24. // DEFINES    
  25.    
  26. // defines for windows    
  27. #define WINDOW_CLASS_NAME "WINCLASS1"   
  28.    
  29. // default screen size   
  30. #define SCREEN_WIDTH    640  // size of screen   
  31. #define SCREEN_HEIGHT   480   
  32. #define SCREEN_BPP      32 // bits per pixel   
  33.    
  34. #define BITMAP_ID            0x4D42 // universal id for a bitmap   
  35. #define MAX_COLORS_PALETTE   256   
  36. #define _RGB32BIT(a,r,g,b) ((b) + ((g) << 8) + ((r) << 16) + ((a) << 24))   
  37.    
  38. #define ALLEY "alley32.bmp"   
  39. #define DEDSP "Dedsp32.bmp"   
  40. #define OLD 1   
  41. int BMPBIT=32;   
  42. // TYPES //   
  43.    
  44. // basic unsigned types   
  45. typedef unsigned short USHORT;   
  46. typedef unsigned short WORD;   
  47. typedef unsigned char  UCHAR;   
  48. typedef unsigned char  BYTE;   
  49.    
  50. // //BMP 位图容器 结构   
  51. typedef struct BITMAP_FILE_TAG   
  52. {   
  53.     BITMAPFILEHEADER bitmapfileheader;   // 包含位图文件头   
  54.     BITMAPINFOHEADER bitmapinfoheader;  // 位图信息段,包含调色板(如果有的话)   
  55.     PALETTEENTRY     palette[256];       // 调色板我们将存储在这里   
  56.     UCHAR            *buffer;         // 数据指针   
  57.        
  58. } BITMAP_FILE, *BITMAP_FILE_PTR;   
  59.    
  60. // this will hold our little alien   
  61. typedef struct ALIEN_OBJ_TYP   
  62. {   
  63.        // LPDIRECTDRAWSURFACE7 表面描绘的接口   
  64.        LPDIRECTDRAWSURFACE7 frames[3], // 三帧的动画完整步行周期   
  65.                                                  animation_fire_frames[3],//三帧开火动画   
  66.                                                  fire_frames;//火球   
  67.         int x,y;                        //外星人的位置   
  68.         int velocity;                   //X坐标的速度   
  69.         int current_frame;              // 当前移动帧的动画   
  70.         int current_animation_fire_frames;//当前开火帧的动画   
  71.         int counter;                    // 移动动画的使用时间   
  72.         int counter_animation_fire;//开火动画的使用时间   
  73.        
  74. } ALIEN_OBJ, *ALIEN_OBJ_PTR;   
  75. //弹药结构   
  76. struct ALIEN_AMM   
  77. {   
  78.    
  79.        
  80.     int x,y;  //弹药坐标   
  81.     int velocity; //X坐标的速度   
  82.     bool life;//判断弹药生命周期是否结束   
  83. };   
  84.    
  85. // PROTOTYPES  //   
  86. //翻转位图   
  87. int Flip_Bitmap(UCHAR *p_w_picpath, int bytes_per_line, int height);   
  88. //读取位图   
  89. int Load_Bitmap_File(BITMAP_FILE_PTR bitmap, char *filename);   
  90.    
  91. int Unload_Bitmap_File(BITMAP_FILE_PTR bitmap);   
  92. //生成离屏表面   
  93. LPDIRECTDRAWSURFACE7 DDraw_Create_Surface(int width, int height, int mem_flags);   
  94. //生成剪辑器   
  95. LPDIRECTDRAWCLIPPER DDraw_Attach_Clipper(LPDIRECTDRAWSURFACE7 lpdds, int num_rects,  LPRECT clip_list);   
  96. //填充表面   
  97. int DDraw_Fill_Surface(LPDIRECTDRAWSURFACE7 lpdds,int color);   
  98. //扫描位图   
  99. int Scan_Image_Bitmap(BITMAP_FILE_PTR bitmap, LPDIRECTDRAWSURFACE7 lpdds, int cx,int cy);   
  100.    
  101.    
  102.    
  103. int DDraw_Draw_Surface(LPDIRECTDRAWSURFACE7 source, int x, int y,    
  104.                        int width, int height, LPDIRECTDRAWSURFACE7 dest,    
  105.                        int transparent);       
  106.    
  107.    
  108.    
  109. int Draw_Text_GDI(char *text, int x,int y,COLORREF color, LPDIRECTDRAWSURFACE7 lpdds);   
  110.    
  111. // MACROS /   
  112.    
  113. // tests if a key is up or down   
  114. #define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)   
  115. #define KEYUP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)   
  116.    
  117. // initializes a direct draw struct   
  118. #define DDRAW_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }   
  119.    
  120. // GLOBALS    
  121.    
  122. HWND      main_window_handle = NULL; // globally track main window   
  123. int       window_closed      = 0;    // tracks if window is closed   
  124. HINSTANCE hinstance_app      = NULL; // globally track hinstance   
  125.    
  126. // directdraw stuff   
  127.    
  128. LPDIRECTDRAW7         lpdd         = NULL;   // 申请接口对象   
  129. LPDIRECTDRAWSURFACE7  lpddsprimary = NULL;   //主表面   
  130. LPDIRECTDRAWSURFACE7  lpddsback    = NULL;   //背面   
  131. LPDIRECTDRAWPALETTE   lpddpal      = NULL;   //调色板指针   
  132. LPDIRECTDRAWCLIPPER   lpddclipper  = NULL;   //剪切器   
  133. PALETTEENTRY          palette[256];          // 调色板   
  134. PALETTEENTRY          save_palette[256];     // 用于保存调色板   
  135. DDSURFACEDESC2        ddsd;                  // 直接绘制表面的描述结构   
  136. DDBLTFX               ddbltfx;               // 用来填充   
  137. DDSCAPS2              ddscaps;               //直接绘制表面的功能结构   
  138. HRESULT               ddrval;                // result back from dd calls   
  139. DWORD                 start_clock_count = 0; //用于定时   
  140.    
  141. BITMAP_FILE           bitmap;                // holds the bitmap   
  142.    
  143. ALIEN_OBJ             aliens[3];             //3个外星人   
  144.    
  145. std::list aliens_amm;      //用LIST容器存放弹药结构   
  146. bool first_fire;   
  147. ALIEN_AMM aa={-80,-80,6,false};//弹药坐标X,Y  X坐标的速度  判断弹药生命周期是否结束 false 等于结束   
  148. LPDIRECTDRAWSURFACE7  lpddsbackground=NULL;        //这将保留背景图片   
  149. char buffer[80];                             // general printing buffer   
  150.    
  151. int gwidth  = -1;   
  152. int gheight = -1;   
  153.    
  154. // FUNCTIONS    
  155.    
  156. int Load_Bitmap_File(BITMAP_FILE_PTR bitmap, char *filename)   
  157. {   
  158.        
  159.         //此函数打开一个位图文件,并加载数据导入位图   
  160.    
  161.         int file_handle,  // 文件句柄    
  162.                 index;        // 循环用的变量   
  163.    
  164.    
  165.         UCHAR   *temp_buffer = NULL; //用于把24位转换成16位的图像   
  166.         OFSTRUCT file_data;          // 文件的数据信息   
  167.    
  168.         //打开文件,如果存在的话   
  169.         if ((file_handle = OpenFile(filename,&file_data,OF_READ))==-1)   
  170.    
  171.    
  172.    
  173.                 return(0);   
  174.    
  175.         // 现在载入位图文件头   
  176.         _lread(file_handle, &bitmap->bitmapfileheader,sizeof(BITMAPFILEHEADER));   
  177.    
  178.    
  179.    
  180.         // 测试,如果这是一个位图文件   
  181.    
  182.         if (bitmap->bitmapfileheader.bfType!=BITMAP_ID)   
  183.         {   
  184.                 // 关闭文件   
  185.                 _lclose(file_handle);   
  186.    
  187.    
  188.                 // 返回 error   
  189.                 return(0);   
  190.         } // end if   
  191.    
  192.         //现在我们知道这是一个位图,所以在读取所有部分之前,   
  193.    
  194.         // 首先是读取位图的 infoheader   
  195.    
  196.         //现在载人位图文件头   
  197.         _lread(file_handle, &bitmap->bitmapinfoheader,sizeof(BITMAPINFOHEADER));   
  198.    
  199.    
  200.    
  201.    
  202.    
  203.    
  204.    
  205.    
  206.    
  207.         // 最后,读取图像数据本身   
  208.         _llseek(file_handle,-(int)(bitmap->bitmapinfoheader.biSizeImage),SEEK_END);   
  209.    
  210.    
  211.    
  212.    
  213.    
  214.    
  215.    
  216.         //现在读的图像,如果图像是8位或16位则仅仅是读取它,   
  217.         //但如果是24位,就读入一个临时区域,然后将其转换为16位的图像   
  218.    
  219.    
  220.    
  221.    
  222.    
  223.    
  224.    
  225.    
  226.    
  227.    
  228.    
  229.         if (bitmap->bitmapinfoheader.biBitCount==8 || bitmap->bitmapinfoheader.biBitCount==16 ||    
  230.                 bitmap->bitmapinfoheader.biBitCount==24||bitmap->bitmapinfoheader.biBitCount==32)   
  231.         {   
  232.                 // 删除最后的图像,如果有的话   
  233.                 if (bitmap->buffer)   
  234.                         free(bitmap->buffer);   
  235.    
  236.                 // 为图像分配内存   
  237.                 if (!(bitmap->buffer = (UCHAR *)malloc(bitmap->bitmapinfoheader.biSizeImage)))   
  238.                 {   
  239.                         //分配失败,关闭文件   
  240.                         _lclose(file_handle);   
  241.    
  242.                         // 返回 error   
  243.    
  244.    
  245.    
  246.    
  247.                         return(0);   
  248.                 } // end if   
  249.    
  250.    
  251.                 // 现在读取它   
  252.                 _lread(file_handle,bitmap->buffer,bitmap->bitmapinfoheader.biSizeImage);   
  253.    
  254.    
  255.    
  256.    
  257.         } // end if   
  258.         else   
  259.         {   
  260.                 // 出现严重问题   
  261.                 return(0);   
  262.    
  263.         } // end else   
  264.    
  265. #if 0   
  266.         // 写出来的文件信息   
  267.         printf("\nfilename:%s \nsize=%d \nwidth=%d \nheight=%d \nbitsperpixel=%d \ncolors=%d \nimpcolors=%d",   
  268.                 filename,   
  269.                 bitmap->bitmapinfoheader.biSizeImage,   
  270.                 bitmap->bitmapinfoheader.biWidth,   
  271.                 bitmap->bitmapinfoheader.biHeight,   
  272.                 bitmap->bitmapinfoheader.biBitCount,   
  273.                 bitmap->bitmapinfoheader.biClrUsed,   
  274.                 bitmap->bitmapinfoheader.biClrImportant);   
  275. #endif   
  276.    
  277.         // 关闭文件   
  278.         _lclose(file_handle);   
  279.    
  280.    
  281.    
  282.         // 翻转位图   
  283.         Flip_Bitmap(bitmap->buffer,    
  284.                 bitmap->bitmapinfoheader.biWidth*(bitmap->bitmapinfoheader.biBitCount/8),    
  285.                 bitmap->bitmapinfoheader.biHeight);   
  286.    
  287.    
  288.         return(1);   
  289.    
  290.        
  291. // end Load_Bitmap_File   
  292.    
  293. ///   
  294.    
  295. int Unload_Bitmap_File(BITMAP_FILE_PTR bitmap)   
  296. {   
  297.     // this function releases all memory associated with "bitmap"   
  298.     if (bitmap->buffer)   
  299.     {   
  300.         // release memory   
  301.         free(bitmap->buffer);   
  302.            
  303.         // reset pointer   
  304.         bitmap->buffer = NULL;   
  305.            
  306.     } // end if   
  307.        
  308.     // return success   
  309.     return(1);   
  310.        
  311. // end Unload_Bitmap_File   
  312.    
  313. ///   
  314.    
  315. int Flip_Bitmap(UCHAR *p_w_picpath, int bytes_per_line, int height)   
  316. {   
  317.     // this function is used to flip bottom-up .BMP p_w_picpaths   
  318.        
  319.     UCHAR *buffer; // used to perform the p_w_picpath processing   
  320.     int index;     // looping index   
  321.        
  322.     // allocate the temporary buffer   
  323.     if (!(buffer = (UCHAR *)malloc(bytes_per_line*height)))   
  324.         return(0);   
  325.        
  326.     // copy p_w_picpath to work area   
  327.     memcpy(buffer,p_w_picpath,bytes_per_line*height);   
  328.        
  329.     // flip vertically   
  330.     for (index=0; index < height; index++)   
  331.         memcpy(&p_w_picpath[((height-1) - index)*bytes_per_line],   
  332.         &buffer[index*bytes_per_line], bytes_per_line);   
  333.        
  334.     // release the memory   
  335.     free(buffer);   
  336.        
  337.     // return success   
  338.     return(1);   
  339.        
  340. // end Flip_Bitmap   
  341.    
  342. LPDIRECTDRAWSURFACE7 DDraw_Create_Surface(int width, int height, int mem_flags)   
  343. {   
  344. //        这个函数创建一个简单的离屏表面   
  345.        
  346.     DDSURFACEDESC2 ddsd;         // working description   
  347.     LPDIRECTDRAWSURFACE7 lpdds;  //临时表用的面   
  348.    
  349.    
  350.     // /设置宽,高,CAPS成员有效   
  351.     memset(&ddsd,0,sizeof(ddsd));      
  352.     ddsd.dwSize  = sizeof(ddsd);   
  353.     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;   
  354.        
  355.     //设置新位图表面的尺寸   
  356.     ddsd.dwWidth  =  width;   
  357.     ddsd.dwHeight =  height;   
  358.        
  359.     // set surface to offscreen plain   
  360.     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | mem_flags;   
  361.        
  362.     // 创建表面   
  363.     if (FAILED(lpdd->CreateSurface(&ddsd,&lpdds,NULL)))   
  364.         return(NULL);   
  365.        
  366.    
  367.    
  368.         // 设置色彩索引0为透明色  (黑)   
  369.         DDCOLORKEY color_key; // used to set color key   
  370.         color_key.dwColorSpaceLowValue  = 0;   
  371.         color_key.dwColorSpaceHighValue =0;   
  372.            
  373.         // now set the color key for source blitting   
  374.         lpdds->SetColorKey(DDCKEY_SRCBLT, &color_key);   
  375.  // end if   
  376.        
  377.     // return surface   
  378.     return(lpdds);   
  379.    
  380. // end DDraw_Create_Surface   
  381.    
  382. ///   
  383.    
  384. LPDIRECTDRAWCLIPPER DDraw_Attach_Clipper(LPDIRECTDRAWSURFACE7 lpdds,   
  385.                                          int num_rects,   
  386.                                          LPRECT clip_list)   
  387.                                             
  388. {   
  389.     // this function creates a clipper from the sent clip list and attaches   
  390.     // it to the sent surface   
  391.     //这个函数创建一个从发送剪辑列表Clipper和其附加到发送的表面   
  392.    
  393.     int index;                         // 循环变量   
  394.     LPDIRECTDRAWCLIPPER lpddclipper;   // pointer to the newly created dd clipper   
  395.     LPRGNDATA region_data;             // pointer to the region data that contains   
  396.     // the header and clip list   
  397.        
  398.     // first create the direct draw clipper   
  399.     if (FAILED(lpdd->CreateClipper(0,&lpddclipper,NULL)))   
  400.         return(NULL);   
  401.        
  402.     // now create the clip list from the sent data   
  403.        
  404.     // first allocate memory for region data   
  405.     region_data = (LPRGNDATA)malloc(sizeof(RGNDATAHEADER)+num_rects*sizeof(RECT));   
  406.        
  407.     // now copy the rects into region data   
  408.     memcpy(region_data->Buffer, clip_list, sizeof(RECT)*num_rects);   
  409.        
  410.     // set up fields of header   
  411.     region_data->rdh.dwSize          = sizeof(RGNDATAHEADER);   
  412.     region_data->rdh.iType           = RDH_RECTANGLES;   
  413.     region_data->rdh.nCount          = num_rects;   
  414.     region_data->rdh.nRgnSize        = num_rects*sizeof(RECT);   
  415.        
  416.     region_data->rdh.rcBound.left    =  64000;   
  417.     region_data->rdh.rcBound.top     =  64000;   
  418.     region_data->rdh.rcBound.right   = -64000;   
  419.     region_data->rdh.rcBound.bottom  = -64000;   
  420.        
  421.     // find bounds of all clipping regions   
  422.     for (index=0; index
  423.     {   
  424.         // test if the next rectangle unioned with the current bound is larger   
  425.         if (clip_list[index].left < region_data->rdh.rcBound.left)   
  426.             region_data->rdh.rcBound.left = clip_list[index].left;   
  427.            
  428.         if (clip_list[index].right > region_data->rdh.rcBound.right)   
  429.             region_data->rdh.rcBound.right = clip_list[index].right;   
  430.            
  431.         if (clip_list[index].top < region_data->rdh.rcBound.top)   
  432.             region_data->rdh.rcBound.top = clip_list[index].top;   
  433.            
  434.         if (clip_list[index].bottom > region_data->rdh.rcBound.bottom)   
  435.             region_data->rdh.rcBound.bottom = clip_list[index].bottom;   
  436.            
  437.     } // end for index   
  438.        
  439.     // now we have computed the bounding rectangle region and set up the data   
  440.     // now let's set the clipping list   
  441.        
  442.     if (FAILED(lpddclipper->SetClipList(region_data, 0)))   
  443.     {   
  444.         // release memory and return error   
  445.         free(region_data);   
  446.         return(NULL);   
  447.     } // end if   
  448.        
  449.     // now attach the clipper to the surface   
  450.     if (FAILED(lpdds->SetClipper(lpddclipper)))   
  451.     {   
  452.         // release memory and return error   
  453.         free(region_data);   
  454.         return(NULL);   
  455.     } // end if   
  456.        
  457.     // all is well, so release memory and send back the pointer to the new clipper   
  458.     free(region_data);   
  459.     return(lpddclipper);   
  460.        
  461. // end DDraw_Attach_Clipper   
  462.    
  463. ///      
  464.    
  465. int DDraw_Fill_Surface(LPDIRECTDRAWSURFACE7 lpdds,int color)   
  466. {   
  467.     DDBLTFX ddbltfx; // this contains the DDBLTFX structure   
  468.        
  469.     // clear out the structure and set the size field    
  470.     DDRAW_INIT_STRUCT(ddbltfx);   
  471.        
  472.     // set the dwfillcolor field to the desired color   
  473.     ddbltfx.dwFillColor = color;    
  474.    
  475.            
  476.    
  477.    
  478.     // ready to blt to surface   
  479.     lpdds->Blt(NULL,       // ptr to dest rectangle   
  480.         NULL,       // ptr to source surface, NA               
  481.         NULL,       // ptr to source rectangle, NA   
  482.         DDBLT_COLORFILL | DDBLT_WAIT ,   // fill and wait                      
  483.         &ddbltfx);  // ptr to DDBLTFX structure   
  484.        
  485.     // return success   
  486.     return(1);   
  487. // end DDraw_Fill_Surface   
  488.    
  489. ///   
  490. int DDraw_Draw_Surface(LPDIRECTDRAWSURFACE7 source, // 要画的源表面   
  491.         int x, int y,                 // 要绘制的位置   
  492.         int width, int height,        // 源表面的尺寸   
  493.         LPDIRECTDRAWSURFACE7 dest,    // 要画的目标表面   
  494.         int transparent = 1)          //透明颜色标志   
  495. {   
  496.     // draw a bob at the x,y defined in the BOB   
  497.     // on the destination surface defined in dest   
  498.        
  499.     RECT dest_rect, //目标矩形   
  500.         source_rect; // 源矩形                                  
  501.        
  502.     //设置目标矩形的数据   
  503.     dest_rect.left   = x;   
  504.     dest_rect.top    = y;   
  505.     dest_rect.right  = x+width-1;   
  506.     dest_rect.bottom = y+height-1;   
  507.        
  508.      //设置源矩形的数据   
  509.     source_rect.left    = 0;   
  510.     source_rect.top     = 0;   
  511.     source_rect.right   = width-1;   
  512.     source_rect.bottom  = height-1;   
  513.        
  514.      // 透明度标志测试   
  515.        
  516.     if (transparent)   
  517.     {   
  518.         //启用色彩键   
  519.         // blt 到目的表面   
  520.         if (FAILED(dest->Blt(&dest_rect, source,   
  521.             &source_rect,(DDBLT_WAIT | DDBLT_KEYSRC),   
  522.             NULL)))   
  523.             return(0);   
  524.            
  525.     } // end if   
  526.     else   
  527.     {   
  528.         // 没有色彩键   
  529.         // blt 到目的表面   
  530.         if (FAILED(dest->Blt(&dest_rect, source,   
  531.             &source_rect,(DDBLT_WAIT),   
  532.             NULL)))   
  533.             return(0);   
  534.            
  535.     } // end if   
  536.        
  537.     // return success   
  538.     return(1);   
  539.        
  540. // end DDraw_Draw_Surface