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

📄 m_entity.cpp

📁 C++课程大学作业的一次任务
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/////////////////////////////
//    M_ENTITY.CPP
//
// CORE ENTITIES FOR UPM
//
// PROJECT: ULTRA PAC MAN
// PROGRAMER: Mal
// LAST UPDATE: Dec. 2nd 2001
///////////////////////////////

#include "m_entity.h"
#include "m_time.h"
#include "upm_game.h"
#include "m_err.h"

#include <stdlib.h>
#include <conio.h>
#include <math.h>

extern unsigned breakflags;
extern long clockticks;

M_Sprite* thisSprite;//Global pointer for single instance class

M_Entity::M_Entity()
{
	if((thisEnt = new BaseProperty) == NULL)
		MErr("ERROR OCCURRED WHEN CREATING ENTITY PROPERTY STRUCT");

	thisEnt->isLiving = M_FALSE;
}

M_Entity::~M_Entity()
{
	delete thisEnt;
}

const BaseProperty* M_Entity::Report()
{
	return thisEnt;
}

////////////////////////
// DERIVATIVE CLASSES
///////////////////////

bool M_Mover::Move(int direction)
{
 if(thisEnt->isLiving == M_TRUE)
 {
	if(direction == DIR_STEADY)//direction is steady...
	{                          //refresh Entity only.
		thisRenderer->AddEC(thisEnt->nPosX,thisEnt->nPosY,thisEnt->nTexture,fOffsetX,fOffsetY);
	 return M_NORMAL;
	}

	int   deltaX,deltaY;//delta sets
	int	  traceStart, traceEnd, mbCnt;//counter and indicators
	int   tmpThisPosX,tmpThisPosY,tmpNextPosX,tmpNextPosY;
	float tmpThisActX,tmpThisActY,tmpNextActX,tmpNextActY;
	const MapBlock *nextMB, *thisMB;

//STEP 1. Flush the blocks that the Entity within

	//Flush the current map block
	thisRenderer->AddMBC(thisEnt->nPosX,thisEnt->nPosY,thisMap->GetMapBlockInfo(thisEnt->nPosX,thisEnt->nPosY)->nTexture);

	if(nLastMovDir == DIR_UP || nLastMovDir == DIR_DOWN)
	{//if offsets is presented, refresh the DOWN one
	 if(fOffsetX!=0 || fOffsetY!=0)
		thisRenderer->AddMBC(thisEnt->nPosX,thisEnt->nPosY+1,thisMap->GetMapBlockInfo(thisEnt->nPosX,thisEnt->nPosY+1)->nTexture);
	}

	if(nLastMovDir == DIR_LEFT || nLastMovDir == DIR_RIGHT)
	{//if offsets is presented, refresh the RIGHT one
	 if(fOffsetX!=0 || fOffsetY!=0)
		thisRenderer->AddMBC(thisEnt->nPosX+1,thisEnt->nPosY,thisMap->GetMapBlockInfo(thisEnt->nPosX+1,thisEnt->nPosY)->nTexture);
	}


//STEP 2. Calculate the next step

	//Direction deltaSets
	switch(direction)
	{
		case DIR_UP:     deltaX=0;  deltaY=-1; break;
		case DIR_DOWN:   deltaX=0;  deltaY=1;  break;
		case DIR_LEFT:   deltaX=-1; deltaY=0;  break;
		case DIR_RIGHT:  deltaX=1;  deltaY=0;  break;
		case DIR_STEADY: deltaX=0;  deltaY=0;  break;
	}
	//this MB X and Y
	tmpThisPosX = thisEnt->nPosX;
	tmpThisPosY = thisEnt->nPosY;
	//this actual X and Y
	tmpThisActX = (tmpThisPosX-1)*8 + fOffsetX;
	tmpThisActY = (tmpThisPosY-1)*8 + fOffsetY;
	//next actual X and Y
	tmpNextActX = tmpThisActX + (thisEnt->fSpeed)*deltaX;
	tmpNextActY = tmpThisActY + (thisEnt->fSpeed)*deltaY;

	//next MB X and Y
	tmpNextPosX = int(tmpNextActX)/8 + 1;
	tmpNextPosY = int(tmpNextActY)/8 + 1;


//STEP 3. Check the path between THIS and NEXT position for WALL and CORNER

	//WALL DETECTION
	if((deltaX!=0 && tmpNextPosX==tmpThisPosX) || (deltaY!=0 && tmpNextPosY==tmpThisPosY))
	{//Still within the same block
	  if(direction==DIR_UP || direction==DIR_LEFT)
	  {//if going up or left
		if(direction==DIR_LEFT)//go left
		{
			if(tmpNextActX == (tmpNextPosX-1)*8)
			{//on the origin point of block, check this block for wall only
				if(thisMap->GetMapBlockInfo(tmpThisPosX-1,tmpThisPosY)->nBlockType == B_WALL)
				{
					thisEnt->nDirection = DIR_STEADY;//stops the current direction
				}
			//jump over wall detection to corner detection
			 goto CORNER_DETECTION;
			}
		}

		if(direction==DIR_UP)//go up
		{
			if(tmpNextActY == (tmpNextPosY-1)*8)
			{//on the origin point of block, check this block for wall only
				if(thisMap->GetMapBlockInfo(tmpThisPosX,tmpThisPosY-1)->nBlockType == B_WALL)
				{
					thisEnt->nDirection = DIR_STEADY;//stops the current direction
				}
			//jump over wall detection to corner detection
			 goto CORNER_DETECTION;
			}
		}
	  }

	 //if not on the origin point of block,or going RIGHT or DOWN
	 //jump over wall detection and corner detection
		goto END_OF_TRACE;
	}
	else//if not within the same block
	{
		if(direction==DIR_UP)//if going UP
		{
			if(tmpNextActY!=(tmpNextPosY-1)*8)//with offset
			{
				traceStart = tmpThisPosY;//from this block
				traceEnd = tmpNextPosY+1;//to block before NP
			}
			else//without offset
			{
				traceStart = tmpThisPosY;//from this block
				traceEnd = tmpNextPosY;//to NP
			}
		}

		if(direction==DIR_LEFT)//if going LEFT
		{
			if(tmpNextActX!=(tmpNextPosX-1)*8)//with offset
			{
				traceStart = tmpThisPosX;//from this block
				traceEnd = tmpNextPosX+1;//to block before NP
			}
			else//without offset
			{
				traceStart = tmpThisPosX;//from this block
				traceEnd = tmpNextPosX;//to NP
			}
		}

		if(direction==DIR_DOWN)//going DOWN
		{
			traceStart = tmpThisPosY+1;//from next block
			traceEnd = tmpNextPosY;//to NP
		}

		if(direction==DIR_RIGHT)//going RIGHT
		{
			traceStart = tmpThisPosX+1;//from next block
			traceEnd = tmpNextPosX;//to NP
		}

		for(mbCnt=traceStart;/*define below*/;mbCnt+= deltaX+deltaY)
		{
		  //check for wall in the direction
			if(deltaX!=0)
			{
				if(thisMap->GetMapBlockInfo(mbCnt+deltaX,tmpThisPosY)->nBlockType == B_WALL)
				{//if meet a wall
					tmpNextPosX = mbCnt;//set next MB x to infront of the wall
					tmpNextActX = (tmpNextPosX-1)*8;
					thisEnt->nDirection = DIR_STEADY;
					break;//jump out of WALL DETECTION
				}
			}

			if(deltaY!=0)
			{
				if(thisMap->GetMapBlockInfo(tmpThisPosX,mbCnt+deltaY)->nBlockType == B_WALL)
				{//if meet a wall
					tmpNextPosY = mbCnt;//set next MB y to infront of the wall
					tmpNextActY = (tmpNextPosY-1)*8;
					thisEnt->nDirection = DIR_STEADY;
					break;//jump out of WALL DETECTION
				}
			}
		 if(mbCnt==traceEnd) break;//end condition
		}
	}//==>End of WALL DETECTION

CORNER_DETECTION:
;
	//CORNER DETECTION
	if(nNextMovDir == direction)
	{//if next direction equals present direction
		nNextMovDir = DIR_STEADY;
	}

	if(nNextMovDir!=DIR_STEADY)
	{
		if((deltaX!=0 && tmpThisPosX==tmpNextPosX) || (deltaY!=0 && tmpThisPosY==tmpNextPosY))
		{//if next step still in the same block
			 if(direction==DIR_UP || direction==DIR_LEFT)
			 {//if going up or left
				if(direction==DIR_LEFT)//go left
				{
					if(tmpNextActX == (tmpNextPosX-1)*8)
					{//on the origin point of block, check this block for turning only
					  traceStart=tmpThisPosX;//from this block
					  traceEnd = tmpThisPosX;//to this block
					}
				}

				if(direction==DIR_UP)//go up
				{
					if(tmpNextActY == (tmpNextPosY-1)*8)
					{//on the origin point of block, check this block turning
					  traceStart=tmpThisPosY;
					  traceEnd=tmpThisPosY;
					}
				}
			 }
			 else
			//if not on the origin point of block,or going RIGHT or DOWN
			//jump over wall detection and corner detection
			goto END_OF_TRACE;
		}
		else//if not within the same block
		{
			if(direction==DIR_UP)//if going UP
			{
				if(tmpNextActY!=(tmpNextPosY-1)*8)//with offset
				{
					traceStart = tmpThisPosY;//from this block
					traceEnd = tmpNextPosY+1;//to block before NP
				}
				else//without offset
				{
					traceStart = tmpThisPosY;//from this block
					traceEnd = tmpNextPosY;//to NP
				}
			}

			if(direction==DIR_LEFT)//if going LEFT
			{
				if(tmpNextActX!=(tmpNextPosX-1)*8)//with offset
				{
					traceStart = tmpThisPosX;//from this block
					traceEnd = tmpNextPosX+1;//to block before NP
				}
				else//without offset
				{
					traceStart = tmpThisPosX;//from this block
					traceEnd = tmpNextPosX;//to NP
				}
			}

			if(direction==DIR_DOWN)//going DOWN
			{
				traceStart = tmpThisPosY+1;//from next block
				traceEnd = tmpNextPosY;//to NP
			}

			if(direction==DIR_RIGHT)//going RIGHT
			{
				traceStart = tmpThisPosX+1;//from next block
				traceEnd = tmpNextPosX;//to NP
			}
		}

		for(mbCnt=traceStart;/*define below*/;mbCnt+= deltaX+deltaY)
		{

			if(deltaX!=0)
			{
				if(nNextMovDir == DIR_UP)
				{
					if(thisMap->GetMapBlockInfo(mbCnt,tmpThisPosY-1)->nBlockType!=B_WALL)
					{
						tmpNextPosX = mbCnt;
						tmpNextActX = (mbCnt-1)*8;
						thisEnt->nDirection = nNextMovDir;
						nNextMovDir = DIR_STEADY;
						break;
					}
				}

				if(nNextMovDir == DIR_DOWN)
				{
					if(thisMap->GetMapBlockInfo(mbCnt,tmpThisPosY+1)->nBlockType!=B_WALL)
					{
						tmpNextPosX = mbCnt;
						tmpNextActX = (mbCnt-1)*8;
						thisEnt->nDirection = nNextMovDir;
						nNextMovDir = DIR_STEADY;
						break;
					}
				}

				if(nNextMovDir == DIR_LEFT)
				{
					if(thisMap->GetMapBlockInfo(mbCnt-1,tmpThisPosY)->nBlockType!=B_WALL)
					{
						tmpNextPosX = mbCnt;
						tmpNextActX = (mbCnt-1)*8;
						thisEnt->nDirection = nNextMovDir;
						nNextMovDir = DIR_STEADY;
						break;
					}
				}

				if(nNextMovDir == DIR_RIGHT)
				{
					 if(thisMap->GetMapBlockInfo(mbCnt+1,tmpThisPosY)->nBlockType!=B_WALL)
					 {
						tmpNextPosX = mbCnt;
						tmpNextActX = (mbCnt-1)*8;
						thisEnt->nDirection = nNextMovDir;
						nNextMovDir = DIR_STEADY;
						break;
					 }
				}
			}//==>end of LEFT or RIGHT going

			if(deltaY!=0)
			{

				if(nNextMovDir == DIR_UP)
				{
					if(thisMap->GetMapBlockInfo(tmpThisPosX,mbCnt-1)->nBlockType!=B_WALL)
					{
						tmpNextPosY = mbCnt;
						tmpNextActY = (mbCnt-1)*8;
						thisEnt->nDirection = nNextMovDir;
						nNextMovDir = DIR_STEADY;
						break;
					}
				}

				if(nNextMovDir == DIR_DOWN)
				{
					if(thisMap->GetMapBlockInfo(tmpThisPosX,mbCnt+1)->nBlockType!=B_WALL)
					{
						tmpNextPosY = mbCnt;
						tmpNextActY = (mbCnt-1)*8;
						thisEnt->nDirection = nNextMovDir;
						nNextMovDir = DIR_STEADY;
						break;
					}
				}

				if(nNextMovDir == DIR_LEFT)
				{
					if(thisMap->GetMapBlockInfo(tmpThisPosX-1,mbCnt)->nBlockType!=B_WALL)
					{
						tmpNextPosY = mbCnt;
						tmpNextActY = (mbCnt-1)*8;
						thisEnt->nDirection = nNextMovDir;
						nNextMovDir = DIR_STEADY;
						break;
					}
				}

				if(nNextMovDir == DIR_RIGHT)
				{
					 if(thisMap->GetMapBlockInfo(tmpThisPosX+1,mbCnt)->nBlockType!=B_WALL)
					 {
						tmpNextPosY = mbCnt;
						tmpNextActY = (mbCnt-1)*8;
						thisEnt->nDirection = nNextMovDir;
						nNextMovDir = DIR_STEADY;
						break;
					 }
				}
			}//==>end of UP or DOWN
		 if(mbCnt==traceEnd) break;
		}
	}//==>End of Corner detection

END_OF_TRACE:
;
//STEP 4. CONFIRM THE NEW POSITION

	//Set the Entity's new Position
	thisEnt->nPosX = tmpNextPosX;
	thisEnt->nPosY = tmpNextPosY;
	fOffsetX = fabs(tmpNextActX - (tmpNextPosX-1)*8);
	fOffsetY = fabs(tmpNextActY - (tmpNextPosY-1)*8);

⌨️ 快捷键说明

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