看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动态演示
都是我自己的博客来的....当时因为这里太蛋疼的限制。才发那边的
- // 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 *image, 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 *image, int bytes_per_line, int height)
- {
- // this function is used to flip bottom-up .BMP images
- UCHAR *buffer; // used to perform the image processing
- int index; // looping index
- // allocate the temporary buffer
- if (!(buffer = (UCHAR *)malloc(bytes_per_line*height)))
- return(0);
- // copy image to work area
- memcpy(buffer,image,bytes_per_line*height);
- // flip vertically
- for (index=0; index < height; index++)
- memcpy(&image[((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