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

📄 role.cpp

📁 圣剑英雄传源码适合初学C语言者如细心阅读完定有收获!
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//********************************************
//	角色 相关函数
//  创建于2000年4月14日
//********************************************
#include <windows.h>
#include <stdio.h>
#include "gamelib\goldpoint.h"
#include "interface\interface.h"
#include "menu\menu_inc.h"
#include "main.h"
#include "map.h"
#include "findpath.h"
#include "talk.h"
#include "message.h"
#include "script.h"
#include "role.h"

//构造
CRole::CRole()
{
	Path=NULL;
	State.Surface=State.lpShadow=NULL;
	bCuted = FALSE;
	bCancelTalk = FALSE;
}

//析构
CRole::~CRole()
{
	_RELEASE( State.Surface );			//行走的页面
	_RELEASE( State.lpShadow );
	_DELETE_ARRAY( Path );
}

//释放
void CRole::Release()
{
	_RELEASE( State.Surface );
	_RELEASE( State.lpShadow );
	_DELETE_ARRAY( Path );
}

//***************
//初始化角色
bool CRole::InitRole()
{
	strcpy(Name,"无名");
	Width=32;
	Height=48;
	Max_Step=4;
	Max_Dir=4;
	//行走序列
	StepList[0]=0;
	StepList[1]=1;
	StepList[2]=0;
	StepList[3]=2;

	DirList[0]=0;
	DirList[1]=1;
	DirList[2]=2;
	DirList[3]=3;
	//位置
	State.x=State.oldx=CenterX;
	State.y=State.oldy=CenterY;

	State.X=State.oldX=_grid_x(State.x);
	State.Y=State.oldY=_grid_y(State.y);

	map.Block[map.Width*State.Y+State.X] = 1;
	StepSize=8;
	StepSize2=3;
	MoveX=0;
	MoveY=0;
	//脚底碰撞矩形
	FootRect[0].x=-8;		
	FootRect[0].y=-8;
	FootRect[1].x=8;		
	FootRect[1].y=-8;	
	FootRect[2].x=-8;		
	FootRect[2].y=8;
	FootRect[3].x=8;		
	FootRect[3].y=8;

	//页面
	char* strTemp = GameIni.ReadText("角色","Pic");
	strcpy(State.SurfaceFileName, strTemp);
	_FREE(strTemp);
	CreateBitmap(State.Surface, 0, 0, State.SurfaceFileName);
	DDSetColorKey(State.Surface, ColorKey);
	
	//生成角色影子页面
	CreateShadow();

	bMoving=false;
	State.CurrentStep=0;
	State.CurrentDir=2;
	State.LastDir=2;

	//对应脚本
	strcpy(ScriptFile, "script\\null.gps");
	Path=NULL;
	StepStep=0;
	return true;
}

//读取角色设定
bool CRole::LoadRoleIni(char *filename, char *index)
{
	CIniSet Ini(filename);

	//------通用数据----------
	Id=Ini.ReadInt(index,"Id");					//角色编号
	char* strTemp = Ini.ReadText(index, "Name");
	strcpy(Name, strTemp);	//名字
	_FREE(strTemp);
	Width=Ini.ReadInt(index,"Width");
	Height=Ini.ReadInt(index,"Height");			//单张尺寸
	Max_Step=Ini.ReadInt(index,"Max_Step");		//每个方向行走的步数
	Max_Dir=Ini.ReadInt(index,"Max_Dir");		//方向数

	//行走图片变换列表
	char _Steps[32];
	strTemp = Ini.ReadText(index, "StepList");
	strcpy(_Steps, strTemp);
	_FREE(strTemp);
	for(int i=0; i<Max_Step; i++)
	{
		StepList[i]=Ini.ReadInt(_Steps, i);
	}

	//行走方向列表
	strTemp = Ini.ReadText(index, "DirList");
	strcpy(_Steps, strTemp);
	_FREE(strTemp);
	for(i=0; i<4; i++)
	{
		DirList[i]=Ini.ReadInt(_Steps, i);
	}

	//脚底碰撞矩阵
	FootRect[0].x=-8;
	FootRect[0].y=-8;
	FootRect[1].x=8;
	FootRect[1].y=-8;
	FootRect[2].x=-8;
	FootRect[2].y=8;
	FootRect[3].x=8;
	FootRect[3].y=8;

	StepSize=Ini.ReadInt(index,"StepSize");		//每步走的距离
	StepSize2=Ini.ReadInt(index,"StepSize2");	//斜向走的距离

	//对应脚本
	strTemp = Ini.ReadText(index, "Script");
	strcpy( ScriptFile, strTemp);
	_FREE(strTemp);

	//人物的参数结构
	Propertiy.Level=Ini.ReadInt(index,"Level");
	Propertiy.Exp=Ini.ReadInt(index,"Exp");
	Propertiy.MaxExp=Ini.ReadInt(index,"MaxExp");
	Propertiy.Hp=Ini.ReadInt(index,"Hp");
	Propertiy.MaxHp=Ini.ReadInt(index,"MaxHp");
	Propertiy.Mp=Ini.ReadInt(index,"Mp");
	Propertiy.MaxMp=Ini.ReadInt(index,"MaxMp");

	oldAttack = Propertiy.Attack=Ini.ReadInt(index,"Attack");
	oldDefend = Propertiy.Defend=Ini.ReadInt(index,"Defend");
	Propertiy.Magic=Ini.ReadInt(index,"MagicAct");
	
	Propertiy.Stamina=Ini.ReadInt(index,"Stamina");
	Propertiy.Luck=Ini.ReadInt(index,"Luck");
	Propertiy.Speed=Ini.ReadInt(index,"Speed");
	Propertiy.Bp=Ini.ReadInt(index,"Bp");
	Propertiy.Ip=Ini.ReadInt(index,"Ip");

	//金钱
	Propertiy.Money=Ini.ReadInt(index,"Money");
	
	//随身物品
	char _Goods[32];
	strTemp = Ini.ReadText(index,"Goods");
	strcpy(_Goods, strTemp );
	_FREE(strTemp);
	Propertiy.CurGoodsNum=Ini.ReadInt(_Goods, "Max_Good");
	for(i=0; i<Propertiy.CurGoodsNum; i++)
	{
		char* str = Ini.ReadData(_Goods, i);
		Propertiy.Goods[i]=atoi(str);
		_DELETE(str);
		Propertiy.GoodsNum[i]=Ini.ReadInt(_Goods, i);
	}

	//装备
	char _Arm[32];
	strTemp = Ini.ReadText(index,"Arm");
	strcpy(_Arm, strTemp );
	_FREE(strTemp);
	Propertiy.CurArmNum=Ini.ReadInt(_Arm, "Max_Arm");
	for(i=0; i<Propertiy.CurArmNum; i++)
	{
		Propertiy.Arm[i]=atoi(Ini.ReadData(_Arm, i));
		Propertiy.ArmNum[i]=Ini.ReadInt(_Arm, i);
	}

	//魔法
	strTemp = Ini.ReadText(index,"Magics");
	strcpy(_Goods, strTemp );
	_FREE(strTemp);
	Propertiy.MagicsNum=Ini.ReadInt(_Goods, "Max_Magics");
	for(i=0; i<Propertiy.MagicsNum; i++)
	{
		Propertiy.Magics[i]=Ini.ReadInt(_Goods, i);
	}

	Propertiy.Arms=Ini.ReadInt(index, "Arms");
	SetupArm(Propertiy.Arms);
	Propertiy.Corselet=Ini.ReadInt(index, "Corselet");
	SetupArm(Propertiy.Corselet);

	//战斗
	strcpy(Propertiy.Fight_Ini_Name, Name);

	//------状态数据----------
	State.x=Ini.ReadInt(index,"x");			//当前坐标 脚底中心点
	State.y=Ini.ReadInt(index,"y");
	State.oldx=Ini.ReadInt(index,"oldx");
	State.oldy=Ini.ReadInt(index,"oldy");				//上一步的坐标
	State.CurrentStep=Ini.ReadInt(index,"CurrentStep");	//当前步数
	State.CurrentDir=Ini.ReadInt(index,"CurrentDir");	//当前方向
	State.LastDir=Ini.ReadInt(index,"LastDir");			//上一步的方向
	State.bActive=Ini.ReadInt(index,"bActive");			//是否活动
	State.bShow=Ini.ReadInt(index,"bShow");				//是否可见
	
	//取主角的格子坐标
	State.X=State.oldX=_grid_x(State.x);
	State.Y=State.oldY=_grid_y(State.y);

	map.Block[map.Width*State.Y+State.X] = 1;
	//行走的页面
	strTemp = Ini.ReadText(index,"SurfaceFileName");
	strcpy(State.SurfaceFileName, strTemp );	//对应文件
	_FREE(strTemp);
	CreateBitmap(State.Surface, 0, 0, State.SurfaceFileName);
	DDSetColorKey(State.Surface, ColorKey);
	
	//生成角色影子页面
	CreateShadow();

	//静止
	bMoving=false;
	Path=NULL;
	StepStep=0;

	return true;
}

//***************
//生成人物阴影
bool CRole::CreateShadow()
{
	int m,n;

	int W,H;
	LoadBitmapFileInfo(hWnd, State.SurfaceFileName, W, H);
	int nRows = W / Width;
	int nLines = H / Height;
	int W2=W;			
	int H2=H/4;			
	State.SW=W2/nRows;	//宽度不变
	State.SH=Height/4;	//高度为1/4

	//创建角色影子页面
	CreateBitmap(State.lpShadow, W2, H2, NULL, DDSCAPS_SYSTEMMEMORY);
	DDSetColorKey(State.lpShadow, ColorKey);
	FillSurface(State.lpShadow, ColorKey16);

	LPDIRECTDRAWSURFACE lpTemp;
	CreateBitmap(lpTemp, State.SW, State.SH, NULL, DDSCAPS_SYSTEMMEMORY);

	// 分块压扁
	for(m=0; m<nLines; m++)
		for(n=0; n<nRows; n++)
		{
			RECT rt={n*State.SW, m*State.SH, n*State.SW+State.SW, (m+1)*State.SH};
			RECT rs={n*Width, m*Height, (n+1)*Width, (m+1)*Height};
			SBlt(State.lpShadow, rt, State.Surface, rs, false);
		}

	// 锁定表面
	WORD* pShadow;
	WORD* pTemp;
	if( BeginDraw(State.lpShadow) )
	{
		pShadow = (WORD*)GraphBuffer;
		EndDraw(State.lpShadow);
	}
	if( BeginDraw(lpTemp) )
	{
		pTemp = (WORD*)GraphBuffer;
		EndDraw(lpTemp);
	}

	int i,j;
	for(m=0; m<nLines; m++)
		for(n=0; n<nRows; n++)
		{
			//清色处理
			for(i=0; i<State.SH; i++)
				for(j=0; j<State.SW; j++)
				{
					int p=(i+m*State.SH)*W2+(j+n*State.SW);
					if( pShadow[p] != ColorKey16 )
					{
						pShadow[p] = RGB16(0, 0, 0);		//全部做成黑色
					}
					else
					{
						pShadow[p] = 31;		//0x001f,蓝色五位都为1,将来显示的透明色
					}
				}
				
				//上下反转
				Blt(lpTemp, 0, 0, State.lpShadow, 
					GetRect(n*State.SW, m*State.SH, n*State.SW+State.SW, m*State.SH+State.SH)
					, false);

				for(i=0; i<State.SW; i++)
					for(j=0; j<State.SH; j++)
					{
						int p1=(j+m*State.SH)*W2+(i+n*State.SW);
						int p2=(State.SH-1-j)*State.SW+i;
						pShadow[p1] = pTemp[p2];
					}
		}

	_RELEASE(lpTemp);

	return true;
}

//***************
//读入进度时候
bool CRole::LoadRole(char *FileName)
{
	FILE *fp;

	fp=fopen(FileName, "rb");
	if( fp==NULL )
	{
		ShowMessage("Can't open file <%s>!",FileName);
		return false;
	}

	fread(&Id, 4, 1, fp);
	fread(Name,32,1,fp);
	fread(&Width,4,1,fp);
	fread(&Height,4,1,fp);
	fread(&Max_Step, sizeof(byte), 1, fp);
	fread(&Max_Dir, sizeof(byte), 1, fp);
	fread(StepList, Max_Step, sizeof(byte), fp);
	fread(DirList, 4, 1, fp);
	fread(FootRect, sizeof(POINT), 4, fp);
	fread(&StepSize, sizeof(int), 1, fp);
	fread(&StepSize2, sizeof(int), 1, fp);

	fread(ScriptFile, 64, 1, fp);
	fread(&Propertiy, sizeof(stRolePropertiy), 1, fp);
	fread(&State, sizeof(stRoleState), 1, fp);

	CreateBitmap(State.Surface, 0, 0, State.SurfaceFileName);
	DDSetColorKey(State.Surface, ColorKey);
	CreateShadow();		//生成角色影子页面


	//------移动数据-----------
	fread(&PathSteps, 4, 1, fp);
	fread(&PathCurrentStep, 4, 1, fp);
	fread(&DesX, sizeof(int), 1, fp);
	fread(&DesY, sizeof(int), 1, fp);
	fread(&bMoving, 1, 1, fp);
	fread(&StepStep, sizeof(int), 1, fp);
	fread(&MoveX, sizeof(int), 1, fp);
	fread(&MoveY, sizeof(int), 1, fp);
	fread(&bShowed, 1, 1, fp);
	fread(&oldAttack,sizeof(int),1,fp);
	fread(&oldDefend,sizeof(int),1,fp);

	if( PathSteps > 0 && bMoving )
	{
		_DELETE_ARRAY( Path );
		Path=new POINT[PathSteps];
		fread(Path, sizeof(POINT) , PathSteps, fp);
	}
	else 
		Path=NULL;

	fclose(fp);

	return true;
}

//***************
//保存进度的时候
bool CRole::SaveRole(char *FileName)
{
	FILE *fp;

	fp=fopen(FileName, "wb");
	if( fp==NULL )
	{
		MessageBox(hWnd,"save map file error!","",MB_OK);
		return false;
	}

	fwrite(&Id, 4, 1, fp);
	fwrite(Name,32,1,fp);
	fwrite(&Width,4,1,fp);
	fwrite(&Height,4,1,fp);
	fwrite(&Max_Step, sizeof(byte), 1, fp);
	fwrite(&Max_Dir, sizeof(byte), 1, fp);
	fwrite(StepList, Max_Step, sizeof(byte), fp);
	fwrite(DirList, 4, 1, fp);
	fwrite(FootRect, sizeof(POINT), 4, fp);
	fwrite(&StepSize, sizeof(int), 1, fp);
	fwrite(&StepSize2, sizeof(int), 1, fp);

	fwrite(ScriptFile, 64, 1, fp);
	fwrite(&Propertiy, sizeof(stRolePropertiy), 1, fp);
	fwrite(&State, sizeof(stRoleState), 1, fp);
	
	//------移动数据-----------
	fwrite(&PathSteps, 4, 1, fp);
	fwrite(&PathCurrentStep, 4, 1, fp);
	fwrite(&DesX, sizeof(int), 1, fp);
	fwrite(&DesY, sizeof(int), 1, fp);
	fwrite(&bMoving, 1, 1, fp);
	fwrite(&StepStep, sizeof(int), 1, fp);
	fwrite(&MoveX, sizeof(int), 1, fp);
	fwrite(&MoveY, sizeof(int), 1, fp);
	fwrite(&bShowed, 1, 1, fp);
	fwrite(&oldAttack,sizeof(int),1,fp);
	fwrite(&oldDefend,sizeof(int),1,fp);

	if( PathSteps > 0 && bMoving ) 
		fwrite(Path, sizeof(POINT) , PathSteps, fp);

	fclose(fp);
	return true;
}

//*******************
//显示角色
void CRole::ShowRole()
{
	//坐标计算

	//人物在图片上的位置
	int x1=Width*StepList[State.CurrentStep];
	int y1=Height*State.CurrentDir;

	//显示人在地图上的位置

	//脚底中心x坐标向左半个人宽
	int sx=State.x-(Width>>1)- _point_x(map.SX) +map.DX;	
	//脚底中心y坐标向上一个人高,再加上脚的高度
	int sy=State.y-Height+(int)FootRect[3].y - _point_y(map.SY) +map.DY;

	//显示影子
	int x2=State.SW*StepList[State.CurrentStep];
	int y2=State.SH*State.CurrentDir;

	RECT r={x2, y2, x2+State.SW, y2+State.SH};
	//用0x001f为透明色,看看产生影子的函数
	//缩减一点点,因为影子有部分是在脚下的
	ABlt(lpDDSBack, sx, sy+Height-6, State.lpShadow, r, 31, 20);

	//显示人
	RECT bs={ x1, y1, x1+Width, y1+Height};

	Blt(lpDDSBack, sx, sy, State.Surface, bs, true);

}

//*******************
//半透明显示角色
void CRole::ShowRole(int alpha)
{
	//坐标计算
	int x1=Width*StepList[State.CurrentStep];
	int y1=Height*State.CurrentDir;
	//一样的方法
	int sx=State.x-(Width>>1)- _point_x(map.SX) +map.DX;
	int sy=State.y-Height+(int)FootRect[3].y - _point_y(map.SY) +map.DY;

	//显示人
	RECT bs={ x1, y1, x1+Width, y1+Height};

	ABlt(lpDDSBack, sx, sy, State.Surface, bs, ColorKey16, alpha);
}

//*******************
//显示角色
void CRole::ShowRole(int lx, int ly, int lDir, int lStep)
{
	//坐标计算
	int x1=Width*StepList[lStep];
	int y1=Height*lDir;
	//…………
	int sx=lx-(Width>>1)- _point_x(map.SX) +map.DX;
	int sy=ly-Height+(int)FootRect[3].y - _point_y(map.SY) +map.DY;

	//显示影子
	int x2=State.SW*StepList[State.CurrentStep];
	int y2=State.SH*State.CurrentDir;
	RECT r={x2, y2, x2+State.SW, y2+State.SH};

	ABlt(lpDDSBack, sx-16, sy+Height-4, State.lpShadow, r, 31, 20);

	//显示人
	RECT bs={ x1, y1, x1+Width, y1+Height};
	Blt(lpDDSBack, sx, sy, State.Surface, bs, true);
}

//*************************
//显示 tx,ty=当前地图坐标
void CRole::Show(int tx, int ty)
{
	ShowRole();
}

//*******************************
//移动,参数是当前位置,相对与地图格子坐标的
void CRole::Move(int nx, int ny)
{
	//正在行走中……
	if( bMoving )
	{
		//下一个点的坐标,在地图格子的中心
		int subx= _point_x(Path[PathCurrentStep].x) +(CellWidth>>1);
		int suby= _point_y(Path[PathCurrentStep].y) +(CellHeight>>1);

		//到达下一点
		if( abs(State.x-subx) <= 2 && abs(State.y-suby) <= 2 )
		{
			if(PathCurrentStep<PathSteps-1&&map.Block[Path[PathCurrentStep+1].x +Path[PathCurrentStep+1].y*map.Width]==1)
			{
				int xTemp = Path[PathCurrentStep+1].x;		//下一个点
				int yTemp = Path[PathCurrentStep+1].y;
				map.Cell[xTemp +yTemp*map.Width].Block=1;	//不能通过(用于寻路)
				MoveTo(_point_x(DesX),_point_y(DesY));
				map.Cell[xTemp +yTemp*map.Width].Block=0;	//恢复

				map.Block[ map.Width*State.oldY + State.oldX ] = 0;//上一个点可以通过
				map.Block[ map.Width*ny + nx ] = 1;		//该点不能通过
				return;
			}
			if(PathCurrentStep<PathSteps-1)
				map.Block[Path[PathCurrentStep+1].x +Path[PathCurrentStep+1].y*map.Width] = 1;

			map.Block[ map.Width*State.oldY + State.oldX ] = 0;//上一个点可以通过
			map.Block[ map.Width*ny + nx ] = 1;		//该点不能通过
			if( PathCurrentStep+1==PathSteps )	//目标点
			{
				State.x=subx;	//更新当前脚底坐标
				State.y=suby;
				
				static bool left=true;
				if( left )	//先出左脚
				{
					left=!left;
					State.CurrentStep=0;	//设置人物的停止状态,保证两个脚并在一起
				}
				else		//先出右脚
				{
					left=!left;
					State.CurrentStep=2;
				}

				bMoving=false;				//停止移动
				MoveX=0;					//坐标变化为0
				MoveY=0;

				

				//如果目标点不能行走的话,那么主角转向目标点
				if(	/*map.Cell[map.Width*DesY+DesX].Block == 1
					&&*/ ((DesX!=State.X)
					|| (DesY!=State.Y))&&!bCuted)
				{
					if( DesX > State.X ) 
						State.CurrentDir = 3;		//向右转
					else 
						if( DesX < State.X ) 
							State.CurrentDir = 1;	//向左转
					if( DesY > State.Y ) 
						State.CurrentDir = 0;		//向下转
					else 
						if( DesY < State.Y ) 
							State.CurrentDir = 2;	//向上转
					RunScript();
				}

				State.oldX=State.X;
				State.oldY=State.Y;
				
				//判断当前点是否为场景切换点
				ChangeScene();
				return;
			}
			else	//到下一点
			{
				//保存上个位置
				State.oldX=State.X;

⌨️ 快捷键说明

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