📄 m_entity.cpp
字号:
/////////////////////////////
// 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 + -