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

📄 map.cpp

📁 凌星科技_2004-5-17_《圣剑英雄传II》的源代码scr2
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		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 + -