⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 game.cpp

📁 学游戏不错的实例教程
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*********************************
[学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(){}	//析构函数
//****************************************************************
// init() 初始化,建立图形处理环境
//	BkDC0-装载背景地面
//	BkDC1-在此生成即时场景,在1个时钟周期后翻转到当前显示屏。
//	MemDC-调入的对象图片。
//****************************************************************
BOOL game::init()//初始化
{	hScrDC=CreateDC("DISPLAY", NULL, NULL, NULL);	//创建屏幕设备句柄
	BkDC0 =CreateCompatibleDC(hScrDC);				//创建地图设备句柄
	BkDC1 =CreateCompatibleDC(hScrDC);				//创建暂存设备句柄
	bit0  =CreateCompatibleBitmap(hScrDC,WIDTH,HEIGHT);//创建暂存位图内存0
	bit1  =CreateCompatibleBitmap(hScrDC,WIDTH,HEIGHT);//创建暂存位图内存1
	SelectObject(BkDC1,bit1);						//暂存位图内存1与暂存设备句柄关联
	OldMak=(HBITMAP)SelectObject(BkDC0,bit0);		//暂存位图内存0与地图设备句柄关联
	MemDC =CreateCompatibleDC(hScrDC);				//创建对象设备句柄
//==================================================
	BK =CreateCompatibleDC(hScrDC);//创建暂存设备句柄
	bi =CreateCompatibleBitmap(hScrDC,WIDTH,HEIGHT);
	SelectObject(BK,bi);

	bitya=CreateCompatibleBitmap(hScrDC,220,200);
	DeleteDC(hScrDC);								//删除屏幕设备句柄
	rBlend.BlendOp = AC_SRC_OVER;	//
	rBlend.BlendFlags = 0;			//
	rBlend.AlphaFormat = 0;			//
	rBlend.SourceConstantAlpha=140;
//==================================================
	GetCurrentDirectory(256,appdir);//取当前目录
	dir=appdir;
	if(dir.Right(8)=="运行程序")
			dir="图片/";
	else	
		dir="../运行程序/图片/";	//图片路径
//==================================================
	sys=getsys();	//取当前系统
	scrx=0;scry=0;
	rs=0;			//对象数置0
	find_p=0;		//无搜索0有搜索1
	stmp=NULL;rtmp=NULL;jtmp=NULL;
	return TRUE;
}
//**************************************************
//  exit() 退出, 删除图形处理环境
//**************************************************
void game::exit()//退出
{	DeleteDC(BK);
	DeleteObject(bi);
	DeleteObject(bitya);
	DeleteObject(bit0);	//删除暂存位图内存
	DeleteObject(bit1);	//删除暂存位图内存
	DeleteDC(BkDC0);	//删除地图设备句柄
	DeleteDC(BkDC1);	//删除暂存设备句柄
	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;
}

//**********************************************************
//  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)==FALSE) return;
	man[q].w=w; man[q].h=h;			//对象的尺寸
}
//**********************************************************************
//  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
				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&&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_a(i);		//没加寻路时不要这句。
	 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);								  //设置活动对象初值

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -