📄 role.cpp
字号:
//********************************************
// 角色 相关函数
// 创建于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 + -