看WIndows遊戲編程大師技巧,中有這麼一個範例,不過是隻有3個自動移動的機器人,8位顯示模式ios
而後本身手癢,就改爲這樣了,32位顯示模式 讀取32位圖,加入角色控制,以及×××發射編程
這玩意。真要算時間的話,也蠻久的了。11年開始寫。而後遇到某些緣由,停了下來,而後最近這周又開始寫,終於寫出來了windows
期間遇到不少難處,基本無人可問,全憑本身研究,實在不容易啊,因此放上網,等有須要的人蔘考下吧api
代碼是VC6寫的,VS2010的本身改下就好了。不會改的就下個VC6吧- -app
編譯代碼前記得安裝DX9.0 SDK ide
工程記得添加資源Microsoft DirectX SDK (March 2009)\Lib\x86\ ddraw.lib函數
ESC 退出oop
方向鍵-> 移動測試
長按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("\nfilename:%s \nsize=%d \nwidth=%d \nheight=%d \nbitsperpixel=%d \ncolors=%d \nimpcolors=%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