📄 game.cpp
字号:
int nX1,int nY1,int nW1,int nH1,//源起点坐标,源宽高宽
UINT Tcol) //透明色,COLORREF类型
{ if(sys>1)//是win98以上的系统,直接调API函数TransparentBlt()
{TransparentBlt(hdc0,nX0,nY0,nW0,nH0,hdc1,nX1,nY1,nW1,nH1,Tcol);
return;
}
HBITMAP hBMP =CreateCompatibleBitmap(hdc0,nW0, nH0); //创建位图内存
HBITMAP mBMP =CreateBitmap(nW0,nH0,1,1,NULL); //创建单色掩码位图
HDC hDC =CreateCompatibleDC(hdc0); //创建设备句柄
HDC mDC =CreateCompatibleDC(hdc0); //创建设备句柄
HBITMAP oldBMP =(HBITMAP)SelectObject(hDC, hBMP);
HBITMAP oldmBMP=(HBITMAP)SelectObject(mDC, mBMP);
// 将源DC中的位图拷贝到临时DC中
if (nW0==nW1&&nH0==nH1)
BitBlt(hDC,0,0,nW0,nH0,hdc1,nX1,nY1,SRCCOPY);
else
StretchBlt(hDC,0,0,nW0,nH0,hdc1,nX1,nY1,nW1,nH1,SRCCOPY);
SetBkColor(hDC, Tcol);// 设置透明色
BitBlt(mDC,0,0,nW0,nH0,hDC,0,0,SRCCOPY);//生成透明区域为白色,其它区域为黑色的掩码位图
SetBkColor(hDC, RGB(0,0,0)); //生成透明区域为黑色,其它区域保持不变的位图
SetTextColor(hDC, RGB(255,255,255)); //白色
BitBlt(hDC,0,0,nW0,nH0,mDC,0,0,SRCAND);
SetBkColor(hdc0,RGB(255,255,255)); //透明部分保持屏幕不变,其它部分变成黑色
SetTextColor(hdc0,RGB(0,0,0)); //黑色
BitBlt(hdc0,nX0,nY0,nW0,nH0,mDC,0,0,SRCAND); //"与"运算,在hdc0生成掩模
BitBlt(hdc0,nX0,nY0,nW0,nH0,hDC,0,0,SRCPAINT);//"或"运算,生成最终透明效果
SelectObject(hDC,oldBMP);
SelectObject(mDC,oldmBMP);
DeleteDC(hDC);
DeleteDC(mDC);
DeleteObject(hBMP);
DeleteObject(mBMP);
}
//**************************************************
// setman(int q) 设置活动对象初值
// 由给定的对象、方位、动作计算出图形的位置和数量。
//**************************************************
void game::setman(int q)//设置活动对象初值
{ int a=400;
if(man[q].lb==0)//人
{man[q].m0=man[q].js*a+zjdz[man[q].zs].qi
+man[q].fw*zjdz[man[q].zs].bc;//位置初值
man[q].m1=zjdz[man[q].zs].bc+man[q].m0;//位置终值
man[q].p=man[q].m0; //数量计数
}
if(man[q].lb==1)//兽
{man[q].m0=man[q].js*a+zjdw[man[q].zs].qi
+man[q].fw*zjdw[man[q].zs].bc;//位置初值
man[q].m1=zjdw[man[q].zs].bc+man[q].m0;//位置终值
man[q].p=man[q].m0; //数量计数
}
man[q].zd=0;
}
//**************************************************
// manmove(int i) 活动对象的移动
// 由当前、目标位置的差,计算当前位置向不同方位的改变。
//**************************************************
void game::manmove(int i)//活动对象的移动
{ if(man[i].lb==2) return; //是静物返回
if(find_p==1) //find_p;无搜索0有搜索1
{if(man[i].pk<1) return;} //无搜索路径返回,
int stx,sty,qx,qy;
switch(man[i].zs)
{case 2: {stx=9;sty=6;break;}//跑步长
case 1: {stx=4;sty=2;break;}//走步长
default:{stx=2;sty=1;break;}
}
qx=man[i].x0-man[i].xix; //x当前、目标位置差
qy=man[i].y0-man[i].xiy; //y当前、目标位置差
if (qx==0&&qy==0)
{if(find_p==1) //find_p;无搜索0有搜索1
{//加入自动搜索后,应执行的代码
if(man[i].fid<man[i].pk) //从搜索的路径中取目标点
{man[i].x0=man[i].ph[man[i].fid].x*GX+man[i].w/2;
man[i].y0=man[i].ph[man[i].fid].y*GY+man[i].h/2;
man[i].fid++;
if(man[i].x0<GX) man[i].x0=GX;
if(man[i].y0<GX) man[i].y0=GY;
bianfw(i); //方位转换
}
else //搜索路径取完
{man[i].x0=man[i].fx;
man[i].y0=man[i].fy;
}
//-----------------------------
}
return ; //到达返回
}
int qxa=abs(qx); //x位置差绝对值
int qya=abs(qy); //y位置差绝对值
if(qxa<stx) stx=qxa; //位置差不足步长,步长为差
if(qya<sty) sty=qya; //
if(qx!=0) man[i].xix+=qxa/qx*stx;//当前位置加步长
if(qy!=0) man[i].xiy+=qya/qy*sty;//[qya/qy]单位绝对值
}
//**************************************************
// bianfw(int q)//方位转换
// 由当前、目标位置的差,计算活动图形的方向取向。
//**************************************************
void game::bianfw(int q)//方位转换
{ int qx=man[q].x0-man[q].xix; //x当前,目标位置差
int qy=man[q].y0-man[q].xiy; //y当前,目标位置差
if(qx==0&&qy==0)
{if(man[q].zd==0) man[q].zs=0; //为0,动作为站,方位保留
goto aa;
}
if(man[q].zd==0) //没打
{int a=rand()%2+1; //随机产生走、跑
if(man[q].lb==0) man[q].zs=1; //设为走
if(man[q].lb==1) man[q].zs=dw[man[q].js][a];
}
if(qx<0&&qy>0) {man[q].fw=1;goto aa;}//取西南向
if(qx<0&&qy<0) {man[q].fw=3;goto aa;}//取西北向
if(qx>0&&qy<0) {man[q].fw=5;goto aa;}//取东北向
if(qx>0&&qy>0) {man[q].fw=7;goto aa;}//取东南向
if (qy>0) {man[q].fw=0;goto aa;}//取南向
if(qx<0) {man[q].fw=2;goto aa;}//取西向
if (qy<0) {man[q].fw=4;goto aa;}//取北向
if(qx>0) {man[q].fw=6;goto aa;}//取东向
aa: setman(q); //设置活动对象初值
if(man[q].zs==0)
man[q].p=man[q].p+rand()%3; //避免动作一致
}
//**************************************************
// loadmap(CString name)//调地图
// 调入编制好的对象场景(.dat)
// 场景文件(.dat)的格式:
// 第1行,为背景图形
// 第2行,对象数,后面一行是一个对象。
// 序号,类别,角色,静物图形号,x,y位置6个数据
//**************************************************
void game::loadmap(CString name)//调地图
{ FILE *f;
SetCurrentDirectory(appdir);//置当前目录
f=fopen(name,"r");
if(f==NULL) {AfxMessageBox("没有地图文件!!!");return;}
fscanf(f,"%s\n",mapbak); //地图块名
fscanf(f,"%d\n",&rs); //对象数
if(rs>SU_LIANG)
{fclose(f);return;} //对象数大于设定值返回
int i;
for (i=0;i<rs;i++)
{fscanf(f,"%d,",&man[i].jisu);//序号
fscanf(f,"%d,",&man[i].lb); //类别: [0人1兽2景]
fscanf(f,"%d,",&man[i].js); //角色:人[0男1女]
//角色:兽[0豹1狼2鹿3马4雀5羊6猪]
fscanf(f,"%d,",&man[i].p); //静物图形号
fscanf(f,"%d,",&man[i].xix); //当前位置x
fscanf(f,"%d,",&man[i].xiy); //当前位置y
man[i].x0=man[i].xix; //目标位置x
man[i].y0=man[i].xiy; //目标位置y
man[i].fw=1; //方位: [0南1西南2西3西北4北5东北6东7东南]
man[i].zs=0; //动作:人[0站1走2刺3劈4倒]
//动作:兽[0站1走2跑3斗4倒5尸]
man[i].pk =-1; //路径长
man[i].fid=-1; //路径计数
man[i].zd=0;
if(man[i].lb!=2)
setman(man[i].jisu); //设置活动对象初值
getobjwh(i); //取对象的尺寸
}
fclose(f);
SetCurrentDirectory(appdir); //置当前目录
}
//以下是DirectX程序段////////////////////////////////////
BOOL game::InitDDraw(void)//功能:初始化DirectDraw环境。
{ ddrval=DirectDrawCreate( NULL, &DXW, NULL );
if(ddrval!= DD_OK ) return FALSE;//创建DirectCraw对象失败返回
ddrval=DXW->SetCooperativeLevel(GetActiveWindow(),DDSCL_NORMAL);
if(ddrval!= DD_OK) return FALSE;// 取得窗口模式失败返回
ddrval=DXW->SetDisplayMode(800,600,16);
if(ddrval!= DD_OK) return FALSE;//设置显示模式失败返回
//========================================================================
ddsd.dwSize = sizeof( ddsd );// 创建主显页面
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps =DDSCAPS_PRIMARYSURFACE;
ddsd.dwBackBufferCount=1;
ddrval = DXW->CreateSurface( &ddsd, &DXSPrimary, NULL );
if( ddrval != DD_OK ) return FALSE;//创建主显页面失败返回
//=========================================================================
Surface(WIDTH,HEIGHT);//创建背景地图缓存页面0
ddrval=DXW->CreateSurface(&ddsd,&DXSBack0, NULL);
if (ddrval!=DD_OK) return FALSE;
//=========================================================================
Surface(WIDTH,HEIGHT);//创建地图移动缓存页面1
ddrval=DXW->CreateSurface(&ddsd,&DXSBack00, NULL);
if (ddrval!=DD_OK) return FALSE;
//=========================================================================
Surface(SCRWI0,SCRHE0);//创建主缓存页面1//840=100+640+100,780 =150+480+150
ddrval=DXW->CreateSurface(&ddsd,&DXSBack1, NULL);
if (ddrval!=DD_OK) return FALSE;
//=========================================================================
Surface(210,200);//创建对象缓存
ddrval=DXW->CreateSurface(&ddsd,&DXSgonh, NULL);
if (ddrval!=DD_OK) return FALSE;
col.dwColorSpaceLowValue=RGB(255,255,255);//255,255,255
col.dwColorSpaceHighValue=RGB(255,255,255);//透明关键色100,100,100
DXSgonh->SetColorKey(DDCKEY_SRCBLT,&col); //关键色
return TRUE;
}
void game::Surface(int w,int h)//定义缓存页面的大小
{ ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;
ddsd.dwWidth = w; //
ddsd.dwHeight=h; //
// ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY;
//定义显示内存为缓存区
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY;
//定义系统内存为缓存区
}
void game::Bk1ToPr(HDC scrhdc,CRect lpRect)//后页1到前页DX
{/////////////////////////////////////////////////////////////
/* HDC hdc;
if ( DXSBack1->GetDC(&hdc) != DD_OK) return;
BitBlt(scrhdc,2,10,WIDTH,HEIGHT,hdc,SCRW,SCRH,SRCCOPY);
DXSBack1->ReleaseDC(hdc);*/
//后台缓存1上的源矩形
rect.left=SCRW,rect.top=SCRH,rect.right=WIDTH+SCRW,rect.bottom=HEIGHT+SCRH;
if( DXSPrimary->BltFast
(lpRect.left+5,lpRect.top+13,DXSBack1,&rect,DDBLTFAST_WAIT)!=DD_OK)
return ;
/////////////////////////////////////////////////////////////
}
void game::FreeDDraw( void )//功能:释放所有的DirectDraw对象。
{ if( DXW != NULL )
{
if( DXSPrimary != NULL ) //主显页面
{ DXSPrimary->Release();DXSPrimary = NULL;}
if( DXSBack0 != NULL )
{ DXSBack0->Release();DXSBack0 = NULL;}
if( DXSBack00 != NULL ) //地图移动缓存页面0
{ DXSBack00->Release();DXSBack00=NULL;}
if( DXSBack1 != NULL ) //地图移动缓存页面1
{ DXSBack1->Release();DXSBack1 = NULL;}
if( DXSgonh != NULL ) //对象缓存
{ DXSgonh->Release(); DXSgonh = NULL; }
DXW->Release(); DXW = NULL;
}
}
void game::Memcpy0(unsigned char *mu,unsigned char *yu,int z)
{//memcpy(mu,yu,z);
int z0=z/32;
int z1=z-z0*32;
_asm
{//pand mm0,mm4 ;//packed and
mov esi,yu
mov edi,mu
mov ecx,z0
Mcont:
movq mm0,qword ptr [esi]
movq qword ptr [edi],mm0
movq mm0,qword ptr [esi][8]
movq qword ptr [edi][8],mm0
movq mm0,qword ptr [esi][16]
movq qword ptr [edi][16],mm0
movq mm0,qword ptr [esi][24]
movq qword ptr [edi][24],mm0
add esi,8*4
add edi,8*4
loop Mcont
mov ecx,z1;
repe movsb;
emms ;//empty MMX state
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -