📄 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雀,无跑
};
unsigned short smz[2][7]={60,50,30,20,40,10,15,//生命值
10 ,8 ,6 ,3 ,5 ,1 ,2 };//攻击力
//兽[0豹1狼2猪3鹿4马5雀6羊]
////////////////////////////////////////////////////////////////////////////
game:: game(){} //构造函数
game::~game(){} //析构函数
//****************************************************************
// A、 init() 初始化,建立图形处理环境
// BkDC0-装载背景地面
// BkDC1-在此生成即时场景,在1个时钟周期后翻转到当前显示屏。
// MemDC-调入的对象图片。
//****************************************************************
BOOL game::init()//初始化
{ 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);
Font.CreateFont(-4,0,0,0,400,0,0,0,134,0,0,0,0,LPCTSTR("impact"));
mansmz[0]=200;mansmz[1]=5;mansmz[2]=10;mansmz[3]=20;mansmz[4]=0;
da=0;
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;
if(man[q].zs>5) //生命值
{Delete(q);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(getpic(q,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); //活动对象的移动
//生命值==================================================================
if(man[q].zd==1) setxtx(q,x,y); //正在打时,调显示生命值函数
if(man[q].zs>4)//生命值
{man[q].smz=man[q].smz-1; //动物死后,smz用于尸体消失计数
if(man[q].smz<-200) {man[q].smz=0;man[q].p++;}
}
else
//========================================================================
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上透明显示
}
///////////////////////////////////////////
//setxtx(int q,int x,int y)显示生命值函数
// 在[x,y]位置显示当前对象q的生命值和攻击力
// 生命值用颜色表示;按赤、橙、黄、绿、蓝、青、紫、从低到高表示。
// 攻击力用星表示;星越多攻击力越高。
///////////////////////////////////////////
void game::setxtx(int q,int x,int y)//显示生命值函数
{ if(man[q].lb==0) return;
CString cc;
COLORREF col;
if(smz[1][man[q].js]>8) {cc="●●●●●";goto aa;}//攻击力
if(smz[1][man[q].js]>6) {cc="●●●● ";goto aa;}
if(smz[1][man[q].js]>4) {cc="●●● ";goto aa;}
if(smz[1][man[q].js]>2) {cc="●● ";goto aa;}
cc="● ";
aa: if(man[q].smz>=60) {col=RGB(0x0,0x00,0xff);goto bb;}//生命值
if(man[q].smz>=50) {col=RGB(0x0,0x88,0xff);goto bb;}
if(man[q].smz>=40) {col=RGB(0x0,0xff,0xff);goto bb;}
if(man[q].smz>=30) {col=RGB(0x0,0xff,0x88);goto bb;}
if(man[q].smz>=20) {col=RGB(0xff,0xff,0x0);goto bb;}
if(man[q].smz>=10) {col=RGB(0xff,0x88,0x0);goto bb;}
col=RGB(0xff,0x0,0x0);
bb: HDC hdc; //设备环境句柄
if (DXSBack1->GetDC(&hdc) != DD_OK) return;//打开DXSBack1面
CDC* dc = CDC::FromHandle (hdc);
CFont *pOldFont;
pOldFont=dc->SelectObject(&Font); //设置字体为4号impact体
dc->SetBkColor(col); //字底色
dc->SetTextColor(RGB(0x0,0x0,0x0));//字色
dc->TextOut(x+SCRW+w/2,y+SCRH-10,cc,lstrlen(cc));//写攻击力字串
dc->SelectObject(pOldFont); //恢复原来的字体
CDC::DeleteTempMap( );
DXSBack1->ReleaseDC(hdc);//关闭DXSBack1面
}
//**********************************************************
// 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
}
//**************************************************
// 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)//调图片
BOOL game::getpic(int q,int a)//调图片
{ int len;
int p=man[q].p;
if(p<0) return FALSE;
BYTE *tmp;
if(man[q].lb==0)//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(man[q].lb==1)//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(man[q].lb==2)//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);
}
if(man[q].lb==3)//if(cc=="物")
{if(p>WBUF-1) return FALSE;
len=wbufadd[p+1]-wbufadd[p]; //取数据块长度
tmp=(BYTE *)new BYTE[len];
Memcpy0(tmp,wtmp+wbufadd[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,//目标左坐标,目标宽高宽
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -