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

📄 game.cpp

📁 过程的c++编译器 里面有超级玛丽的源代码 还有一个 管理系统的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	}
	else
	{//向左移动,则X值越大越近
		Compare.XLarge=true;
	}
	std::priority_queue<BLOCKINFO,std::vector<BLOCKINFO>,BLOCKINFOCompare> BlockList(Compare);//在运动路径内的所有阻挡物

	int start,end;
	if(Vert<0)
	{//向上移动,只可能是本对象的顶线与阻挡物的底线相碰
		start=Obj->YPos;
		end=start+Vert;
		//判断有无物体在移动路径之内
		std::set<CObject*>::const_iterator it;
		for(it=m_Object.begin();it!=m_Object.end();it++)
		{
			if(*it==Obj)continue;//是自己
			int ypos=(*it)->YPos+(*it)->Height;
			if(ypos>end&&ypos<=start)
			{//底线在运动范围之内
				//看阻挡物的横坐标是否在运动范围内
				int x1=Obj->XPos+Horz*(ypos-start)/Vert;
				int x2=x1+Obj->Width;
				if(!((*it)->XPos>=x2||(*it)->XPos+(*it)->Width<=x1))
				{//横坐标也在运动范围内,则受到阻挡
					bi.Blocker=(*it);
					bi.BlockMode=2;
					bi.BumpMode=2;
					bi.MayBe=false;
					bi.x=x1;
					bi.y=ypos;
					BlockList.push(bi);
				}
				else if( (Horz>0&&(*it)->XPos==x2) || (Horz<0&&(*it)->XPos+(*it)->Width==x1) )
				{//在水平方向上有速度,而阻挡物正好在运动区域的左或右边界上,则可能阻挡,也可能不阻挡
					bi.Blocker=(*it);
					bi.MayBe=true;
					bi.x=x1;
					bi.y=ypos;
					BlockList.push(bi);
				}
			}
		}
	}
	else if(Vert>0)
	{//向下移动,只可能是本对象的底线与阻挡物的顶线相碰
		start=Obj->YPos+Obj->Height;
		end=start+Vert;
		//判断有无物体在移动路径之内
		std::set<CObject*>::const_iterator it;
		for(it=m_Object.begin();it!=m_Object.end();it++)
		{
			if(*it==Obj)continue;//是自己
			int ypos=(*it)->YPos;
			if(ypos>=start&&ypos<end)
			{//顶线在运动范围之内
				//看阻挡物的横坐标是否在运动范围内
				int x1=Obj->XPos+Horz*(ypos-start)/Vert;
				int x2=x1+Obj->Width;
				if(!((*it)->XPos>=x2||(*it)->XPos+(*it)->Width<=x1))
				{//横坐标也在运动范围内,则受到阻挡
					bi.Blocker=(*it);
					bi.BlockMode=2;
					bi.BumpMode=1;
					bi.MayBe=false;
					bi.x=x1;
					bi.y=ypos-Obj->Height;
					BlockList.push(bi);
				}
				else if( (Horz>0&&(*it)->XPos==x2) || (Horz<0&&(*it)->XPos+(*it)->Width==x1) )
				{//在水平方向上有速度,而阻挡物正好在运动区域的左或右边界上,则可能阻挡,也可能不阻挡
					bi.Blocker=(*it);
					bi.MayBe=true;
					bi.x=x1;
					bi.y=ypos-Obj->Height;
					BlockList.push(bi);
				}
			}
		}
	}

	if(Horz<0)
	{//向左移动,只可能是本对象的左边线与阻挡物的右边线相碰
		start=Obj->XPos;
		end=start+Horz;
		//判断有无物体在移动路径之内
		std::set<CObject*>::const_iterator it;
		for(it=m_Object.begin();it!=m_Object.end();it++)
		{
			if(*it==Obj)continue;//是自己
			int xpos=(*it)->XPos+(*it)->Width;
			if(xpos>end&&xpos<=start)
			{//右边线在运动范围之内
				//看阻挡物的纵坐标是否在运动范围内
				int y1=Obj->YPos+Vert*(xpos-start)/Horz;
				int y2=y1+Obj->Height;
				if(!((*it)->YPos>=y2||(*it)->YPos+(*it)->Height<=y1))
				{//纵坐标也在运动范围内,则受到阻挡
					bi.Blocker=(*it);
					bi.BlockMode=1;
					bi.BumpMode=3;
					bi.MayBe=false;
					bi.x=xpos;
					bi.y=y1;
					BlockList.push(bi);
				}
				else if( (Vert>0&&(*it)->YPos==y2) || (Vert<0&&(*it)->YPos+(*it)->Height==y1) )
				{//在竖直方向上有速度,而阻挡物正好在运动区域的左或右边界上,则可能阻挡,也可能不阻挡
					bi.Blocker=(*it);
					bi.MayBe=false;
					bi.x=xpos;
					bi.y=y1;
					BlockList.push(bi);
				}
			}
		}
		if(end<0)
		{//左边线超出左边界
			bi.Blocker=NULL;
			bi.BlockMode=1;
			bi.MayBe=false;
			bi.x=0;
			bi.y=Obj->YPos+Vert*(0-start)/Horz;
			BlockList.push(bi);
		}
	}
	else if(Horz>0)
	{//向右移动,只可能是本对象的右边线与阻挡物的左边线相碰
		start=Obj->XPos+Obj->Width;
		end=start+Horz;
		//判断有无物体在移动路径之内
		std::set<CObject*>::const_iterator it;
		for(it=m_Object.begin();it!=m_Object.end();it++)
		{
			if(*it==Obj)continue;//是自己
			int xpos=(*it)->XPos;
			if(xpos>=start&&xpos<end)
			{//左边线在运动范围之内
				//看阻挡物的纵坐标是否在运动范围内
				int y1=Obj->YPos+Vert*(xpos-start)/Horz;
				int y2=y1+Obj->Height;
				if(!((*it)->YPos>=y2||(*it)->YPos+(*it)->Height<=y1))
				{//纵坐标也在运动范围内,则受到阻挡
					bi.Blocker=(*it);
					bi.BlockMode=1;
					bi.BumpMode=3;
					bi.MayBe=false;
					bi.x=xpos-Obj->Width;
					bi.y=y1;
					BlockList.push(bi);
				}
				else if( (Vert>0&&(*it)->YPos==y2) || (Vert<0&&(*it)->YPos+(*it)->Height==y1) )
				{//在水平方向上有速度,而阻挡物正好在运动区域的左或右边界上,则可能阻挡,也可能不阻挡
					bi.Blocker=(*it);
					bi.MayBe=true;
					bi.x=xpos-Obj->Width;
					bi.y=y1;
					BlockList.push(bi);
				}
			}
		}
		if(end+Obj->Width>288)
		{//右边线超出左边界
			bi.Blocker=NULL;
			bi.BlockMode=1;
			bi.MayBe=false;
			bi.x=288-Obj->Width;
			bi.y=Obj->YPos+Vert*(288-start)/Horz;
			BlockList.push(bi);
		}
	}

	//若没有阻挡,则运动到指定的位置
	Obj->XPos=OrDestX;
	Obj->YPos=OrDestY;

	std::set<CObject*> Has;
	for(;!BlockList.empty();BlockList.pop())
	{
		if(Has.find(BlockList.top().Blocker)!=Has.end())continue;//可能会有重复项
		Has.insert(BlockList.top().Blocker);
		int BumpMode;
		if(BlockList.top().MayBe)
		{//是一个刚好在边界上的阻挡物
			if(Obj==m_Mario)
			{//玛莉遇到这种情况,视为竖直方向遇到阻挡,仍可水平行走
				retval=2;
				BumpMode=Vert>0?1:2;
			}
			else
			{//妖怪遇到这种情况,视为水平方向遇到阻挡,使其掉下去
				retval=1;
				BumpMode=3;
			}
			Obj->Bump(BlockList.top().Blocker,BumpMode,true);
			//自己碰对方和对方碰自己的方式正好上下相反
			if(1==BumpMode)
				BumpMode=2;
			else if(2==BumpMode)
				BumpMode=1;
			BlockList.top().Blocker->Bump(Obj,BumpMode,false);
			if(!Obj->Block(BlockList.top().Blocker))continue;//不受阻挡,则继续看更远的阻挡物
			Obj->XPos=BlockList.top().x;
			Obj->YPos=BlockList.top().y;
			break;
		}
		else
		{
			if(BlockList.top().Blocker)
			{
				Obj->Bump(BlockList.top().Blocker,BlockList.top().BumpMode,true);
				//自己碰对方和对方碰自己的方式正好上下相反
				if(1==BlockList.top().BumpMode)
					BumpMode=2;
				else if(2==BlockList.top().BumpMode)
					BumpMode=1;
				else
					BumpMode=3;
				BlockList.top().Blocker->Bump(Obj,BumpMode,false);
			}
			if(!Obj->Block(BlockList.top().Blocker))continue;//不受阻挡,则继续看更远的阻挡物
			Obj->XPos=BlockList.top().x;
			Obj->YPos=BlockList.top().y;
			retval=BlockList.top().BlockMode;
			BlockList.pop();
			//同一距离可能有多个阻挡物,与它们都相碰
			while(!BlockList.empty())
			{
				if(BlockList.top().MayBe)break;
				if(BlockList.top().x!=Obj->XPos||BlockList.top().y!=Obj->YPos)break;
				if(BlockList.top().Blocker)
				{
					Obj->Bump(BlockList.top().Blocker,BlockList.top().BumpMode,true);
					//自己碰对方和对方碰自己的方式正好上下相反
					if(1==BlockList.top().BumpMode)
						BumpMode=2;
					else if(2==BlockList.top().BumpMode)
						BumpMode=1;
					BlockList.top().Blocker->Bump(Obj,BumpMode,false);
				}
				BlockList.pop();
			}
			break;
		}
	}

	if(1==retval)
	{
		if(Obj->YPos!=OrDestY)
		{//水平方向有阻挡,且未达到指定的纵坐标,则要在竖直方向上走完该距离
			retval|=Move(Obj,0,OrDestY-Obj->YPos);
		}
	}
	else if(2==retval||4==retval)
	{
		if(Obj->XPos!=OrDestX)
		{//竖直方向有阻挡,且未达到指定的横坐标,则要在水平方向上走完该距离
			retval|=Move(Obj,OrDestX-Obj->XPos,0);
		}
	}

	return retval;
}

void CGame::LoadMapData()
{
	m_SoundMan->PlayBackMusic(1);

	//将玛莉重置到这一关的起始位置
	m_Mario->ResetPos(m_MapData[0]*16,m_MapData[1]*16);

	//加载地图最前面16*20格的数据
	int x,y;
	const int (*pMap)[16];
	pMap=reinterpret_cast<const int(*)[16]>(m_MapData+3);
	for(x=0;x<20;x++)
	{
		for(y=0;y<16;y++)
		{
			if(pMap[x][y])InsertObject(x*16,y*16,pMap[x][y]);
		}
	}
	m_MapPos=0;
	m_NextMap=20;
}

void CGame::MoveMap(int Offset)
{
/*
	将地图向左移动,读取右边的新数据。
	参数:
		[i]Offset		要移动的像素。
*/
	int NewPos=m_MapPos+Offset;
	if(NewPos>m_MapData[2]*16-288)NewPos=m_MapData[2]*16-288;//已到达最右边
	Offset=NewPos-m_MapPos;
	if(!Offset)return;//没有移动
	m_MapPos=NewPos;

	//所有的角色和物体都向左移动
	std::set<CObject*>::iterator it;
	for(it=m_Object.begin();it!=m_Object.end();it++)
	{
		(*it)->XPos-=Offset;
	}

	//读取右边的新数据
	int end=(m_MapPos+288+(16-1))/16+1;//读到右边界外的一格
	if(end>m_MapData[2])end=m_MapData[2];//右边界外已经没有了,则只读到右边界处
	int x;
	int y;
	const int (*pMap)[16];
	pMap=reinterpret_cast<const int(*)[16]>(m_MapData+3);
	for(x=m_NextMap;x<end;x++)
	{
		for(y=0;y<16;y++)
		{
			if(pMap[x][y])InsertObject(x*16-m_MapPos,y*16,pMap[x][y]);
		}
	}
	m_NextMap=end;
}

void CGame::AddObj(CObject * Obj)
{
/*
	新增一个角色或物体。
	参数:
		[i]Obj		要增加的对象。
*/
	m_Object.insert(Obj);
}

void CGame::SetSound(CSoundMan * Obj)
{
/*
	设置声音处理对象。
	参数:
		[i]Obj		要使用的CSoundMan对象。在游戏中,CGame将通过该对象控制声音。
*/
	m_SoundMan=Obj;
}

void CGame::PlaySound(CSoundMan::SOUNDNUM Num)
{
	m_SoundMan->PlaySound(Num);
}

void CGame::PlayBackMusic(int Num)
{
	m_SoundMan->PlayBackMusic(Num);
}

⌨️ 快捷键说明

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