看WIndows遊戲程式設計大師技巧,中有這麼一個範例,不過是隻有3個自動移動的機器人,8位顯示模式

然後自己手癢,就改成這樣了,32位顯示模式 讀取32點陣圖,加入角色控制,以及子彈發射

這玩意。真要算時間的話,也蠻久的了。11年開始寫。然後遇到某些原因,停了下來,然後最近這周又開始寫,終於寫出來了

期間遇到很多難處,基本無人可問,全憑自己研究,實在不容易啊,所以放上網,等有需要的人蔘考下吧

程式碼是VC6寫的,VS2010的自己改下就行了。不會改的就下個VC6吧- –

編譯程式碼前記得安裝DX9.0 SDK 

工程記得新增資源Microsoft DirectX SDK (March 2009)Libx86 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 <windows.h>   // include important windows stuff   
  8. #include <windowsx.h>    
  9. #include <mmsystem.h>   
  10. #include <iostream.h> // include important C/C++ stuff   
  11. #include <conio.h>   
  12. #include <stdlib.h>   
  13. #include <malloc.h>   
  14. #include <memory.h>   
  15. #include <string.h>   
  16. #include <stdarg.h>   
  17. #include <stdio.h>    
  18. #include <math.h>   
  19. #include <io.h>   
  20. #include <fcntl.h>   
  21.    
  22. #include <ddraw.h> // include directdraw   
  23. #include <list>   
  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<ALIEN_AMM> 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(" filename:%s  size=%d  width=%d  height=%d  bitsperpixel=%d  colors=%d  impcolors=%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<num_rects; 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