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

📄 upm_game.cpp

📁 C++课程大学作业的一次任务
💻 CPP
字号:
///////////////////////////////
//     UPM_GAME.CPP
//
// MAIN GAME PROCESS FUNCTIONS
//
// PROJECT: Ultra Pac Man
// PROGRAMER: Mal
// LAST UPDATED: Dec 2nd 2001
///////////////////////////////

#include "upm_game.h"
#include "m_err.h"
#include <stdlib.h>
#include <conio.h>
#include <math.h>

ItemNode* pItemHead = NULL;
MonsterNode* pMonsterHead = NULL;

bool NormalDotCheck(M_Map* map,M_Sprite* sprite,bool isInit)
{
	static long lRemainScore=0;

	if(map->GetMapState()==M_TRUE)
	{
		if(isInit==M_TRUE && thisMap->GetMapState()==M_TRUE)
		{
			lRemainScore = 0;//reset lRemainScore
			for(int nY=1;nY<=MAPMAXY;nY++)
			{
			 for(int nX=1;nX<=MAPMAXX;nX++)
			 {
				if(map->GetMapBlockInfo(nX,nY)->nBlockType == B_NORMAL_DOT)
					lRemainScore+=DEFAULT_ADDITION_SCORE;
			 }
			}
		}

		if(sprite->Report()->isLiving == M_TRUE && lRemainScore!=0)
		{
			if(map->GetMapBlockInfo(sprite->Report()->nPosX,sprite->Report()->nPosY)->nBlockType == B_NORMAL_DOT
				&& sprite->HaveOffset()==M_FALSE)
			{
				map->ChgBlockProperty(sprite->Report()->nPosX,sprite->Report()->nPosY, B_SPACE, T_SPACE);
				sprite->AddScore(DEFAULT_ADDITION_SCORE);
				lRemainScore-=DEFAULT_ADDITION_SCORE;
			}
		}

		if(lRemainScore!=0) return M_TRUE;//still some normal dots remains
		else
		{
		  return M_FALSE;//all normal dots have been eaten
		}
	}
 return M_ERR_MAP_NOT_READY;
}


void PrintMap()
{
	for(int y=1; y<=MAPMAXY; y++)
	{
		for(int x=1; x<=MAPMAXX; x++)
		{
			switch(thisMap->GetMapBlockInfo(x,y)->nBlockType)
			{
				case B_WALL:		thisRenderer->AddMBC(x,y,T_WALL);break;
				case B_SPACE:		thisRenderer->AddMBC(x,y,T_SPACE);break;
				case B_NORMAL_DOT:  thisRenderer->AddMBC(x,y,T_SPACE);
									thisRenderer->AddEC(x,y,T_NORMAL_DOT);break;
				case B_POWER_DOT:   thisRenderer->AddMBC(x,y,T_SPACE);
									thisRenderer->AddEC(x,y,T_POWER_DOT);break;
				case B_SRP:			thisRenderer->AddMBC(x,y,T_SRP);break;
				case B_MRP:			thisRenderer->AddMBC(x,y,T_MRP);break;
				case B_AVOID:		thisRenderer->AddMBC(x,y,T_AVOID);break;
				case B_SPEED_DOT:   thisRenderer->AddMBC(x,y,T_SPACE);
									thisRenderer->AddEC(x,y,T_SPEED_DOT);break;
			}
		}
	}
}


bool InitItems(M_Map* map)
{
 if(map->GetMapState() == M_TRUE)//check if map has initialized
 {
	ItemNode* tmp;

	for(int y=1; y<=MAPMAXY; y++)
	{
	 for(int x=1; x<=MAPMAXX; x++)
	 {
		if(map->GetMapBlockInfo(x,y)->nBlockType == B_POWER_DOT)
		{
			tmp = pItemHead;

			if((pItemHead=new ItemNode) == NULL)
				MErr("ERROR OCCURRED WHEN CREATING ITEM NODE");

			if((pItemHead->thisItem=new M_PowerDot(x,y)) == NULL)
				MErr("ERROR OCCURRED WHEN CREATING POWER DOT OBJECT");

			pItemHead->nextItem = tmp;

			//clear it from map to prevent override
			map->ChgBlockProperty(x,y,B_SPACE,T_SPACE);
			thisRenderer->AddMBC(x,y,T_SPACE);
		}

		if(map->GetMapBlockInfo(x,y)->nBlockType == B_SPEED_DOT)
		{
			tmp = pItemHead;

			if((pItemHead=new ItemNode) == NULL)
				MErr("ERROR OCCURRED WHEN CREATING ITEM NODE");

			if((pItemHead->thisItem=new M_SpeedDot(x,y)) == NULL)
				MErr("ERROR OCCURRED WHEN CREATING SPEED DOT OBJECT");

			pItemHead->nextItem = tmp;

			//change block property to prevent override
			map->ChgBlockProperty(x,y,B_SPACE,T_SPACE);
			thisRenderer->AddMBC(x,y,T_SPACE);
		}
	 }
	}
  return M_NORMAL;
 }

 return M_ERR_MAP_NOT_READY;
}


bool CheckItems(M_Sprite* sprite, MonsterNode* monsters, M_Map* map)
{
 if(map->GetMapState() == M_TRUE)//only when map is ready
 {
	ItemNode *pThis = pItemHead;

	while(pThis!=NULL)
	{
		if(pThis->thisItem->Report()->isLiving == M_FALSE)
		{
			pThis->thisItem->Respawn();
		}
		else
		{//you can add some codes to delete the used items
			pThis->thisItem->Think(sprite,monsters);
		}

		pThis = pThis->nextItem;

	}
  return M_NORMAL;
 }

 return M_ERR_MAP_NOT_READY;
}

void KillItems()
{
	ItemNode* tmp;
	while(pItemHead!=NULL)
	{
		delete pItemHead->thisItem;
		tmp = pItemHead;
		pItemHead = pItemHead->nextItem;
		delete tmp;
	}
}

bool InitMonsters(M_Map* map)
{
 if(map->GetMapState() == M_TRUE)//only when map is ready
 {
	int TotalMonsters = map->GetMapInfo()->nTotalMRPoints;

	for(;TotalMonsters>0;TotalMonsters--)
	{
		MonsterNode* tmp = pMonsterHead;

		if((pMonsterHead = new MonsterNode)==NULL)
			MErr("ERROR OCCURRED WHEN CREATING MONSTER NODE");

		if((pMonsterHead->thisMonster = new M_Monster)==NULL)
			MErr("ERROR OCCURRED WHEN CREATING MONSTER OBJECT");

		pMonsterHead->nextMonster = tmp;
	}
  return M_NORMAL;
 }

 return M_ERR_MAP_NOT_READY;
}

bool CheckMonsters(M_Map* map)
{
 if(map->GetMapState() == M_TRUE)//only when map is ready
 {
	MonsterNode* pThis = pMonsterHead;

	while(pThis!=NULL)
	{
		pThis->thisMonster->Think();
		pThis = pThis->nextMonster;
	}
 return M_NORMAL;
 }
 return M_ERR_MAP_NOT_READY;
}

void KillMonsters()
{
 MonsterNode* tmp;
 //clear monster link table
 while(pMonsterHead!=NULL)
 {
   delete pMonsterHead->thisMonster;
   tmp = pMonsterHead;
   pMonsterHead = pMonsterHead->nextMonster;
   delete tmp;
 }
}

bool CheckCollision(M_Sprite* sprite, MonsterNode* monsters, M_Map* map)
{
 if(map->GetMapState() == M_TRUE)//only when map is ready
 {
  if(sprite->Report()->isLiving == M_TRUE)//dead man can't collide
  {
	while(monsters!=NULL)
	{
	 if(sprite->Report()->nPosX == monsters->thisMonster->Report()->nPosX
		&& sprite->Report()->nPosY == monsters->thisMonster->Report()->nPosY)
	 {
		if(sprite->MoverState() == S_NORMAL
			&& monsters->thisMonster->MoverState() == S_NORMAL)
		{
			sprite->Kill();
		}
		else
		if((sprite->MoverState() == S_POWER || sprite->MoverState() == S_SPEED)
			&& monsters->thisMonster->MoverState() == S_WEAK)
		{
			monsters->thisMonster->Kill();
			sprite->AddScore(DEFAULT_MONSTER_SCORE);
		}
		else
		if((sprite->MoverState() == S_POWER || sprite->MoverState() == S_SPEED)
			&& monsters->thisMonster->MoverState() == S_NORMAL)
		{
			sprite->AddScore(-(DEFAULT_MONSTER_SCORE));
		}
		else
		if(sprite->MoverState() == S_NORMAL
			&& monsters->thisMonster->MoverState() == S_WEAK)
		{
			sprite->AddScore(DEFAULT_MONSTER_SCORE);
		}
	 }

	 monsters = monsters->nextMonster;
	}
  }
  else return M_ERR_NOTLIVING;

  return M_NORMAL;
 }
 else return M_ERR_MAP_NOT_READY;
}


bool AI(M_Sprite* sprite,MonsterNode* monsters, M_Map* map)
{
 if(map->GetMapState() == M_TRUE)//only when map is ready
 {
	int SPosX,SPosY,MPosX,MPosY,nDistance,mbCnt,deltaX=0,deltaY=0;
	int nextMove, altNextMove,traceStart;
	//Get Sprite Present Position
	SPosX = sprite->Report()->nPosX;
	SPosY = sprite->Report()->nPosY;

	while(monsters!=NULL)
	{
		MPosX = monsters->thisMonster->Report()->nPosX;
		MPosY = monsters->thisMonster->Report()->nPosY;
		nDistance = monsters->thisMonster->nAwareDistance;
		if(MPosX==SPosX && MPosY==SPosY)
			return M_NORMAL;
	  //only go detect when near enough
	  if(abs(MPosX-SPosX)<=nDistance && abs(MPosY-SPosY)<=nDistance)
	  {
		if(MPosX==SPosX && MPosY>SPosY)//M is lower than S, check up
		{
			deltaX		= 0;
			deltaY   	= -1;
			traceStart 	= MPosY;
			nextMove 	= DIR_UP;//if found Sprite, go this direction
			altNextMove	= DIR_DOWN;//if Sprite is powered or speeded
		}

		else if(MPosX==SPosX && MPosY<SPosY)//M is higher than S, check down
		{
			deltaX		= 0;
			deltaY		= 1;
			traceStart 	= MPosY;
			nextMove 	= DIR_DOWN;
			altNextMove	= DIR_UP;
		}

		else if(MPosY==SPosY && MPosX>SPosX)//M is 'righter' than S, check left
		{
			deltaX   	= -1;
			deltaY		= 0;
			traceStart 	= MPosX;
			nextMove 	= DIR_LEFT;
			altNextMove = DIR_RIGHT;
		}

		else if(MPosY==SPosY && MPosX<SPosX)//M is 'lefter' than S, check right
		{
			deltaX   	= 1;
			deltaY		= 0;
			traceStart 	= MPosX;
			nextMove 	= DIR_RIGHT;
			altNextMove = DIR_LEFT;
		}
		else
			return M_ERR_UNKNOWN;//unknown error if reached this


		for(mbCnt=traceStart;/*define below*/;mbCnt+= deltaX+deltaY)
		{//check for sprite in the direction, if countered a wall, stop scan

			if(deltaX!=0)//check left or right
			{
				if(thisMap->GetMapBlockInfo(mbCnt+deltaX,MPosY)->nBlockType == B_WALL)
				{//if meet a wall
					break;
				}
				if(mbCnt+deltaX == SPosX)//if found a sprite
				{
					if(sprite->MoverState()==S_NORMAL)
					{
						monsters->thisMonster->AIChangeNextMove(nextMove);
					}
					else
					{
						if(thisMap->GetMapBlockInfo(MPosX-deltaX,MPosY)->nBlockType != B_WALL)
							monsters->thisMonster->AIChangeNextMove(altNextMove);
					}
					break;
				}
			}

			if(deltaY!=0)
			{
				if(thisMap->GetMapBlockInfo(MPosX,mbCnt+deltaY)->nBlockType == B_WALL)
				{//if meet a wall
					break;
				}
				if(mbCnt+deltaY == SPosY)//if found a sprite
				{
					if(sprite->MoverState()==S_NORMAL)
					{
						monsters->thisMonster->AIChangeNextMove(nextMove);
					}
					else
					{
						if(thisMap->GetMapBlockInfo(MPosX,MPosY-deltaY)->nBlockType != B_WALL)
							monsters->thisMonster->AIChangeNextMove(altNextMove);
					}
					break;
				}
			}
		 if(mbCnt==traceStart+nDistance) break;//end condition
		}
	  }

	  monsters = monsters->nextMonster;
	}//==>end while
  return M_NORMAL;
 }
 return M_ERR_MAP_NOT_READY;
}

⌨️ 快捷键说明

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