看WIndows遊戲程式設計大師技巧,中有這麼一個範例,不過是隻有3個自動移動的機器人,8位顯示模式
然後自己手癢,就改成這樣了,32位顯示模式 讀取32點陣圖,加入角色控制,以及子彈發射
這玩意。真要算時間的話,也蠻久的了。11年開始寫。然後遇到某些原因,停了下來,然後最近這周又開始寫,終於寫出來了
期間遇到很多難處,基本無人可問,全憑自己研究,實在不容易啊,所以放上網,等有需要的人蔘考下吧
程式碼是VC6寫的,VS2010的自己改下就行了。不會改的就下個VC6吧- –
編譯程式碼前記得安裝DX9.0 SDK
工程記得新增資源Microsoft DirectX SDK (March 2009)Libx86 ddraw.lib
ESC 退出
方向鍵-> 移動
長按A 開槍
蛋疼的網站,程式碼要分成3塊才能發上來。。
圖片上傳還限大小。。。只能傳別的網站
演示:
都是我自己的部落格來的….當時因為這裡太蛋疼的限制。才發那邊的
- // INCLUDES ///////////////////////////////////////////////
- #define WIN32_LEAN_AND_MEAN // just say no to MFC
- #define INITGUID
- #include <windows.h> // include important windows stuff
- #include <windowsx.h>
- #include <mmsystem.h>
- #include <iostream.h> // include important C/C++ stuff
- #include <conio.h>
- #include <stdlib.h>
- #include <malloc.h>
- #include <memory.h>
- #include <string.h>
- #include <stdarg.h>
- #include <stdio.h>
- #include <math.h>
- #include <io.h>
- #include <fcntl.h>
- #include <ddraw.h> // include directdraw
- #include <list>
- // DEFINES ////////////////////////////////////////////////
- // defines for windows
- #define WINDOW_CLASS_NAME "WINCLASS1"
- // default screen size
- #define SCREEN_WIDTH 640 // size of screen
- #define SCREEN_HEIGHT 480
- #define SCREEN_BPP 32 // bits per pixel
- #define BITMAP_ID 0x4D42 // universal id for a bitmap
- #define MAX_COLORS_PALETTE 256
- #define _RGB32BIT(a,r,g,b) ((b) + ((g) << 8) + ((r) << 16) + ((a) << 24))
- #define ALLEY "alley32.bmp"
- #define DEDSP "Dedsp32.bmp"
- #define OLD 1
- int BMPBIT=32;
- // TYPES //////////////////////////////////////////////////////
- // basic unsigned types
- typedef unsigned short USHORT;
- typedef unsigned short WORD;
- typedef unsigned char UCHAR;
- typedef unsigned char BYTE;
- // //BMP 點陣圖容器 結構
- typedef struct BITMAP_FILE_TAG
- {
- BITMAPFILEHEADER bitmapfileheader; // 包含點陣圖檔案頭
- BITMAPINFOHEADER bitmapinfoheader; // 點陣圖資訊段,包含調色盤(如果有的話)
- PALETTEENTRY palette[256]; // 調色盤我們將儲存在這裡
- UCHAR *buffer; // 資料指標
- } BITMAP_FILE, *BITMAP_FILE_PTR;
- // this will hold our little alien
- typedef struct ALIEN_OBJ_TYP
- {
- // LPDIRECTDRAWSURFACE7 表面描繪的介面
- LPDIRECTDRAWSURFACE7 frames[3], // 三幀的動畫完整步行週期
- animation_fire_frames[3],//三幀開火動畫
- fire_frames;//火球
- int x,y; //外星人的位置
- int velocity; //X座標的速度
- int current_frame; // 當前移動幀的動畫
- int current_animation_fire_frames;//當前開火幀的動畫
- int counter; // 移動動畫的使用時間
- int counter_animation_fire;//開火動畫的使用時間
- } ALIEN_OBJ, *ALIEN_OBJ_PTR;
- //彈藥結構
- struct ALIEN_AMM
- {
- int x,y; //彈藥座標
- int velocity; //X座標的速度
- bool life;//判斷彈藥生命週期是否結束
- };
- // PROTOTYPES //////////////////////////////////////////////
- //翻轉點陣圖
- int Flip_Bitmap(UCHAR *p_w_picpath, int bytes_per_line, int height);
- //讀取點陣圖
- int Load_Bitmap_File(BITMAP_FILE_PTR bitmap, char *filename);
- int Unload_Bitmap_File(BITMAP_FILE_PTR bitmap);
- //生成離屏表面
- LPDIRECTDRAWSURFACE7 DDraw_Create_Surface(int width, int height, int mem_flags);
- //生成剪輯器
- LPDIRECTDRAWCLIPPER DDraw_Attach_Clipper(LPDIRECTDRAWSURFACE7 lpdds, int num_rects, LPRECT clip_list);
- //填充表面
- int DDraw_Fill_Surface(LPDIRECTDRAWSURFACE7 lpdds,int color);
- //掃描點陣圖
- int Scan_Image_Bitmap(BITMAP_FILE_PTR bitmap, LPDIRECTDRAWSURFACE7 lpdds, int cx,int cy);
- int DDraw_Draw_Surface(LPDIRECTDRAWSURFACE7 source, int x, int y,
- int width, int height, LPDIRECTDRAWSURFACE7 dest,
- int transparent);
- int Draw_Text_GDI(char *text, int x,int y,COLORREF color, LPDIRECTDRAWSURFACE7 lpdds);
- // MACROS /////////////////////////////////////////////////
- // tests if a key is up or down
- #define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
- #define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
- // initializes a direct draw struct
- #define DDRAW_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }
- // GLOBALS ////////////////////////////////////////////////
- HWND main_window_handle = NULL; // globally track main window
- int window_closed = 0; // tracks if window is closed
- HINSTANCE hinstance_app = NULL; // globally track hinstance
- // directdraw stuff
- LPDIRECTDRAW7 lpdd = NULL; // 申請介面物件
- LPDIRECTDRAWSURFACE7 lpddsprimary = NULL; //主表面
- LPDIRECTDRAWSURFACE7 lpddsback = NULL; //背面
- LPDIRECTDRAWPALETTE lpddpal = NULL; //調色盤指標
- LPDIRECTDRAWCLIPPER lpddclipper = NULL; //剪下器
- PALETTEENTRY palette[256]; // 調色盤
- PALETTEENTRY save_palette[256]; // 用於儲存調色盤
- DDSURFACEDESC2 ddsd; // 直接繪製表面的描述結構
- DDBLTFX ddbltfx; // 用來填充
- DDSCAPS2 ddscaps; //直接繪製表面的功能結構
- HRESULT ddrval; // result back from dd calls
- DWORD start_clock_count = 0; //用於定時
- BITMAP_FILE bitmap; // holds the bitmap
- ALIEN_OBJ aliens[3]; //3個外星人
- std::list<ALIEN_AMM> aliens_amm; //用LIST容器存放彈藥結構
- bool first_fire;
- ALIEN_AMM aa={-80,-80,6,false};//彈藥座標X,Y X座標的速度 判斷彈藥生命週期是否結束 false 等於結束
- LPDIRECTDRAWSURFACE7 lpddsbackground=NULL; //這將保留背景圖片
- char buffer[80]; // general printing buffer
- int gwidth = -1;
- int gheight = -1;
- // FUNCTIONS ////////////////////////////////////////////////
- int Load_Bitmap_File(BITMAP_FILE_PTR bitmap, char *filename)
- {
- //此函式開啟一個點陣圖檔案,並載入資料匯入點陣圖
- int file_handle, // 檔案控制程式碼
- index; // 迴圈用的變數
- UCHAR *temp_buffer = NULL; //用於把24位轉換成16位的影像
- OFSTRUCT file_data; // 檔案的資料資訊
- //開啟檔案,如果存在的話
- if ((file_handle = OpenFile(filename,&file_data,OF_READ))==-1)
- return(0);
- // 現在載入點陣圖檔案頭
- _lread(file_handle, &bitmap->bitmapfileheader,sizeof(BITMAPFILEHEADER));
- // 測試,如果這是一個點陣圖檔案
- if (bitmap->bitmapfileheader.bfType!=BITMAP_ID)
- {
- // 關閉檔案
- _lclose(file_handle);
- // 返回 error
- return(0);
- } // end if
- //現在我們知道這是一個點陣圖,所以在讀取所有部分之前,
- // 首先是讀取點陣圖的 infoheader
- //現在載人點陣圖檔案頭
- _lread(file_handle, &bitmap->bitmapinfoheader,sizeof(BITMAPINFOHEADER));
- // 最後,讀取影像資料本身
- _llseek(file_handle,-(int)(bitmap->bitmapinfoheader.biSizeImage),SEEK_END);
- //現在讀的影像,如果影像是8位或16位則僅僅是讀取它,
- //但如果是24位,就讀入一個臨時區域,然後將其轉換為16位的影像
- if (bitmap->bitmapinfoheader.biBitCount==8 || bitmap->bitmapinfoheader.biBitCount==16 ||
- bitmap->bitmapinfoheader.biBitCount==24||bitmap->bitmapinfoheader.biBitCount==32)
- {
- // 刪除最後的影像,如果有的話
- if (bitmap->buffer)
- free(bitmap->buffer);
- // 為影像分配記憶體
- if (!(bitmap->buffer = (UCHAR *)malloc(bitmap->bitmapinfoheader.biSizeImage)))
- {
- //分配失敗,關閉檔案
- _lclose(file_handle);
- // 返回 error
- return(0);
- } // end if
- // 現在讀取它
- _lread(file_handle,bitmap->buffer,bitmap->bitmapinfoheader.biSizeImage);
- } // end if
- else
- {
- // 出現嚴重問題
- return(0);
- } // end else
- #if 0
- // 寫出來的檔案資訊
- printf(" filename:%s size=%d width=%d height=%d bitsperpixel=%d colors=%d impcolors=%d",
- filename,
- bitmap->bitmapinfoheader.biSizeImage,
- bitmap->bitmapinfoheader.biWidth,
- bitmap->bitmapinfoheader.biHeight,
- bitmap->bitmapinfoheader.biBitCount,
- bitmap->bitmapinfoheader.biClrUsed,
- bitmap->bitmapinfoheader.biClrImportant);
- #endif
- // 關閉檔案
- _lclose(file_handle);
- // 翻轉點陣圖
- Flip_Bitmap(bitmap->buffer,
- bitmap->bitmapinfoheader.biWidth*(bitmap->bitmapinfoheader.biBitCount/8),
- bitmap->bitmapinfoheader.biHeight);
- return(1);
- } // end Load_Bitmap_File
- ///////////////////////////////////////////////////////////
- int Unload_Bitmap_File(BITMAP_FILE_PTR bitmap)
- {
- // this function releases all memory associated with "bitmap"
- if (bitmap->buffer)
- {
- // release memory
- free(bitmap->buffer);
- // reset pointer
- bitmap->buffer = NULL;
- } // end if
- // return success
- return(1);
- } // end Unload_Bitmap_File
- ///////////////////////////////////////////////////////////
- int Flip_Bitmap(UCHAR *p_w_picpath, int bytes_per_line, int height)
- {
- // this function is used to flip bottom-up .BMP p_w_picpaths
- UCHAR *buffer; // used to perform the p_w_picpath processing
- int index; // looping index
- // allocate the temporary buffer
- if (!(buffer = (UCHAR *)malloc(bytes_per_line*height)))
- return(0);
- // copy p_w_picpath to work area
- memcpy(buffer,p_w_picpath,bytes_per_line*height);
- // flip vertically
- for (index=0; index < height; index++)
- memcpy(&p_w_picpath[((height-1) - index)*bytes_per_line],
- &buffer[index*bytes_per_line], bytes_per_line);
- // release the memory
- free(buffer);
- // return success
- return(1);
- } // end Flip_Bitmap
- LPDIRECTDRAWSURFACE7 DDraw_Create_Surface(int width, int height, int mem_flags)
- {
- // 這個函式建立一個簡單的離屏表面
- DDSURFACEDESC2 ddsd; // working description
- LPDIRECTDRAWSURFACE7 lpdds; //臨時表用的面
- // /設定寬,高,CAPS成員有效
- memset(&ddsd,0,sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
- //設定新點陣圖表面的尺寸
- ddsd.dwWidth = width;
- ddsd.dwHeight = height;
- // set surface to offscreen plain
- ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | mem_flags;
- // 建立表面
- if (FAILED(lpdd->CreateSurface(&ddsd,&lpdds,NULL)))
- return(NULL);
- // 設定色彩索引0為透明色 (黑)
- DDCOLORKEY color_key; // used to set color key
- color_key.dwColorSpaceLowValue = 0;
- color_key.dwColorSpaceHighValue =0;
- // now set the color key for source blitting
- lpdds->SetColorKey(DDCKEY_SRCBLT, &color_key);
- // end if
- // return surface
- return(lpdds);
- } // end DDraw_Create_Surface
- ///////////////////////////////////////////////////////////////
- LPDIRECTDRAWCLIPPER DDraw_Attach_Clipper(LPDIRECTDRAWSURFACE7 lpdds,
- int num_rects,
- LPRECT clip_list)
- {
- // this function creates a clipper from the sent clip list and attaches
- // it to the sent surface
- //這個函式建立一個從傳送剪輯列表Clipper和其附加到傳送的表面
- int index; // 迴圈變數
- LPDIRECTDRAWCLIPPER lpddclipper; // pointer to the newly created dd clipper
- LPRGNDATA region_data; // pointer to the region data that contains
- // the header and clip list
- // first create the direct draw clipper
- if (FAILED(lpdd->CreateClipper(0,&lpddclipper,NULL)))
- return(NULL);
- // now create the clip list from the sent data
- // first allocate memory for region data
- region_data = (LPRGNDATA)malloc(sizeof(RGNDATAHEADER)+num_rects*sizeof(RECT));
- // now copy the rects into region data
- memcpy(region_data->Buffer, clip_list, sizeof(RECT)*num_rects);
- // set up fields of header
- region_data->rdh.dwSize = sizeof(RGNDATAHEADER);
- region_data->rdh.iType = RDH_RECTANGLES;
- region_data->rdh.nCount = num_rects;
- region_data->rdh.nRgnSize = num_rects*sizeof(RECT);
- region_data->rdh.rcBound.left = 64000;
- region_data->rdh.rcBound.top = 64000;
- region_data->rdh.rcBound.right = -64000;
- region_data->rdh.rcBound.bottom = -64000;
- // find bounds of all clipping regions
- for (index=0; index<num_rects; index++)
- {
- // test if the next rectangle unioned with the current bound is larger
- if (clip_list[index].left < region_data->rdh.rcBound.left)
- region_data->rdh.rcBound.left = clip_list[index].left;
- if (clip_list[index].right > region_data->rdh.rcBound.right)
- region_data->rdh.rcBound.right = clip_list[index].right;
- if (clip_list[index].top < region_data->rdh.rcBound.top)
- region_data->rdh.rcBound.top = clip_list[index].top;
- if (clip_list[index].bottom > region_data->rdh.rcBound.bottom)
- region_data->rdh.rcBound.bottom = clip_list[index].bottom;
- } // end for index
- // now we have computed the bounding rectangle region and set up the data
- // now let`s set the clipping list
- if (FAILED(lpddclipper->SetClipList(region_data, 0)))
- {
- // release memory and return error
- free(region_data);
- return(NULL);
- } // end if
- // now attach the clipper to the surface
- if (FAILED(lpdds->SetClipper(lpddclipper)))
- {
- // release memory and return error
- free(region_data);
- return(NULL);
- } // end if
- // all is well, so release memory and send back the pointer to the new clipper
- free(region_data);
- return(lpddclipper);
- } // end DDraw_Attach_Clipper
- ///////////////////////////////////////////////////////////
- int DDraw_Fill_Surface(LPDIRECTDRAWSURFACE7 lpdds,int color)
- {
- DDBLTFX ddbltfx; // this contains the DDBLTFX structure
- // clear out the structure and set the size field
- DDRAW_INIT_STRUCT(ddbltfx);
- // set the dwfillcolor field to the desired color
- ddbltfx.dwFillColor = color;
- // ready to blt to surface
- lpdds->Blt(NULL, // ptr to dest rectangle
- NULL, // ptr to source surface, NA
- NULL, // ptr to source rectangle, NA
- DDBLT_COLORFILL | DDBLT_WAIT , // fill and wait
- &ddbltfx); // ptr to DDBLTFX structure
- // return success
- return(1);
- } // end DDraw_Fill_Surface
- ///////////////////////////////////////////////////////////////
- int DDraw_Draw_Surface(LPDIRECTDRAWSURFACE7 source, // 要畫的源表面
- int x, int y, // 要繪製的位置
- int width, int height, // 源表面的尺寸
- LPDIRECTDRAWSURFACE7 dest, // 要畫的目標表面
- int transparent = 1) //透明顏色標誌
- {
- // draw a bob at the x,y defined in the BOB
- // on the destination surface defined in dest
- RECT dest_rect, //目標矩形
- source_rect; // 源矩形
- //設定目標矩形的資料
- dest_rect.left = x;
- dest_rect.top = y;
- dest_rect.right = x+width-1;
- dest_rect.bottom = y+height-1;
- //設定源矩形的資料
- source_rect.left = 0;
- source_rect.top = 0;
- source_rect.right = width-1;
- source_rect.bottom = height-1;
- // 透明度標誌測試
- if (transparent)
- {
- //啟用色彩鍵
- // blt 到目的表面
- if (FAILED(dest->Blt(&dest_rect, source,
- &source_rect,(DDBLT_WAIT | DDBLT_KEYSRC),
- NULL)))
- return(0);
- } // end if
- else
- {
- // 沒有色彩鍵
- // blt 到目的表面
- if (FAILED(dest->Blt(&dest_rect, source,
- &source_rect,(DDBLT_WAIT),
- NULL)))
- return(0);
- } // end if
- // return success
- return(1);
- } // end DDraw_Draw_Surface