📄 game.cpp
字号:
/*********************************
[学VC编游戏]
编著、程序设计:唐明理 2004.7
E-mail: cqtml@163.com
**********************************/
#include "stdafx.h"
#include "game.h"
JCDZ zjdz[6]={0,5,40,10,120,10,200,10,280,10,360,5};//人动作结构400幅
//0站,1走, 2刺, 3劈, 4倒 5尸
JCDZ zjdw[6]={0,5,40,10,120,10,200,10,280,10,360,5};//兽动作结构400幅
//0站,1走, 2跑, 3斗, 4倒, 5尸
unsigned short dw[7][6]={0,1,1,3,4,5, //0豹,无跑
0,1,2,3,4,5, //1狼,
0,1,1,3,4,5, //2猪,无跑
0,1,2,3,4,5, //3鹿,
0,2,2,2,4,5, //4马,无走、斗
0,1,1,1,4,5, //5羊,无跑、斗
0,1,1,3,4,5 //6雀,无跑
};
////////////////////////////////////////////////////////////////////////////
game:: game(){} //构造函数
game::~game(){} //析构函数
//****************************************************************
// A、 init() 初始化,建立图形处理环境
// BkDC0-装载背景地面
// BkDC1-在此生成即时场景,在1个时钟周期后翻转到当前显示屏。
// MemDC-调入的对象图片。
//****************************************************************
BOOL game::init()//初始化
{ srand( (unsigned)time( NULL ) );
if(!InitDDraw()) //初始化DirectDraw环境。
return FALSE;
hScrDC=CreateDC("DISPLAY", NULL, NULL, NULL); //创建屏幕设备句柄
MemDC =CreateCompatibleDC(hScrDC); //创建对象设备句柄
hBMP0 =CreateCompatibleBitmap(hScrDC,100,100); //创建位图内存
hBMP1 =CreateCompatibleBitmap(hScrDC,100,100); //创建位图内存
hDC0 =CreateCompatibleDC(hScrDC);
hDC1 =CreateCompatibleDC(hScrDC);
SelectObject(hDC0, hBMP0);
SelectObject(hDC1, hBMP1);
/////////////////////////////////////////////////////////////////////////
GetCurrentDirectory(256,appdir);
dir=appdir;
if(dir.Right(8)=="运行程序")
dir="图片/";
else
dir="../运行程序/图片/"; //图片路径
sys=getsys(); //取当前系统
rs=0; //对象数置0
edi=0; //非编辑态
scrx=0;scry=0;
stmp=NULL;rtmp=NULL;jtmp=NULL;
find_p=0; //无搜索0有搜索1
SCRP0=5; //默认地图的是显示区5倍
rBlend.BlendOp = AC_SRC_OVER; //
rBlend.BlendFlags = 0; //
rBlend.AlphaFormat = 0; //
rBlend.SourceConstantAlpha=140;
return TRUE;
}
//**************************************************
// exit() 退出, 删除图形处理环境
//**************************************************
void game::exit()//退出
{ if(stmp!=NULL) delete[] stmp;//删除兽资源包
if(rtmp!=NULL) delete[] rtmp;//删除人资源包
if(jtmp!=NULL) delete[] jtmp;//删除景资源包
DeleteDC(hDC0);
DeleteDC(hDC1);
DeleteObject(hBMP0);
DeleteObject(hBMP1);
DeleteDC(MemDC); //删除对象设备句柄
DeleteDC(hScrDC); //删除屏幕设备句柄
}
//****************************************************
// getsys()//识别操作系统
// 使用TransparentBlt()透明显示的需要;
// 是WIN2000,直接调用TransparentBlt();否则调用自编的。
//****************************************************
int game::getsys()//识别操作系统
{ OSVERSIONINFO stOSVI ;
ZeroMemory(&stOSVI , sizeof ( OSVERSIONINFO )) ;
stOSVI.dwOSVersionInfoSize = sizeof ( OSVERSIONINFO ) ;
GetVersionEx ( &stOSVI);
int a=0;
if (stOSVI.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS &&
(stOSVI.dwMajorVersion>4||(stOSVI.dwMajorVersion==4
&& stOSVI.dwMinorVersion>0)))
a=1;// rec="Windows98";
if (VER_PLATFORM_WIN32_NT==stOSVI.dwPlatformId&&stOSVI.dwMajorVersion>=5)
a=2;// rec="Windows2000";
if (VER_PLATFORM_WIN32_NT==stOSVI.dwPlatformId&&stOSVI.dwMajorVersion==4)
a=3;// rec="WindowsNT4.0";
if (VER_PLATFORM_WIN32_NT==stOSVI.dwPlatformId)
a=4;// rec="WindowsNT";
return a;
}
//**********************************************************
// inscreer(int i)//在显示区?
//**********************************************************
BOOL game::inscreer(int i)//在显示区?
{ int xs=man[i].xix-scrx-man[i].w/2; //x当前位置
int ys=man[i].xiy-scry-man[i].h; //y当前位置
if(xs>(-man[i].w+2)&&xs<WIDTH&&ys>(-man[i].h+10)&&ys<HEIGHT)
return TRUE;
else return FALSE;
}
//**************************************************
// setobj(int q) 对象显示
// 调入由man[q].lb指出的,不同的man[q].p图片,和偏移值。
// 将对象q在各自的当前位置x,y上以透明方式TransparentBlt2显示。
// 之后进行移动或方位转换的功能。
// 为防止闪烁,所有对象先显示在暂存区BkDC1,一屏完成后再翻转到主屏上。
//**************************************************
void game::Alphasetobj(int q,int a)//对象显示
{ if(a==1&&man[q].lb==2) return;
CString cc;
int x=man[q].xix-scrx-man[q].w/2; //x当前位置
int y=man[q].xiy-scry-man[q].h; //y当前位置
if(inscreer(q))//在显示区?
{if(man[q].lb==0) {cc="人";}
if(man[q].lb==1) {cc="兽";}
if(man[q].lb==2) {cc="景";}
if(getpic(cc,man[q].p,0)==FALSE) return;
if(man[q].lb!=2)//调角色的偏移位置
{int x0=0,y0=0;
if(man[q].lb==0) {x0=rbufx[man[q].p];y0=rbufy[man[q].p];}
if(man[q].lb==1) {x0=sbufx[man[q].p];y0=sbufy[man[q].p];}
if(man[q].fw>4) x0=w-x0;//是东北、东、东南方位
x=man[q].xix-scrx-x0;
y=man[q].xiy-scry-y0;
}
rect.left=0,rect.top=0,rect.right=w,rect.bottom=h;
if(a==0)//DX
{if(DXSBack1->BltFast(x+SCRW,y+SCRH,DXSgonh,&rect,
DDBLTFAST_WAIT|DDBLTFAST_SRCCOLORKEY)!=DD_OK) return;//在缓存区1上透明显示
return;
}
else Alpha(x,y);
mans++;
}
///////////////////////////////////////////////////////////////////////
if(man[q].lb==2) return;
else manmove(q); //活动对象的移动
man[q].p++; //下一动作
if(man[q].p>=man[q].m1) {bianfw(q);}//本动作完成,进行方位转换
}
void game::Alpha(int x,int y)//DX
{ HDC hdc;
if ( DXSBack1->GetDC(&hdc) != DD_OK) return;
BitBlt(hDC0,0,0,w,h,hdc,x+SCRW,y+SCRH,SRCCOPY);
BitBlt(hDC1,0,0,w,h,hdc,x+SCRW,y+SCRH,SRCCOPY);
DXSBack1->ReleaseDC(hdc);
if ( DXSgonh->GetDC(&hdc) != DD_OK) return;
TransparentBlt2(hDC1,0,0,w,h,hdc,0,0,w,h,RGB(255,255,255));//透明显示
AlphaBlend(hDC1,0,0,w,h,hDC0,0,0,w,h,rBlend);//半透明处理
BitBlt(hdc,0,0,w,h,hDC1,0,0,SRCCOPY);
DXSgonh->ReleaseDC(hdc);
if(DXSBack1->BltFast
(x+SCRW,y+SCRH,DXSgonh,&rect,DDBLTFAST_WAIT|DDBLTFAST_SRCCOLORKEY)!=DD_OK) return;//在缓存区1上透明显示
}
//**********************************************************
// sort() 排序(冒泡法)
// 将rs个对象序列对Y位置进行排序;用于在显示时分出前后位置。
//**********************************************************
void game::sort()//排序(冒泡法)
{ MAN man0;
for(int a=0;a<rs-1;a++)
for(int b=a+1;b<rs;b++)
if(man[a].xiy>man[b].xiy)//前数大于后数
{man0=man[a]; //两数交换
man[a]=man[b];
man[b]=man0;
} //排序结果,当前位置Y小的在前。
mans=0; //显示区对象数置0
}
//**************************************************
// getobjwh(int q) 取对象的尺寸
// 取序号q对象的尺寸(宽man[q].w高man[q].h)。
//**************************************************
void game::getobjwh(int q)//取对象的尺寸
{ CString cc;
if(man[q].lb==0) {cc="人";}
if(man[q].lb==1) {cc="兽";}
if(man[q].lb==2) {cc="景";}
if(getpic(cc,man[q].p,0)==FALSE) return;
man[q].w=w; man[q].h=h; //对象的尺寸
}
//**************************************************
// loadbmp(CString cc)//调BMP图片
// 调cc指定的图形;取得的图形在设备相关位图bit中
// 图形的宽、高存于全局变量w,h中
//**************************************************
BOOL game::loadbmp(CString cc)//调BMP图片[2章]
{ DeleteObject(bitmap); //删除上次的位图内存。
bitmap=(HBITMAP)LoadImage //调入cc指定的图形
(AfxGetInstanceHandle(),//
cc,IMAGE_BITMAP, //文件名,位图方式
0,0, //图形宽,高
LR_LOADFROMFILE|LR_CREATEDIBSECTION//方式
);
if(bitmap==NULL) return FALSE; //调图失败
DIBSECTION ds; //
BITMAPINFOHEADER &bm = ds.dsBmih; //
GetObject(bitmap,sizeof(ds),&ds); //取位图的信息->bminfo
w = bm.biWidth; //得到位图宽度值
h = bm.biHeight; //得到位图高度值
return TRUE;
}
//**************************************************
// BOOL getpic(CString cc,int p,int a) 调普通图片
// A、调cc指定的压缩图形包中第p个图形和图形的尺寸w、h
// B、a=0时取得的图形在对象缓存页面DXSgonh中。
// C、a=1时取得的图形在MemDC中。
//**************************************************
BOOL game::getpic(CString cc,int p,int a)//调图片
{ int len;
if(p<0) return FALSE;
BYTE *tmp;
if(cc=="人")
{if(p>RBUF-1) return FALSE;
len=rbufadd[p+1]-rbufadd[p]; //取数据块长度
tmp=(BYTE *)new BYTE[len];
Memcpy0(tmp,rtmp+rbufadd[p],len);
}
if(cc=="兽")
{if(p>SBUF-1) return FALSE;
len=sbufadd[p+1]-sbufadd[p]; //取数据块长度
tmp=(BYTE *)new BYTE[len];
Memcpy0(tmp,stmp+sbufadd[p],len);
}
if(cc=="景")
{if(p>JBUF-6) return FALSE;
len=jbufadd[p+1]-jbufadd[p]; //取数据块长度
tmp=(BYTE *)new BYTE[len];
Memcpy0(tmp,jtmp+jbufadd[p],len);
}
LPBITMAPINFOHEADER bm=(BITMAPINFOHEADER *)tmp;//图形数据转换
bm->biSize = sizeof(BITMAPINFOHEADER);
w=bm->biWidth; //图形高
h=bm->biHeight; //图形宽
if(a==0)
//DX----------------------------------------------------------------------
{HDC hdc;//将图形装入动画缓存区DXSgonh
if ( DXSgonh->GetDC(&hdc) != DD_OK) return FALSE;//
StretchDIBits(hdc,0,0,w,h,0,0,w,h,tmp+256*sizeof(RGBQUAD)+bm->biSize,
(BITMAPINFO* )bm,DIB_RGB_COLORS,SRCCOPY);
DXSgonh->ReleaseDC(hdc);
//-----------------------------------------------------------------------
}
else
{StretchDIBits(MemDC,0,0,w,h,0,0,w,h,tmp+256*sizeof(RGBQUAD)+bm->biSize,
(BITMAPINFO* )bm,DIB_RGB_COLORS,SRCCOPY);
}
delete[] tmp;
return TRUE;
}
//**********************************************************************
// TransparentBlt2 (......)透明显示
// 根据关键色,将hdc1中的图形在hdc0中
// 自动生成掩模,并生成透明图形。
// 注:TransparentBlt(......)是一个WIN API函数,功能和这里的相同。
// 在WIN2000和以后的系统上可用。在WIN98中有严重的资源泄漏,根本不能用。
// 使用TransparentBlt(......)前,需引用:
// #include <wingdi.h>
// #pragma comment (lib,"msimg32.lib")
//**********************************************************************
void game::TransparentBlt2(HDC hdc0, //目标DC
int nX0,int nY0,int nW0,int nH0,//目标左坐标,目标宽高宽
HDC hdc1, //源DC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -