依样画葫芦的照着写了一个。
先把代码贴在这儿,随时查阅。
#pragma comment(lib,"dxguid.lib") #include <windows.h> #include <windowsx.h> #include <mmsystem.h> #include <iostream.h> #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> #define KEYDOWN(key) ((GetAsyncKeyState(key) & 0x8000) ? 1 : 0) #define KEYUP(key) ((GetAsyncKeyState(key) & 0x8000) ? 0 : 1) #define DD_INIT_STRUCT(ddstruct){memset(&ddstruct,0,sizeof(ddstruct));ddstruct.dwSize=sizeof(ddstruct);} #define SCREEN_WIDTH 640 #define SCREEN_HEIGHT 480 #define SCREEN_BPP 8 #define SPEED_X 3 #define SPEED_Y 3 #define ANINUM 50 #define BITMAP_ID 0x4D42 #define MAX_COLORS_PALETTE 256 //图片结构体 typedef struct BITMAP_FILE_TAG { BITMAPFILEHEADER bitmapfileheader; BITMAPINFOHEADER bitmapinfoheader; PALETTEENTRY palette[256]; UCHAR *buffer; } BITMAP_FILE, *BITMAP_FILE_PTR; typedef struct ALIEN_OBJ_TYP { LPDIRECTDRAWSURFACE7 frames[3]; int x,y; int velocity; int current_frame; int counter; } ALIEN_OBJ, *ALIEN_OBJ_PTR; LPDIRECTDRAW7 lpdd = NULL; // dd4 object LPDIRECTDRAWSURFACE7 lpddsprimary = NULL; // dd primary surface LPDIRECTDRAWSURFACE7 lpddsback = NULL; // dd back surface LPDIRECTDRAWPALETTE lpddpal = NULL; // a pointer to the created dd palette LPDIRECTDRAWCLIPPER lpddclipper = NULL; // dd clipper PALETTEENTRY palette[256]; // color palette PALETTEENTRY save_palette[256]; // used to save palettes DDSURFACEDESC2 ddsd; // a direct draw surface description struct DDBLTFX ddbltfx; // used to fill DDSCAPS2 ddscaps; // a direct draw surface capabilities struct HRESULT ddrval; // result back from dd calls DWORD start_clock_count = 0; // used for timing BITMAP_FILE bitmap; // holds the bitmap ALIEN_OBJ aliens[3]; // 3 aliens, one on each level LPDIRECTDRAWSURFACE7 lpddsbackground = NULL;// this will hold the background image int window_closed=0; #define _RGB16BIT555(r,g,b) ((b&31)+((g&31)<<5)+((r&31)<<10)) #define _RGB16BIT565(r,g,b) ((b&31)+((g&63)<<5)+((r&31)<<11)) #define _RGB32BIT(a,r,g,b) ((b)+((g)<<8)+((r)<<16)+((a)<<24)) int gwidth = -1; int gheight = -1; //从源表面拷贝一个矩形到桌面显示 int DDraw_Draw_Surface(LPDIRECTDRAWSURFACE7 source,int x, int y,int width,int height,LPDIRECTDRAWSURFACE7 dest,int transparent=1) { 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) { if (FAILED(dest->Blt(&dest_rect,source,&source_rect,(DDBLT_WAIT|DDBLT_KEYSRC),NULL))) return(0); } else { if (FAILED(dest->Blt(&dest_rect,source,&source_rect,(DDBLT_WAIT),NULL))) return(0); } return(1); } //得到一个包含所有目标矩形的剪贴板 LPDIRECTDRAWCLIPPER DDraw_Attach_Clipper(LPDIRECTDRAWSURFACE7 lpdds,int num_rects,LPRECT clip_list) { int index; LPDIRECTDRAWCLIPPER lpddclipper; LPRGNDATA region_data; if (FAILED(lpdd->CreateClipper(0,&lpddclipper,NULL))) return(NULL); region_data=(LPRGNDATA)malloc(sizeof(RGNDATAHEADER)+num_rects*sizeof(RECT)); memcpy(region_data->Buffer,clip_list,sizeof(RECT)*num_rects); 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; for(index=0;index<num_rects;index++) { 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; } if(FAILED(lpddclipper->SetClipList(region_data, 0))) { free(region_data); return(NULL); } if(FAILED(lpdds->SetClipper(lpddclipper))) { free(region_data); return(NULL); } free(region_data); return(lpddclipper); } //加载一副图片,图片路径:filename int Flip_Bitmap(UCHAR *image, int bytes_per_line, int height) { UCHAR *buffer; int index; if(!(buffer=(UCHAR*)malloc(bytes_per_line*height))) return 0; memcpy(buffer,image,bytes_per_line*height); for(index=0;index<height;index++) memcpy(&image[((height-1)-index)*bytes_per_line],&buffer[index*bytes_per_line],bytes_per_line); free(buffer); return(1); } int Load_Bitmap_File(BITMAP_FILE_PTR bitmap,char *filename) { int file_handle,index; UCHAR *temp_buffer=NULL; 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); return(0); } _lread(file_handle,&bitmap->bitmapinfoheader,sizeof(BITMAPINFOHEADER)); if (bitmap->bitmapinfoheader.biBitCount==8) { _lread(file_handle,&bitmap->palette,MAX_COLORS_PALETTE*sizeof(PALETTEENTRY)); for (index=0;index<MAX_COLORS_PALETTE;index++) { int temp_color=bitmap->palette[index].peRed; bitmap->palette[index].peRed=bitmap->palette[index].peBlue; bitmap->palette[index].peBlue=temp_color; bitmap->palette[index].peFlags=PC_NOCOLLAPSE; } } _lseek(file_handle,-(int)(bitmap->bitmapinfoheader.biSizeImage),SEEK_END); if (bitmap->bitmapinfoheader.biBitCount==8||bitmap->bitmapinfoheader.biBitCount==16||bitmap->bitmapinfoheader.biBitCount==24) { if(bitmap->buffer) free(bitmap->buffer); if(!(bitmap->buffer=(UCHAR *)malloc(bitmap->bitmapinfoheader.biSizeImage))) { _lclose(file_handle); return(0); } _lread(file_handle,bitmap->buffer,bitmap->bitmapinfoheader.biSizeImage); } else { return(0); } #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); } //用调色板编号为color的颜色填充整个屏幕 int DDraw_Fill_Surface(LPDIRECTDRAWSURFACE7 lpdds,int color) { DDBLTFX ddbltfx; DD_INIT_STRUCT(ddbltfx); ddbltfx.dwFillColor=color; lpdds->Blt(NULL,NULL,NULL,DDBLT_COLORFILL|DDBLT_WAIT,&ddbltfx); return(1); } //创建一个可以过滤颜色的表面 LPDIRECTDRAWSURFACE7 DDraw_Create_Surface(int width,int height,int mem_flags,int color_key=0) { DDSURFACEDESC2 ddsd; LPDIRECTDRAWSURFACE7 lpdds; memset(&ddsd,0,sizeof(ddsd)); ddsd.dwSize=sizeof(ddsd); ddsd.dwFlags=DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT; ddsd.dwWidth=width; ddsd.dwHeight=height; ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN|mem_flags; if(FAILED(lpdd->CreateSurface(&ddsd,&lpdds,NULL))) return(NULL); if(color_key>=0) { DDCOLORKEY color_key; color_key.dwColorSpaceLowValue=0; color_key.dwColorSpaceHighValue=0; lpdds->SetColorKey(DDCKEY_SRCBLT,&color_key); } return(lpdds); } //释放图片内存 int Unload_Bitmap_File(BITMAP_FILE_PTR bitmap) { if (bitmap->buffer) { free(bitmap->buffer); bitmap->buffer=NULL; } return(1); } //显示一张图片 int Scan_Image_Bitmap(BITMAP_FILE_PTR bitmap,LPDIRECTDRAWSURFACE7 lpdds,int cx,int cy) { UCHAR *source_ptr,*dest_ptr; DDSURFACEDESC2 ddsd; ddsd.dwSize=sizeof(ddsd); lpdds->Lock(NULL,&ddsd,DDLOCK_WAIT|DDLOCK_SURFACEMEMORYPTR,NULL); cx=cx*(ddsd.dwWidth+1)+1; cy=cy*(ddsd.dwHeight+1)+1; gwidth=ddsd.dwWidth; gheight=ddsd.dwHeight; source_ptr=bitmap->buffer+cy*bitmap->bitmapinfoheader.biWidth+cx; dest_ptr=(UCHAR *)ddsd.lpSurface; for (int index_y=0;index_y<ddsd.dwHeight;index_y++) { memcpy(dest_ptr,source_ptr,ddsd.dwWidth); dest_ptr+=(ddsd.lPitch); source_ptr+=bitmap->bitmapinfoheader.biWidth; } lpdds->Unlock(NULL); return(1); } void Plot_Pixel_Faster32(int x,int y,int a,int r,int g,int b,UINT *video_buffer,int lpitch32) { UINT color; color=_RGB32BIT(a,r,g,b); video_buffer[x+y*lpitch32]=color; } HWND hwd; HINSTANCE hIns; HDC hdc; LRESULT CALLBACK WinSunProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { HDC hdc; PAINTSTRUCT ps; switch(uMsg) { case WM_PAINT: hdc=BeginPaint(hwnd,&ps); EndPaint(hwnd,&ps); break; case WM_DESTROY: PostQuitMessage(0); break; default: break; } return DefWindowProc(hwnd,uMsg,wParam,lParam); } void Blt_Clip(int x,int y,int width,int height,UCHAR *bitmap,UCHAR *video_buffer,int mempitch) { if((x>=SCREEN_WIDTH)||(y>=SCREEN_HEIGHT)||((x+width)<=0)||((y+height)<=0)) return; int x1=x; int y1=y; int x2=x+width-1; int y2=y+height-1; if(x1<0) x1=0; if(y1<0) y1=0; if(x2>SCREEN_WIDTH) x2=SCREEN_WIDTH; if(y2>SCREEN_HEIGHT) y2=SCREEN_HEIGHT; int x_off=x-x1; int y_off=y-y1; int dx=x2-x1+1; int dy=y2-y1+1; video_buffer=video_buffer+(x1+y1*mempitch); bitmap=bitmap+(x_off+y_off*width); int i,j; UCHAR pixel; for(j=0;j<dy;j++) { for(i=0;i<dx;i++) { pixel=bitmap[i]; video_buffer[i]=pixel; } video_buffer=video_buffer+mempitch; bitmap=bitmap+width; } } void Game_Init() { if(FAILED(DirectDrawCreateEx(NULL,(void**)&lpdd,IID_IDirectDraw7,NULL))) return; if(FAILED(lpdd->SetCooperativeLevel(hwd,DDSCL_FULLSCREEN|DDSCL_ALLOWMODEX|DDSCL_EXCLUSIVE|DDSCL_ALLOWREBOOT))) return; if(FAILED(lpdd->SetDisplayMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,0,0))) return; DD_INIT_STRUCT(ddsd); ddsd.dwFlags=DDSD_CAPS|DDSD_BACKBUFFERCOUNT; ddsd.dwBackBufferCount=1; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_COMPLEX|DDSCAPS_FLIP; if(FAILED(lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL))) return; ddsd.ddsCaps.dwCaps=DDSCAPS_BACKBUFFER; if(FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps,&lpddsback))) return; int i; for(i=1;i<=254;i++) { palette[i].peRed=rand()%256; palette[i].peGreen=rand()%256; palette[i].peBlue=rand()%256; palette[i].peFlags=PC_NOCOLLAPSE; } palette[0].peRed=0; palette[0].peGreen=0; palette[0].peBlue=0; palette[0].peFlags=PC_NOCOLLAPSE; palette[255].peRed=255; palette[255].peGreen=255; palette[255].peBlue=255; palette[255].peFlags=PC_NOCOLLAPSE; if(FAILED(lpdd->CreatePalette(DDPCAPS_8BIT|DDPCAPS_ALLOW256|DDPCAPS_INITIALIZE,palette,&lpddpal, NULL))) return; if(FAILED(lpddsprimary->SetPalette(lpddpal))) return; RECT screen_rect={0,0,SCREEN_WIDTH-1,SCREEN_HEIGHT-1}; lpddclipper=DDraw_Attach_Clipper(lpddsback,1,&screen_rect); if(!Load_Bitmap_File(&bitmap,"alley8.bmp")) return; if(FAILED(lpddpal->SetEntries(0,0,MAX_COLORS_PALETTE,bitmap.palette))) return; DDraw_Fill_Surface(lpddsback,0); DDraw_Fill_Surface(lpddsprimary,0); lpddsbackground=DDraw_Create_Surface(SCREEN_WIDTH,SCREEN_HEIGHT,0,-1); lpddsbackground->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT,NULL); UCHAR* image_buffer=(UCHAR*)ddsd.lpSurface; if(ddsd.lPitch==SCREEN_WIDTH) { memcpy((void*)image_buffer,(void*)bitmap.buffer,SCREEN_WIDTH*SCREEN_HEIGHT); } else { UCHAR *dest=image_buffer; UCHAR *scr=bitmap.buffer; for(i=0;i<SCREEN_HEIGHT;i++) { memcpy((void*)dest,(void*)scr,SCREEN_WIDTH); dest=dest+ddsd.lPitch; scr=scr+SCREEN_WIDTH; } } if(FAILED(lpddsbackground->Unlock(NULL))) return; Unload_Bitmap_File(&bitmap); srand(GetTickCount()); aliens[0].x=rand()%SCREEN_WIDTH; aliens[0].y=116-72; aliens[0].velocity=2+rand()%4; aliens[0].current_frame=0; aliens[0].counter=0; aliens[1].x=rand()%SCREEN_WIDTH; aliens[1].y=246-72; aliens[1].velocity=2+rand()%4; aliens[1].current_frame=0; aliens[1].counter=0; aliens[2].x=rand()%SCREEN_WIDTH; aliens[2].y=382-72; aliens[2].velocity=2+rand()%4; aliens[2].current_frame=0; aliens[2].counter=0; if(!Load_Bitmap_File(&bitmap,"dedsp0.bmp")) return; for(i=0;i<3;i++) { aliens[0].frames[i]=DDraw_Create_Surface(72,80,0); Scan_Image_Bitmap(&bitmap,aliens[0].frames[i],i,0); } Unload_Bitmap_File(&bitmap); for(i=0;i<3;i++) aliens[1].frames[i]=aliens[2].frames[i]=aliens[0].frames[i]; return; } void Game_Main() { static int animation_seq[4]={0,1,0,2}; if(window_closed) return; if(KEYDOWN(VK_ESCAPE)) { PostMessage(hwd,WM_CLOSE,0,0); window_closed=1; } DDraw_Draw_Surface(lpddsbackground,0,0,SCREEN_WIDTH,SCREEN_HEIGHT,lpddsback,0); int i; for(i=0;i<3;i++) { aliens[i].x++; if(aliens[i].x>SCREEN_WIDTH) aliens[i].x=-80; if(++aliens[i].counter>=(8-aliens[i].velocity)) { aliens[i].counter=0; if(++aliens[i].current_frame>3) aliens[i].current_frame=0; } } for(i=0;i<3;i++) { DDraw_Draw_Surface(aliens[i].frames[animation_seq[aliens[i].current_frame]], aliens[i].x,aliens[i].y, 72,80, lpddsback); } while(FAILED(lpddsprimary->Flip(NULL,DDFLIP_WAIT))); Sleep(30); return; } void Game_Shut() { if(lpddpal) { lpddpal->Release(); lpddpal=NULL; } if(lpddsprimary) { lpddsprimary->Release(); lpddsprimary=NULL; } if(lpdd) { lpdd->Release(); lpdd=NULL; } } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdline, int nShowCmd ) { WNDCLASS wndclass; wndclass.cbClsExtra=0; wndclass.cbWndExtra=0; wndclass.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH); wndclass.hCursor=LoadCursor(NULL,IDC_ARROW); wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION); wndclass.hInstance=hInstance; wndclass.lpfnWndProc=WinSunProc; wndclass.lpszClassName="bingshen"; wndclass.lpszMenuName=NULL; wndclass.style=CS_HREDRAW|CS_VREDRAW; ShowCursor(FALSE); HWND hwnd; RegisterClass(&wndclass); hwnd=CreateWindow("bingshen","-------bingshen",WS_POPUP|WS_VISIBLE, 0,0,SCREEN_WIDTH,SCREEN_HEIGHT, NULL,NULL,hInstance,NULL); hwd=hwnd; hdc=GetDC(hwnd); hIns=hInstance; Game_Init(); MSG msg; while(true) { if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { if(msg.message==WM_QUIT) break; TranslateMessage(&msg); DispatchMessage(&msg); } Game_Main(); } Game_Shut(); ReleaseDC(hwnd,hdc); return msg.wParam; }