28#include "ObjectsPacMan.h"
30#include "ResourceManager.h"
31#include "BrainsFactory.h"
34PacMan::PacMan(Sint32 iMX, Sint32 iMY, GameField* GF) : Actor(PME_OBJECT_PACMAN, iMX, iMY, GF)
37 iLifes = PME_PACMAN_START_LIFES;
38 iSpeed = PME_PACMAN_START_SPEED;
39 iPointsForEatingGhostsPerPelletPower = 0;
42 pStateInit =
new(std::nothrow) PacManStateInit(
"Init");
43 pStateEvading =
new(std::nothrow) PacManStateEvading(
"Evading");
44 pStateChasing =
new(std::nothrow) PacManStateChasing(
"Chasing");
45 pStateDeath =
new(std::nothrow) PacManStateDeath(
"Death");
48 Main::Instance().ILogMgr().get()->msg(LML_LOW,
" [PacMan] PacMan ID '%d' created.\n", iID);
59 pStateEvading =
nullptr;
61 pStateChasing =
nullptr;
63 pStateDeath =
nullptr;
65 Main::Instance().ILogMgr().get()->msg(LML_LOW,
" [PacMan] PacMan ID '%d' deleted.\n", iID);
71Sint32 PacMan::execute()
73 Sint32 iRet = PME_ACTOR_ALIVE;
76 if(iLifes <= 0)
return PME_GAME_OVER;
80 if(pCurrentState) pCurrentState->execute(
this);
86 if(stateCurrentCheck(*pStateInit) || stateCurrentCheck(*pStateChasing) || stateCurrentCheck(*pStateDeath)) iRet = PME_ACTOR_SPECIAL;
93Sint32 PacMan::debug(Sint32 iMode)
95 Main &mC64 = Main::Instance();
97 Font* pFont = Main::Instance().IFontMgr().get(ResourceManager::Instance().get(RM_FONT_CONSOLE));
103 pFont->setPosition(PME_DEBUG_PANEL_PACMAN_X, PME_DEBUG_PANEL_PACMAN_Y + iMazeRenderingY);
104 pFont->render(
"PacMan info");
107 mC64.ITool().intToStrDec(iMazeX, sTmp);
108 sDebug =
"Position: [";
111 mC64.ITool().intToStrDec(iMazeY, sTmp);
114 mC64.ITool().intToStrDec(iPositionX, sTmp);
117 mC64.ITool().intToStrDec(iPositionY, sTmp);
120 pFont->setPosition(PME_DEBUG_PANEL_PACMAN_X, PME_DEBUG_PANEL_PACMAN_Y + iMazeRenderingY + 16);
121 pFont->render(sDebug);
125 mC64.ITool().intToStrDec(iSpeed, sTmp);
127 pFont->setPosition(PME_DEBUG_PANEL_PACMAN_X, PME_DEBUG_PANEL_PACMAN_Y + iMazeRenderingY + 32);
128 pFont->render(sDebug);
131 mC64.ITool().intToStrDec(pointTarget.iX, sTmp);
132 sDebug =
"Target: [";
135 mC64.ITool().intToStrDec(pointTarget.iY, sTmp);
138 pFont->setPosition(PME_DEBUG_PANEL_PACMAN_X, PME_DEBUG_PANEL_PACMAN_Y + iMazeRenderingY + 48);
139 pFont->render(sDebug);
142 pCurrentState->getName(sDebug);
143 sDebug =
"State: " + sDebug;
144 pFont->setPosition(PME_DEBUG_PANEL_PACMAN_X, PME_DEBUG_PANEL_PACMAN_Y + iMazeRenderingY + 64);
145 pFont->render(sDebug);
148 if(BrainsFactory::Instance().getName(idBrain, sDebug) == -1) sDebug =
"Empty";
149 sDebug =
"Brain: " + sDebug;
150 pFont->setPosition(PME_DEBUG_PANEL_PACMAN_X, PME_DEBUG_PANEL_PACMAN_Y + iMazeRenderingY + 80);
151 pFont->render(sDebug);
157Sint32 PacMan::getLifes()
163Sint32 PacMan::msgGoInit()
167 stateChange(pStateInit);
172Sint32 PacMan::msgPelletPowerEaten(Sint32 iX, Sint32 iY)
174 stateChange(pStateChasing);
181Sint32 PacMan::msgGhostCollision()
184 if(stateCurrentCheck(*pStateChasing))
186 if(iPointsForEatingGhostsPerPelletPower == 0) iPointsForEatingGhostsPerPelletPower = PME_POINTS_EAT_GHOST;
187 else iPointsForEatingGhostsPerPelletPower *= 2;
188 return iPointsForEatingGhostsPerPelletPower;
191 else stateChange(pStateDeath);
200Sint32 PacMan::applyMovementRules(Sint32 iTX, Sint32 iTY)
202 Sint32 i, iSelected = 0;
203 double dLowest = 1000.0f;
204 vector<MazePoint> vMovementOptions;
207 pGameField->getMovementOptions(iMazeX, iMazeY, vMovementOptions);
210 if(vMovementOptions.size() == 1) iSelected = 0;
216 for(i = 0; i < vMovementOptions.size(); ++i) euclideanDistance(iTX, iTY, vMovementOptions[i]);
219 for(i = 0; i < vMovementOptions.size(); ++i)
221 if((vMovementOptions[i].iX == iMazePrevX) && (vMovementOptions[i].iY == iMazePrevY))
225 vMovementOptions[i].dDistance += 1.75;
230 for(i = 0; i < vMovementOptions.size(); ++i)
232 if(dLowest > vMovementOptions[i].dDistance)
234 dLowest = vMovementOptions[i].dDistance;
241 vPath.push_back(vMovementOptions[iSelected]);
247PacManStateInit::PacManStateInit(
const string& sN) : State(sN) { iTime = 0; }
248void PacManStateInit::enter(Actor* pAct)
250 PacMan* pPM =
reinterpret_cast<PacMan*
>(pAct);
256 pPM->eAM = Actor::eActorMoving::AM_NEXT_STEP;
259 iTime = Main::Instance().ITimer().getTicksNow();
261void PacManStateInit::execute(Actor* pAct)
263 PacMan* pPM =
reinterpret_cast<PacMan*
>(pAct);
264 if(Main::Instance().ITimer().getTicksNow() > (iTime + pPM->pGameField->messageGetReady(-1))) pPM->stateChange(pPM->pStateEvading);
265 else pPM->pGameField->messageGetReady(1);
267void PacManStateInit::exit(Actor* pAct)
272 reinterpret_cast<PacMan*
>(pAct)->pGameField->messageGetReady(0);
277PacManStateEvading::PacManStateEvading(
const string& sN) : State(sN) { iTX = iTY = iITX = iITY = 0; bGetNewTarget =
true; }
278void PacManStateEvading::execute(Actor* pAct)
281 MazePoint pointImmediateTarget;
282 PacMan* pPM =
reinterpret_cast<PacMan*
>(pAct);
285 if((pPM->iMazeX == iTX) && (pPM->iMazeY == iTY)) bGetNewTarget =
true;
288 if((pPM->iMazeX != iITX) || (pPM->iMazeY != iITY))
292 bGetNewTarget =
true;
296 iTargetType = BrainsFactory::Instance().getTargetType(pPM->idBrain);
297 if(iTargetType == PME_BRAIN_IMMEDIATE_TARGET) bGetNewTarget =
true;
302 pPM->think(iTX, iTY);
303 pPM->pointTarget.iX = iTX;
304 pPM->pointTarget.iY = iTY;
305 bGetNewTarget =
false;
309 if(iTargetType == PME_BRAIN_HIGHLEVEL_TARGET)
311 if(pPM->vPath.size() == 0)
313 pPM->applyMovementRules(iTX, iTY);
320 pointImmediateTarget.iX = iTX;
321 pointImmediateTarget.iY = iTY;
322 pPM->vPath.push_back(pointImmediateTarget);
328PacManStateChasing::PacManStateChasing(
const string& sN) : State(sN) { iTicks = 0; }
329void PacManStateChasing::enter(Actor* pAct)
331 PacMan* pPM =
reinterpret_cast<PacMan*
>(pAct);
337 pPM->iPointsForEatingGhostsPerPelletPower = 0;
340 iTicks = (PME_PACMAN_ENPOWERED_TIME * 40) / 1000;
343 pPM->pGameField->setWaveMode(PME_GLOBAL_WAVE_EVADING);
345void PacManStateChasing::execute(Actor* pAct)
347 PacMan* pPM =
reinterpret_cast<PacMan*
>(pAct);
350 if(iTicks < 0) pPM->stateChange(pPM->pStateEvading);
354 if(iTicks < ((PME_PACMAN_ENPOWERED_TIME * 40) / 4) / 1000) pPM->pGameField->setWaveMode(PME_GLOBAL_WAVE_EVADING_END);
355 pPM->pStateEvading->execute(pAct);
359void PacManStateChasing::exit(Actor* pAct)
365 reinterpret_cast<PacMan*
>(pAct)->pGameField->restoreWaveMode();
371PacManStateDeath::PacManStateDeath(
const string& sN) : State(sN) {}
372void PacManStateDeath::enter(Actor* pAct)
377 PacMan* pPM =
reinterpret_cast<PacMan*
>(pAct);
378 Sprite* sprObj = Main::Instance().ISpriteMgr().get(pPM->sprID);
381 pPM->eSS = Actor::eSpriteState::SS_DEATH;
382 sprObj->selectAnim(SPR_STATE_NORMAL);
384void PacManStateDeath::execute(Actor* pAct)
386 PacMan* pPM =
reinterpret_cast<PacMan*
>(pAct);
387 Sprite* sprObj = Main::Instance().ISpriteMgr().get(pPM->sprID);
390 if(sprObj->status() == C64_STATUS_END)
393 pPM->pGameField->initObjects();