📄 map.cpp
字号:
else
{
DX+=ScrollStep;
if(DX>=0)
DX=0;
}
}
//和X方向一样
if( oy > 0 ) //下
{
DY-=ScrollStep;
if( DY <= -32 )
{
DY+=32;
SY++;
}
}
else if( oy < 0 ) //上
{
DY+=ScrollStep;
if( DY >=0 )
{
DY-=32;
SY--;
}
}
else
{
if(m_bScrollDown)
DY=0;
else
{
DY+=ScrollStep;
if(DY>=0)
DY=0;
}
}
//卷动到位了
if( ox == 0 && oy == 0 && DX == 0 && DY == 0 )
{
g_ePlayState=PS_MAIN; //返回
}
ShowMap(); //显示地图
}
//添加地图陷阱
void CMap::AddHook(int x, int y, char *string)
{
if( Hook_Num==MAX_HOOK )
{
ShowMessage("地图陷阱数量已满( Hook_Num=32 )");
return;
}
Cell[Width*y+x].CP=Hook_Num;
strcpy(Hook[Hook_Num], string);
Hook_Num++;
}
//设置地图陷阱
void CMap::SetHook(int x, int y, int num)
{
if( num>=MAX_HOOK && num != BLOCK_CP )
{
ShowMessage("地图陷阱超过最大值( Max Hook_Num=32 )");
return;
}
Cell[Width*y+x].CP=num;
}
//设置地图某格地面
void CMap::SetCell(int level, int x, int y, int num, int page)
{
if( level <0 || level >2 )
{
ShowMessage("层次 %d 超过最大值( MaxLevel=%d )", level, 2);
return;
}
if( x>=Width-1 || y>=Height-1 || x<0 || y< 0 )
{
ShowMessage("坐标(%d,%d)超出范围(0,0 - %d,%d)", x, y, Width-1, Height-1);
return;
}
if( page >= Max_GroundPic )
{
ShowMessage("页面 %d 超过最大值( MaxPage=%d )", page, Max_GroundPic-1);
return;
}
int w,h;
//得到页面大小
GetSurfaceSize(lpDDSMap[page], w, h);
if( num >= (w/32)*(h/32) )
{
ShowMessage("编号 %d 超过最大值( MaxNum=%d )", num, (w/32)*(h/32)-1);
return;
}
switch(level)
{
case 0: //地面
Cell[Width*y+x].GroundPic=page;
Cell[Width*y+x].Ground=num;
break;
case 1: //物体1
Cell[Width*y+x].ObjPic=page;
Cell[Width*y+x].Obj=num;
break;
case 2: //物体2
Cell[Width*y+x].Obj2Pic=page;
Cell[Width*y+x].Obj2=num;
break;
}
}
//设置地图阻挡
void CMap::SetBlock(int x, int y, int block)
{
if( x>=Width-1 || y>=Height-1 || x<0 || y< 0 )
{
ShowMessage("坐标(%d,%d)超出范围(0,0 - %d,%d)", x, y, Width-1, Height-1);
return;
}
if( block < 0 || block > 1 )
{
ShowMessage("block(%d)超出范围(0,1)", block);
return;
}
Cell[Width*y+x].Block=block;
}
//设置地图层次
void CMap::SetLevel(int x, int y, int level1, int level2)
{
if( x>=Width-1 || y>=Height-1 || x<0 || y< 0 )
{
ShowMessage("坐标(%d,%d)超出范围(0,0 - %d,%d)", x, y, Width-1, Height-1);
return;
}
if( level1 < 0 || level1 > 1 )
{
ShowMessage("level1(%d)超出范围(0,1)", level1);
return;
}
if( level2 < 0 || level2 > 1 )
{
ShowMessage("level2(%d)超出范围(0,1)", level2);
return;
}
Cell[Width*y+x].Level=level1;
Cell[Width*y+x].Level2=level2;
}
//读入Npc列表从ini文件
bool CMap::LoadIniNpcList(char *filename)
{
//如果文件不存
if( !CheckFile( filename ) )
{
return true;
}
//读入NPC
CIniSet Ini;
Ini.Open(filename);
ClearNpc();
//NPC最大数目
long lNpcNum = Ini.ReadInt("Npc", "Max_Npc");
for(int i=0; i<lNpcNum; i++)
{
CNpc* p = new CNpc;
char *NpcIndex=Ini.ReadText("Npc", i);
p->LoadNpcIni(filename, NpcIndex);
m_vNpc.push_back(p);
_FREE(NpcIndex);
}
return true;
}
//加入一个Npc
int CMap::AddNpc(char *filename, char *index)
{
//如果文件不存
if( !CheckFile( filename ) )
{
return ERROR_DATA;
}
CNpc* p = new CNpc;
p->LoadNpcIni(filename, index);
m_vNpc.push_back(p);
return m_vNpc.size()-1;
}
//删除一个NPC
int CMap::DelNpc(int num)
{
if( num >= m_vNpc.size() )
{
return ERROR_DATA;
}
//脚底方格清空阻挡
Block[ Width*m_vNpc[num]->State.Y+m_vNpc[num]->State.X ]=0;
if(m_vNpc[num]->bMoving)
{
Block[m_vNpc[num]->Path[m_vNpc[num]->PathCurrentStep].x +m_vNpc[num]->Path[m_vNpc[num]->PathCurrentStep].y*Width] =0;
}
long l = 0;
for(itNpc it=m_vNpc.begin(); it!=m_vNpc.end(); it++)
{
if( l == num )
{
m_vNpc.erase(it);
return m_vNpc.size();
}
l++;
}
return m_vNpc.size();
}
//从npc名字获取ID
int CMap::GetNpcId(char *string)
{
for(int i=0; i<m_vNpc.size(); i++)
{
if( stricmp( m_vNpc[i]->Name, string)==0 )
{
return i;
}
}
return -1; //没找到
}
//排序NPC
void CMap::SortNpc()
{
m_vSortNpc.clear();
for(int i=0; i<m_vNpc.size(); i++)
{
for(itNpc it=m_vSortNpc.begin(); it!=m_vSortNpc.end(); it++)
{
CNpc* p = (*it);
if( m_vNpc[i]->State.y < p->State.y ) //y坐标排序
{
m_vSortNpc.insert(it, m_vNpc[i]);
goto _Next;
}
}
m_vSortNpc.push_back(m_vNpc[i]);
_Next:;
}
}
//清空NPC
void CMap::ClearNpc()
{
for(int i=0; i<m_vNpc.size(); i++)
{
CNpc* p = m_vNpc[i];
_DELETE(p);
}
m_vNpc.clear();
m_vSortNpc.clear();
}
//计算显示格子
void CMap::CountDisplayGrid()
{
if( g_eDisplayState == DS_NORMAL ) //普通模式
{
startx=SX; //全显
starty=SY;
endx=startx+ShowCellW+1;
endy=starty+ShowCellH+1;
}
else if( g_eDisplayState == DS_NIGHT ) //夜晚模式
{
startx=role[0].State.X-5; //显示主角周围的一部分
endx=startx+11;
//边界检查
if( startx<0 )
{
startx=0;
}
if( endx>=Width )
{
endx=Width-1;
}
starty=role[0].State.Y-4;
endy=starty+8;
if( starty<0 )
{
starty=0;
}
if( endy>=Height )
{
endy=Height-1;
}
}
}
//-----------------------------------------------------------------
//获得一个绝对点的格子
int CMap::_GetCell(int x, int y, int W)
{
return _grid_y(y) * W + _grid_x(x);
}
//**********************
//获得一个点所在的格子X
int CMap::_GetCellX(int x, int y)
{
return _grid_x(x);
}
//**********************
//获得一个点所在的格子Y
int CMap::_GetCellY(int x, int y)
{
return _grid_y(y);
}
//**********************
//获得一个点所在的格子
int CMap::GetCell(int x, int y)
{
return Width * (_grid_y(y)+SY) + _grid_x(x) + SX;
}
//**********************
//获得一个点所在的格子X
int CMap::GetCellX(int x, int y)
{
return _grid_x(x)+SX;
}
//**********************
//获得一个点所在的格子Y
int CMap::GetCellY(int x, int y)
{
return _grid_y(y)+SY;
}
//********************
//获取一个格子的坐标
RECT CMap::GetRectangle(int n)
{
int x=_point_x(n%Width), y=_point_y(n/Width);
RECT rect={ x, y, x+CellWidth, y+CellHeight};
return rect;
}
//********************
//获取一个格子的绝对坐标矩形
RECT CMap::_GetRectangle(int n, int W)
{
int x=_point_x(n%W), y=_point_y(n/W);
RECT rect={ x, y, x+CellWidth, y+CellHeight};
return rect;
}
//**********************
//填充一个格子
void CMap::FillCell(int x, int y, WORD num)
{
Blt(lpDDSBack, _point_x(x)+DX, _point_y(y)+DY, lpDDSTools, _GetRectangle(num, ShowCellW), true);
}
/////////////////////////////////////////////////////////////////////////
// 整张地图
/////////////////////////////////////////////////////////////////////////
//把整张地图复制到lpSurf
void CMap::CreateFullMap(LPDIRECTDRAWSURFACE lpSurf, int lSurfWidth, int lSurfHeight)
{
float LoopX, LoopY; //小图块个数
int lTileWidth, lTileHeight; //小图块大小
int x, y;
int _SX=SX; //保存
int _SY=SY;
//需要几个屏幕才能显示完整个地图
LoopX=(float)(Width-1)/20; //横着20个格子
LoopY=(float)(Height-1)/15; //竖着15个格子
lTileWidth = (int)(lSurfWidth/LoopX);
lTileHeight = (int)(lSurfHeight/LoopY);
for( int j=0; j<=(int)LoopY; j++ )
{
SY = j*15;
y = j*lTileHeight;
//最后一个屏幕的行修正
if( j==(int)LoopY )
{
SY=Height - 16; //用于地图的显示,所以要显示一个整的地图
int H=((Height)%15); //剩下的高度
y=(j)*lTileHeight - lTileHeight*H/15; //重叠部分修正
}
for( int i=0; i<=(int)LoopX; i++ )
{
SX = i*20;
x = i*lTileWidth;
//最后一屏幕的列修正
if( i == (int)LoopX )
{
SX=Width - 21;
int W=((Width)%20);
x=(i)*lTileWidth - lTileWidth*W/20;
}
ShowMap(false);
RECT dr={x, y, x+lTileWidth, y+lTileHeight};
lpSurf->Blt(&dr, lpDDSBack, &RectScreen, DDBLT_WAIT, 0);
}
}
SX = _SX;
SY = _SY;
}
//显示整张地图
void CMap::ShowFullMap()
{
//变黑
FillSurface(lpDDSBackGround, RGB16(0,0,0) );
float LoopX, LoopY; //小图块个数
int ow, oh; //小图块大小
int FullWidth, FullHeight; //缩略图的总尺寸
LoopX=(float)(Width-1)/20;
LoopY=(float)(Height-1)/15;
//以宽度为准
if( (float)Width/Height >= (float)4/3 )
{
ow=(int)(ScreenWidth/LoopX);
oh=(int)(ScreenHeight/LoopX);
FullWidth=ScreenWidth;
FullHeight=ScreenWidth*(Height-1)/(Width-1);
}
else //以高度为准
{
ow=(int)(ScreenWidth/LoopY);
oh=(int)(ScreenHeight/LoopY);
FullWidth=ScreenHeight*(Width-1)/(Height-1);
FullHeight=ScreenHeight;
}
CreateFullMap(lpDDSBackGround, FullWidth, FullWidth);
_UpdateScreen(lpDDSBackGround);
//等待返回
int px=0,py=0;
MSG msg;
while(1)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if (!GetMessage(&msg, NULL, 0, 0)) return;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else if(bActive)
{
//获取输入信息
GetInputData();
if( B_UP || mouse == LB_UP)
{
//显示地图的坐标
if( px==0 )
SX=0;
else
SX=Width*px/FullWidth;
if( py==0 )
SY=0;
else
SY=Height*py/FullHeight;
return;
}
if( mouse == RB_UP )
{
return;
}
//跟踪鼠标,产生小视口的位置
px=point.x-ow/2;
py=point.y-oh/2;
//边界检查
if( px < 0 )
px=0;
if( py < 0 )
py=0;
if( px >= FullWidth - ow )
px = FullWidth - ow -2;
if( py >= FullHeight - oh )
py = FullHeight - oh -2;
//显示缩略图
Blt(lpDDSBack, 0,0, lpDDSBackGround, RectScreen, false);
//画上视口矩形
Rectangle(lpDDSBack, px, py, px+ow, py+oh, RGB16(255,255,255));
_UpdateScreen();
}
else WaitMessage(); //等待消息
}
}
// 保存整张地图
void CMap::SaveFullMap(char* filename, float fPer)
{
LPDIRECTDRAWSURFACE lpTemp;
//根据缩放比例计算大小
int w = (int)((Width-1)*32*fPer);
int h = (int)((Height-1)*32*fPer);
CreateBitmap(lpTemp, w, h);
CreateFullMap(lpTemp, w, h);
//保存成BPM文件
SaveToBitmapFile(lpTemp, filename);
_RELEASE(lpTemp);
}
//恢复所有层次关系
void CMap::RestoreLevel(int n)
{
for(int i=0; i<Width*Height; i++)
{
Cell[i].Level=n;
Cell[i].Level2=n;
}
}
//恢复所有阻挡关系
void CMap::RestoreBlock(int n)
{
for(int i=0; i<Width*Height; i++)
{
Cell[i].Block=n;
}
}
//恢复所有鼠标状态
void CMap::RestoreMouseType(int n)
{
for(int i=0; i<Width*Height; i++)
{
Cell[i].MouseType=n;
}
}
//设置陷阱类型
void CMap::SetCPType(int x,int y,int type)
{
Cell[y*Width+x].CPType = type;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -