30#include "ResourceManager.h"
31#include "MazeDynamic.h"
32#include "MazeStatic.h"
33#include "BrainsFactory.h"
34#include "MapSearchAStar.h"
36#include "ObjectsPacMan.h"
37#include "ObjectsGhost.h"
41GameField::GameField(GlobalStatus* GS)
45 iMazeReady = iTimeStart = iNumPellets = iNumEatenPellets = 0;
46 iGetReadyTime = PME_GETREADY_TIME;
47 iMazePixelX = iMazePixelY = 0;
48 iFieldArray =
nullptr;
50 iRenderGraphicsStatus = -1;
51 iSpecialTextCounter = -1;
52 sSpecialMessageCounter.clear();
53 sSpecialMessage.clear();
54 bDebug = bDebugDisableObjectRender = -1;
59 pMapSearch =
new(std::nothrow) MapSearchAStar(
this);
66 Main::Instance().ILogMgr().get()->msg(LML_LOW,
" [Gamefield] Info: Object initialized.\n");
71GameField::~GameField()
74 if(pMapSearch !=
nullptr)
delete pMapSearch;
81 Main::Instance().ILogMgr().get()->msg(LML_LOW,
" [Gamefield] Info: Object closed.\n");
86Sint32 GameField::init()
88 Actor* pActor =
nullptr;
89 Sint32 iPacManBrain, iGhostRedBrain, iGhostPinkBrain, iGhostBlueBrain, iGhostOrangeBrain;
91 if(iMazeReady != 0)
return PME_BREAK;
94 if(pGlobalStatus->iGameType == PME_GAME_WORKBENCH)
96 iPacManBrain = pGlobalStatus->workBench.iPacManBrain;
97 iGhostRedBrain = pGlobalStatus->workBench.iGhostRedBrain;
98 iGhostPinkBrain = pGlobalStatus->workBench.iGhostPinkBrain;
99 iGhostBlueBrain = pGlobalStatus->workBench.iGhostBlueBrain;
100 iGhostOrangeBrain = pGlobalStatus->workBench.iGhostOrangeBrain;
102 ResourceManager::Instance().setPacManDeathAnim(0);
108 iPacManBrain = PME_BRAIN_TYPE_HUMAN;
110 if(pGlobalStatus->iGameType == PME_GAME_STANDARD) iGhostRedBrain = iGhostPinkBrain = iGhostBlueBrain = iGhostOrangeBrain = PME_BRAIN_TYPE_FIXED;
112 else iGhostRedBrain = iGhostPinkBrain = iGhostBlueBrain = iGhostOrangeBrain = PME_BRAIN_TYPE_EVOLVED;
113 iGetReadyTime = PME_GETREADY_TIME;
114 ResourceManager::Instance().setPacManDeathAnim(1);
118 if(iFieldArray ==
nullptr) iFieldArray = create2DArray<sField>(MAZE_HEIGHT, MAZE_WIDTH);
121 pActor =
new(std::nothrow) PacMan(14, 23,
this);
122 pActor->setBrain(iPacManBrain | PME_OBJECT_PACMAN);
123 vObjects.push_back(pActor);
126 if(iGhostRedBrain != PME_OBJECT_NULL)
128 pActor =
new(std::nothrow) Ghost(PME_OBJECT_GHOST_RED, 12, 14,
this);
129 pActor->setBrain(iGhostRedBrain | PME_OBJECT_GHOST_RED);
130 vObjects.push_back(pActor);
134 if(iGhostPinkBrain != PME_OBJECT_NULL)
136 pActor =
new(std::nothrow) Ghost(PME_OBJECT_GHOST_PINK, 13, 14,
this);
137 pActor->setBrain(iGhostPinkBrain | PME_OBJECT_GHOST_PINK);
138 vObjects.push_back(pActor);
142 if(iGhostBlueBrain != PME_OBJECT_NULL)
144 pActor =
new(std::nothrow) Ghost(PME_OBJECT_GHOST_BLUE, 14, 14,
this);
145 pActor->setBrain(iGhostBlueBrain | PME_OBJECT_GHOST_BLUE);
146 vObjects.push_back(pActor);
150 if(iGhostOrangeBrain != PME_OBJECT_NULL)
152 pActor =
new(std::nothrow) Ghost(PME_OBJECT_GHOST_ORANGE, 15, 14,
this);
153 pActor->setBrain(iGhostOrangeBrain | PME_OBJECT_GHOST_ORANGE);
154 vObjects.push_back(pActor);
157 #ifdef DEBUG_INTERNAL
158 Main::Instance().ILogMgr().get()->msg(LML_NORMAL,
" [GameField] Info: Maze loaded and game initialized.\n");
162 pMazeGen =
new(std::nothrow) Maze(9, 5);
169Sint32 GameField::nextMaze()
171 Sint32 x = 0, i, y = 0, iPowerPellet = PME_OBJECT_PELLET_POWER1;
172 char* pMaze =
nullptr;
173 Object* pObj =
nullptr;
174 vector<Uint8> vTiles;
176 if(iFieldArray ==
nullptr)
return PME_BREAK;
179 for(i = 0; i < vObjects.size();)
181 if(vObjects[i]->getID() >= PME_OBJECT_PELLET_POWER1)
184 vObjects.erase(vObjects.begin() + i);
188 iNumPellets = iNumEatenPellets = 0;
191 if(pGlobalStatus->iGameType == PME_GAME_STANDARD)
193 if(iMazeStaticLength < (MAZE_WIDTH * MAZE_HEIGHT))
return PME_BREAK;
194 i = iMazeReady % iMazeStaticNumber;
195 pMaze = (
char*)mazeStatic[i];
196 iMazeDynamicGenerationAttemps = 1;
197 iMazeDynamicGenerationTime = 0;
202 i = Main::Instance().ITimer().getTicksNow();
203 iMazeDynamicGenerationAttemps = pMazeGen->createMaze(vTiles);
204 iMazeDynamicGenerationTime = Main::Instance().ITimer().getTicksNow();
205 iMazeDynamicGenerationTime -= i;
206 pMaze = (
char*)&vTiles[0];
210 for(y = 0; y < MAZE_HEIGHT; y++)
211 for(x = 0; x < MAZE_WIDTH; x++)
214 iFieldArray[y][x].iState = PME_STATE_NULL;
215 iFieldArray[y][x].iItem = PME_ITEM_NULL;
216 iFieldArray[y][x].iObject = PME_OBJECT_NULL;
228 iFieldArray[y][x].iState = PME_STATE_WALL;
233 iFieldArray[y][x].iState = PME_STATE_WALKABLE;
238 iFieldArray[y][x].iState = PME_STATE_WALKABLE;
239 iFieldArray[y][x].iItem = PME_ITEM_PELLET;
245 iFieldArray[y][x].iState = PME_STATE_WALKABLE;
246 if(pGlobalStatus->workBench.iTraining != 1)
248 pObj =
new(std::nothrow) Object(iPowerPellet, x, y,
this);
249 vObjects.push_back(pObj);
250 iFieldArray[y][x].iObject = iPowerPellet;
260 iFieldArray[12][13].iState = PME_STATE_WALKABLE_GHOST;
261 iFieldArray[12][14].iState = PME_STATE_NULL;
262 for(y = 13; y < 16; y++)
263 for(x = 11; x < 17; x++)
266 iFieldArray[y][x].iState = PME_STATE_WALKABLE_GHOST;
273 Main::Instance().IMusicMgr().fadeOut(500);
274 Main::Instance().IConfigMgr().get()->fadeToColor(0, 0, 0, 500);
275 Main::Instance().IMusicMgr().get(ResourceManager::Instance().get(RM_MUS_GAME))->play(-1);
276 pGlobalStatus->iRenderScreen = PME_SCREEN_GAME;
283Sint32 GameField::close()
288 for(i = 0; i < vObjects.size(); ++i)
delete vObjects[i];
291 iMazeReady = iTimeStart = iNumPellets = iNumEatenPellets = 0;
292 iMazePixelX = iMazePixelY = 0;
293 if(iFieldArray) delete2DArray(iFieldArray);
294 iFieldArray =
nullptr;
296 iRenderGraphicsStatus = -1;
297 iSpecialTextCounter = -1;
298 sSpecialMessageCounter.clear();
299 sSpecialMessage.clear();
302 if(pMazeGen !=
nullptr)
delete pMazeGen;
306 Main::Instance().IMusicMgr().fadeOut(500);
307 Main::Instance().IConfigMgr().get()->fadeToColor(0, 0, 0, 500);
309 #ifdef DEBUG_INTERNAL
310 Main::Instance().ILogMgr().get()->msg(LML_NORMAL,
" [GameField] Info: Maze closed.\n\n");
318Sint32 GameField::execute()
320 Sint32 iDone = PME_LOOP, i;
322 Main& mC64 = Main::Instance();
325 if(iMazeReady == 0)
return PME_BREAK;
328 if(pGlobalStatus->iGameType != PME_GAME_WORKBENCH) messageStart();
332 iTimeStart = mC64.ITimer().getTicksNow();
333 iRenderGraphicsStatus = RENDERGRAPHICS_GAME;
334 while(iDone == PME_LOOP)
337 sGlobalWave.update();
340 for(i = 0; (i < vObjects.size()) && (iDone == PME_LOOP) && (sSpecialMessage !=
"PAUSED"); ++i)
345 if(vObjects[i]->getID() == PME_OBJECT_PACMAN)
348 iDone = vObjects[i]->execute();
350 if(iDone != PME_ACTOR_SPECIAL) --sGlobalWave.iTicks;
351 else iDone = PME_LOOP;
355 else vObjects[i]->execute();
359 if(iNumPellets == iNumEatenPellets)
361 iDone = PME_MAZE_END;
365 if(pGlobalStatus->iGameType == PME_GAME_WORKBENCH)
367 if(pGlobalStatus->workBench.iTime != 0)
369 if((mC64.ITimer().getTicksNow() - iTimeStart) > (pGlobalStatus->workBench.iTime * 1000))
377 while(mC64.update(&eEvent))
381 case SDL_EVENT_KEY_UP:
382 switch(eEvent.key.keysym.sym)
391 if(sSpecialMessage ==
"PAUSED") sSpecialMessage.clear();
392 else if(sSpecialMessage.size() == 0) sSpecialMessage =
"PAUSED";
397 bDebug = bDebug * (-1);
402 if(iDebugMode > 0) --iDebugMode;
408 if(iDebugMode < 4) ++iDebugMode;
415 bDebugDisableObjectRender = bDebugDisableObjectRender * (-1);
422 mC64.IConfigMgr().get()->getSnapshot(
"screenshot.png");
429 iDone = PME_MAZE_END;
436 bDebugShowTarget = bDebugShowTarget * (-1);
440 vObjects[0]->msgGhostCollision();
441 for(i = 0; i < vObjects.size(); ++i) vObjects[i]->msgPause();
450 if(iDone != PME_MAZE_END)
452 if(pGlobalStatus->iGameType != PME_GAME_WORKBENCH) messageEnd(iDone);
456 if(pGlobalStatus->workBench.iTraining != 1)
458 mC64.ILogMgr().get()->msg(LML_NORMAL,
" [GameField] Info: Maze '%d' (%s %d %dms)- %2.2f FPS during %2.2f seconds - Points %d \n",
459 iMazeReady, (pGlobalStatus->iGameType == PME_GAME_STANDARD) ?
"static" :
"dynamic", iMazeDynamicGenerationAttemps, iMazeDynamicGenerationTime,
460 mC64.ITimer().getAverageRFR(), (
float)(mC64.ITimer().getTicksNow() - iTimeStart) / 1000.0f,
461 pGlobalStatus->iPoints);
468Sint32 GameField::render(Sint32 iMode)
470 Sint32 iScreenW, iScreenH;
471 Sint32 x, y, i, iLifes;
474 Main& mC64 = Main::Instance();
479 if(iMazeReady == 0)
return PME_BREAK;
482 pScreen = mC64.IConfigMgr().get();
483 pScreen->getSize(&iScreenW, &iScreenH);
484 iMazePixelX = (iScreenW - (MAZE_TILE_SIZE * MAZE_WIDTH)) / 2;
485 iMazePixelY = MAZE_TILE_SIZE;
488 rDst.w = rDst.h = MAZE_TILE_SIZE;
497 for(y = 0; y < MAZE_HEIGHT; y++)
499 for(x = 0; x < MAZE_WIDTH; x++)
501 if(iFieldArray[y][x].iState == PME_STATE_WALL)
503 rDst.x = (x * rDst.w) + iMazePixelX;
504 rDst.y = (y * rDst.h) + iMazePixelY;
505 mC64.IGFX().rectFilled(rDst.x, rDst.y, rDst.x + rDst.w, rDst.y + rDst.h, 0x0000AAFF);
507 if(iFieldArray[y][x].iItem == PME_ITEM_PELLET)
509 rDst.x = (x * rDst.w) + iMazePixelX;
510 rDst.y = (y * rDst.h) + iMazePixelY;
511 i = ResourceManager::Instance().get(RM_SPR_PELLET);
512 mC64.ISpriteMgr().get(i)->setPosition(rDst.x, rDst.y);
513 mC64.ISpriteMgr().get(i)->render();
519 for(i = (Sint32)vObjects.size() - 1; vObjects.size() > i; --i)
521 if(vObjects[i]->getID() == PME_OBJECT_PACMAN)
523 iLifes =
reinterpret_cast<PacMan*
>(vObjects[i])->getLifes();
525 if(bDebugDisableObjectRender == -1) vObjects[i]->render(iMazePixelX, iMazePixelY);
529 pFont = mC64.IFontMgr().get(ResourceManager::Instance().get(RM_FONT_SCORE));
530 pFont->setPosition(iMazePixelX, -8);
531 mC64.ITool().intToStrDec(pGlobalStatus->iPoints, sTmp);
532 sText =
"Score "; sText += sTmp;
533 pFont->render(sText);
534 rDst.x = (iScreenW / 2) - MAZE_TILE_SIZE - (MAZE_TILE_SIZE / 2);
535 rDst.y = 0; rDst.w = MAZE_TILE_SIZE; rDst.h = MAZE_TILE_SIZE;
538 mC64.IImageMgr().get(ResourceManager::Instance().get(RM_IMG_ICON))->render(0,
nullptr, &rDst);
540 rDst.x += MAZE_TILE_SIZE;
542 mC64.ITool().intToStrDec(pGlobalStatus->iHighestScore, sTmp);
543 sText =
"Highest "; sText += sTmp;
544 pFont->setPosition(iMazePixelX + (MAZE_WIDTH * MAZE_TILE_SIZE) - 250, -8);
546 pFont->render(sText);
549 if(iRenderGraphicsStatus == RENDERGRAPHICS_START)
551 pScreen = mC64.IConfigMgr().get();
552 pScreen->getSize(&i,
nullptr);
553 pFont = mC64.IFontMgr().get(ResourceManager::Instance().get(RM_FONT_INFO));
555 specialText(pFont, (i - pFont->getWidth(sSpecialMessage)) / 2, (iScreenH / 2) - 150, sSpecialMessage, iSpecialTextCounter);
556 pFont->setPosition((i - pFont->getWidth(sSpecialMessageCounter)) / 2, (iScreenH / 2) - 80);
557 pFont->render(sSpecialMessageCounter);
563 if(sSpecialMessage.size() > 0)
565 pFont->setPosition((iScreenW - pFont->getWidth(sSpecialMessage)) / 2, (iScreenH / 2) + 20);
566 pFont->render(sSpecialMessage);
572 for(i = 0; i < vObjects.size(); ++i) vObjects[i]->debug(bDebugShowTarget);
581MapSearchAStar& GameField::mapSearch()
587Sint32 GameField::getState(Sint32 iMX, Sint32 iMY)
590 if(iMX < 0)
return PME_STATE_NULL;
591 else if(iMX > MAZE_WIDTH - 1)
return PME_STATE_NULL;
592 if(iMY < 0)
return PME_STATE_NULL;
593 else if(iMY > MAZE_HEIGHT - 1)
return PME_STATE_NULL;
596 return iFieldArray[iMY][iMX].iState;
600Sint32 GameField::getItem(Sint32 iMX, Sint32 iMY)
603 if(iMX < 0)
return PME_STATE_NULL;
604 else if(iMX > MAZE_WIDTH - 1)
return PME_STATE_NULL;
605 if(iMY < 0)
return PME_STATE_NULL;
606 else if(iMY > MAZE_HEIGHT - 1)
return PME_STATE_NULL;
609 return iFieldArray[iMY][iMX].iItem;
613Sint32 GameField::getEatenPelletsPercent()
615 return (iNumEatenPellets * 100) / iNumPellets;
619Sint32 GameField::getObjectPosition(Sint32 iID, Sint32 &iX, Sint32 &iY)
621 Sint32 i = getObjectIndex(iID);
624 vObjects[i]->getPositionMaze(iX, iY);
631Sint32 GameField::getObjectDirection(Sint32 iID, Sint32 &iX, Sint32 &iY)
633 Sint32 i = getObjectIndex(iID);
636 vObjects[i]->getDirection(iX, iY);
643Sint32 GameField::getObjectStateName(Sint32 iID,
string &sN)
645 Sint32 i = getObjectIndex(iID);
648 reinterpret_cast<Actor*
>(vObjects[i])->getStateName(sN);
655Sint32 GameField::getClosestPellet(Sint32 iID, Sint32 &iX, Sint32 &iY)
657 Sint32 iRadius = 1, iOX, iOY;
658 Sint32 i = getObjectIndex(iID);
661 vObjects[i]->getPositionMaze(iOX, iOY);
666 for(
int y = -iRadius; y <= iRadius; y++)
668 for(
int x = -iRadius; x <= iRadius; x++)
670 if(x*x + y * y <= iRadius * iRadius)
675 if(getItem(iX, iY) == PME_ITEM_PELLET)
692Sint32 GameField::moveTo(Sint32 iID, Sint32 iCurMX, Sint32 iCurMY, Sint32 iNewMX, Sint32 iNewMY)
694 Sint32 i, iObjs, iTmp;
695 Sint32 iX = 0, iY = 0;
698 iFieldArray[iCurMY][iCurMX].iObject -= iID;
701 iFieldArray[iNewMY][iNewMX].iObject += iID;
704 iObjs = iFieldArray[iNewMY][iNewMX].iObject;
707 if(iID == PME_OBJECT_PACMAN)
710 if(iFieldArray[iNewMY][iNewMX].iItem == PME_ITEM_PELLET)
712 iFieldArray[iNewMY][iNewMX].iItem = PME_ITEM_NULL;
713 Main::Instance().ISoundMgr().get(ResourceManager::Instance().get(RM_SND_GAMEEATPELLET))->play();
714 addPoints(PME_POINTS_EAT_PELLET);
719 if(iObjs >= PME_OBJECT_PELLET_POWER1)
721 iTmp = PME_GET_PELLET(iObjs);
722 iFieldArray[iNewMY][iNewMX].iObject -= iTmp;
723 Main::Instance().ISoundMgr().get(ResourceManager::Instance().get(RM_SND_GAMEEATPELLETPOWER))->play();
724 addPoints(PME_POINTS_EAT_PELLET_POWER);
728 i = getObjectIndex(iTmp);
731 vObjects[i]->getPositionMaze(iX, iY);
733 vObjects.erase(vObjects.begin() + i);
737 for(i = 0; i < vObjects.size(); ++i) vObjects[i]->msgPelletPowerEaten(iX, iY);
742 if(iObjs & PME_OBJECT_PACMAN)
747 if(iObjs & PME_OBJECT_GHOST_RED)
749 i = getObjectIndex(PME_OBJECT_GHOST_RED);
750 if(i != -1) iTmp = vObjects[i]->msgGhostCollision();
752 else if((iObjs & PME_OBJECT_GHOST_BLUE) && (iTmp == 2))
754 i = getObjectIndex(PME_OBJECT_GHOST_BLUE);
755 if(i != -1) iTmp = vObjects[i]->msgGhostCollision();
757 else if((iObjs & PME_OBJECT_GHOST_PINK) && (iTmp == 2))
759 i = getObjectIndex(PME_OBJECT_GHOST_PINK);
760 if(i != -1) iTmp = vObjects[i]->msgGhostCollision();
762 else if((iObjs & PME_OBJECT_GHOST_ORANGE) && (iTmp == 2))
764 i = getObjectIndex(PME_OBJECT_GHOST_ORANGE);
765 if(i != -1) iTmp = vObjects[i]->msgGhostCollision();
771 i = getObjectIndex(PME_OBJECT_PACMAN);
774 Main::Instance().ISoundMgr().get(ResourceManager::Instance().get(RM_SND_GAMEEATGHOST))->play();
775 addPoints(vObjects[i]->msgGhostCollision());
781 i = getObjectIndex(PME_OBJECT_PACMAN);
784 if(pGlobalStatus->iGameType != PME_GAME_WORKBENCH) Main::Instance().ISoundMgr().get(ResourceManager::Instance().get(RM_SND_GAMEPLAYERDEATH))->play();
785 vObjects[i]->msgGhostCollision();
786 for(i = 0; i < vObjects.size(); ++i) vObjects[i]->msgPause();
797Sint32 GameField::messageGetReady(Sint32 iShow)
799 if(iShow == 0) sSpecialMessage.clear();
800 else if(iShow == 1) sSpecialMessage =
"Get Ready!";
801 return iGetReadyTime;
805Sint32 GameField::initObjects()
810 for(y = 0; y < MAZE_HEIGHT; y++)
811 for(x = 0; x < MAZE_WIDTH; x++)
813 if(iFieldArray[y][x].iObject < PME_OBJECT_PELLET_POWER1) iFieldArray[y][x].iObject = PME_OBJECT_NULL;
817 if((iFieldArray[y][x].iObject & PME_OBJECT_PELLET_POWER1) == PME_OBJECT_PELLET_POWER1) iFieldArray[y][x].iObject = PME_OBJECT_PELLET_POWER1;
818 else if((iFieldArray[y][x].iObject & PME_OBJECT_PELLET_POWER2) == PME_OBJECT_PELLET_POWER2) iFieldArray[y][x].iObject = PME_OBJECT_PELLET_POWER2;
819 else if((iFieldArray[y][x].iObject & PME_OBJECT_PELLET_POWER3) == PME_OBJECT_PELLET_POWER3) iFieldArray[y][x].iObject = PME_OBJECT_PELLET_POWER3;
820 else if((iFieldArray[y][x].iObject & PME_OBJECT_PELLET_POWER4) == PME_OBJECT_PELLET_POWER4) iFieldArray[y][x].iObject = PME_OBJECT_PELLET_POWER4;
825 iFieldArray[23][14].iObject = PME_OBJECT_PACMAN;
826 iFieldArray[14][12].iObject = PME_OBJECT_GHOST_RED;
827 iFieldArray[14][13].iObject = PME_OBJECT_GHOST_PINK;
828 iFieldArray[14][14].iObject = PME_OBJECT_GHOST_BLUE;
829 iFieldArray[14][15].iObject = PME_OBJECT_GHOST_ORANGE;
832 for(i = 0; i < vObjects.size(); ++i) vObjects[i]->msgGoInit();
838 if(pGlobalStatus->iGameType == PME_GAME_WORKBENCH) sGlobalWave.iChanges = PME_CRUISE_MODE;
844Sint32 GameField::validateMazePosition(Sint32& iX, Sint32& iY)
846 Sint32 iRadius = 1, iOX, iOY;
850 else if(iX > (MAZE_WIDTH - 1)) iX = MAZE_WIDTH - 1;
852 else if(iY >(MAZE_HEIGHT - 1)) iY = MAZE_HEIGHT - 1;
859 for(
int y = -iRadius; y <= iRadius; y++)
861 for(
int x = -iRadius; x <= iRadius; x++)
863 if(x*x + y * y <= iRadius * iRadius)
867 if(getState(iX, iY) == PME_STATE_WALKABLE)
883Sint32 GameField::getMovementOptions(Sint32 iX, Sint32 iY, vector<MazePoint>& vMP)
891 if(getState(iX, iY - 1) == PME_STATE_WALKABLE)
895 vMP.push_back(vPoint);
899 if(getState(iX - 1, iY) == PME_STATE_WALKABLE)
903 vMP.push_back(vPoint);
906 else if((iX - 1) < 0)
910 vMP.push_back(vPoint);
914 if(getState(iX, iY + 1) == PME_STATE_WALKABLE)
918 vMP.push_back(vPoint);
922 if(getState(iX + 1, iY) == PME_STATE_WALKABLE)
926 vMP.push_back(vPoint);
929 else if((iX + 1) > (MAZE_WIDTH - 1))
933 vMP.push_back(vPoint);
940Sint32 GameField::getWaveMode()
942 return sGlobalWave.iMode;
946Sint32 GameField::setWaveMode(Sint32 iMode)
948 if(iMode == PME_GLOBAL_WAVE_EVADING)
950 sGlobalWave.iPreviousMode = sGlobalWave.iMode;
951 sGlobalWave.iMode = PME_GLOBAL_WAVE_EVADING;
953 else if(iMode == PME_GLOBAL_WAVE_EVADING_END) sGlobalWave.iMode = PME_GLOBAL_WAVE_EVADING_END;
958Sint32 GameField::restoreWaveMode()
960 sGlobalWave.iMode = sGlobalWave.iPreviousMode;
965Sint32 GameField::sGlobalWave::update()
970 iMode = PME_GLOBAL_WAVE_CHASING;
971 iTicks = (PME_GHOST_CHASING_TIME * Main::Instance().ITimer().getLFR()) / 1000;
976 if((iMode == PME_GLOBAL_WAVE_EVADING) || (iMode == PME_GLOBAL_WAVE_EVADING_END))
return 0;
979 if(iChanges >= PME_CRUISE_MODE)
981 iMode = PME_GLOBAL_WAVE_CHASING;
982 iTicks = (PME_GHOST_CHASING_TIME * Main::Instance().ITimer().getLFR()) / 1000;
988 if(iMode == PME_GLOBAL_WAVE_CHASING)
990 iMode = PME_GLOBAL_WAVE_SCATTERING;
992 iTicks = (PME_GHOST_SCATTERING_TIME * Main::Instance().ITimer().getLFR()) / 1000;
996 iMode = PME_GLOBAL_WAVE_CHASING;
998 iTicks = (PME_GHOST_CHASING_TIME * Main::Instance().ITimer().getLFR()) / 1000;
1005Sint32 GameField::sGlobalWave::reset()
1007 iMode = iChanges = iPreviousMode = 0;
1012Sint32 GameField::messageStart()
1014 Uint32 iTime = 0, iTmp, iStart, iDelay;
1018 Main& mC64 = Main::Instance();
1020 iSpecialTextCounter = 0;
1021 sSpecialMessage =
"Starting maze ";
1022 mC64.ITool().intToStrDec(iMazeReady, sMazeNumber);
1023 sSpecialMessage += sMazeNumber;
1025 iDelay = (iDone * 1000);
1026 iRenderGraphicsStatus = RENDERGRAPHICS_START;
1027 mC64.ISoundMgr().get(ResourceManager::Instance().get(RM_SND_GAMESTARTING))->play();
1028 iStart = mC64.ITimer().getTicksNow();
1033 iTmp = mC64.ITimer().getTicksNow();
1037 mC64.ITool().intToStrDec(iDone, sSpecialMessageCounter);
1039 else if(iTmp > (iTime + 1000))
1044 iSpecialTextCounter += 2;
1047 if(iTmp > (iStart + iDelay)) iDone = 0;
1050 while(mC64.update(&eEvent));
1053 sSpecialMessage.clear();
1059Sint32 GameField::messageEnd(Sint32 bFlag)
1061 Sint32 iDone = PME_LOOP;
1064 Main& mC64 = Main::Instance();
1065 Panel* myPanel = mC64.IGUIMgr().getPanel(ResourceManager::Instance().get(RM_PANEL_GAME));
1068 mC64.IMusicMgr().fadeOut(500);
1073 myPanel->getWidget(ID_GAME_LABEL)->setText(
"Game Aborted");
1074 mC64.ISoundMgr().get(ResourceManager::Instance().get(RM_SND_GAMEABORT))->play();
1077 myPanel->getWidget(ID_GAME_LABEL)->setText(
" Game Over! ");
1078 mC64.ISoundMgr().get(ResourceManager::Instance().get(RM_SND_GAMEOVER))->play();
1085 if(pGlobalStatus->iLowestScore > pGlobalStatus->iPoints) myPanel->getWidget(ID_GAME_ENTERNAME)->hide();
1086 else myPanel->getWidget(ID_GAME_ENTERNAME)->show();
1089 mC64.ICursorMgr().show();
1090 mC64.IGUIMgr().getPanel(ResourceManager::Instance().get(RM_PANEL_GAME))->baseWidget().show();
1091 while(iDone == PME_LOOP)
1096 while(mC64.update(&eEvent))
1102 if(eEvent.user.code == C64_EVENT_WIDGET)
1104 if(*
static_cast<Sint32*
>(eEvent.user.data1) == ID_GAME_CLOSE)
1106 mC64.ISoundMgr().get(ResourceManager::Instance().get(RM_SND_CLICKOK))->play();
1117 myPanel->getWidget(ID_GAME_ENTERNAME)->getText(sText);
1118 if(sText.empty()) sText =
"PacMan";
1119 mC64.ITool().szCopy(pGlobalStatus->szName, sText.c_str(),
sizeof(pGlobalStatus->szName));
1120 #ifdef DEBUG_INTERNAL
1121 mC64.ILogMgr().get()->msg(LML_INFO,
" Player '%s' - Points '%d' (%d<->%d)\n", sText.c_str(), pGlobalStatus->iPoints, pGlobalStatus->iLowestScore, pGlobalStatus->iHighestScore);
1125 sSpecialMessage.clear();
1126 mC64.ICursorMgr().hide();
1127 mC64.IGUIMgr().getPanel(ResourceManager::Instance().get(RM_PANEL_GAME))->baseWidget().hide();
1133Sint32 GameField::specialText(Font* pFont, Sint32 iX, Sint32 iY,
string &sText, Sint32 iCount)
1136 Sint32 i, iXPos, iYPos;
1140 dAngle = (double)iCount * 5.0;
1143 for(i = 0; i < (Sint32)sText.length(); i++)
1145 sChar[0] = sText[i];
1147 if(i == 0) iXPos = iX;
1148 iYPos = (Sint32)(iY + sin(SDL_PI_D / 180 * (dAngle + i * 12)) * pFont->getHeight());
1149 pFont->setPosition(iXPos, iYPos);
1150 pFont->render(sChar);
1151 iXPos = iXPos + pFont->getWidth(sChar);
1157Sint32 GameField::debug()
1159 Sint32 x, y, iFW, iFH;
1160 string sDebug, sTmp;
1161 Main& mC64 = Main::Instance();
1162 Font* pFont = mC64.IFontMgr().get(ResourceManager::Instance().get(RM_FONT_CONSOLE));
1165 if(iMazeReady == 0)
return -1;
1166 iFH = pFont->getHeight();
1169 for(y = 0; y < MAZE_HEIGHT; y++)
1171 for(x = 0; x < MAZE_WIDTH; x++)
1178 mC64.ITool().intToStrDec(x, sTmp);
1179 sDebug = sTmp; sDebug +=
",";
1180 mC64.ITool().intToStrDec(y, sTmp);
1186 mC64.ITool().intToStrDec(iFieldArray[y][x].iState, sTmp);
1192 mC64.ITool().intToStrDec(iFieldArray[y][x].iItem, sTmp);
1198 mC64.ITool().intToStrDec(iFieldArray[y][x].iObject, sTmp);
1204 iFW = pFont->getWidth(sDebug);
1205 pFont->setPosition((x * MAZE_TILE_SIZE + iMazePixelX) - ((iFW - MAZE_TILE_SIZE) / 2), (y * MAZE_TILE_SIZE + iMazePixelY) - ((iFH - MAZE_TILE_SIZE) / 2));
1206 pFont->render(sDebug);
1211 sDebug =
"Debug mode: ";
1218 sDebug +=
"coordinates";
1227 sDebug +=
"objects";
1230 pFont->setPosition(PME_DEBUG_PANEL_GAMEFIELD_X, PME_DEBUG_PANEL_GAMEFIELD_Y + iMazePixelY);
1231 pFont->render(sDebug);
1232 if(bDebugDisableObjectRender == 1) sDebug =
"Objects rendering disabled";
1233 else sDebug =
"Objects rendering enabled";
1234 pFont->setPosition(PME_DEBUG_PANEL_GAMEFIELD_X, PME_DEBUG_PANEL_GAMEFIELD_Y + iMazePixelY + 16);
1235 pFont->render(sDebug);
1237 mC64.ITool().intToStrDec(iMazeReady, sTmp);
1238 sDebug += sTmp; sDebug +=
" - Wave: ";
1239 mC64.ITool().intToStrDec(sGlobalWave.iTicks, sTmp);
1241 pFont->setPosition(PME_DEBUG_PANEL_GAMEFIELD_X, PME_DEBUG_PANEL_GAMEFIELD_Y + iMazePixelY + 48);
1242 pFont->render(sDebug);
1243 sDebug =
"Pellets: ";
1244 mC64.ITool().intToStrDec(iNumEatenPellets, sTmp);
1245 sDebug += sTmp; sDebug +=
"/";
1246 mC64.ITool().intToStrDec(iNumPellets, sTmp);
1247 sDebug += sTmp; sDebug +=
" (";
1248 mC64.ITool().intToStrDec(getEatenPelletsPercent(), sTmp);
1249 sDebug += sTmp; sDebug +=
"%)";
1250 pFont->setPosition(PME_DEBUG_PANEL_GAMEFIELD_X, PME_DEBUG_PANEL_GAMEFIELD_Y + iMazePixelY + 64);
1251 pFont->render(sDebug);
1253 sDebug =
"LFR/RFR: ";
1254 mC64.ITool().intToStrDec(mC64.ITimer().getCurrentLFR(), sTmp);
1255 sDebug += sTmp; sDebug +=
"/";
1256 mC64.ITool().intToStrDec(mC64.ITimer().getCurrentRFR(), sTmp);
1258 pFont->setPosition(PME_DEBUG_PANEL_GAMEFIELD_X, PME_DEBUG_PANEL_GAMEFIELD_Y + iMazePixelY + 80);
1259 pFont->render(sDebug);
1265Sint32 GameField::addPoints(Sint32 iP)
1267 pGlobalStatus->iPoints += iP;
1268 if(pGlobalStatus->iHighestScore < pGlobalStatus->iPoints) pGlobalStatus->iHighestScore = pGlobalStatus->iPoints;
1275Sint32 GameField::getObjectIndex(Sint32 iID)
1279 for(i = 0; i < vObjects.size(); ++i)
1281 if(vObjects[i]->getID() == iID)
return i;
1287Actor* GameField::getActor(Sint32 iID)
1289 Sint32 i = getObjectIndex(iID);
1292 return reinterpret_cast<Actor*
>(vObjects[i]);
1298Sint32 GameField::getMazeNumber()
1304template <
typename T> T** GameField::create2DArray(Sint32 height, Sint32 width)
1311 ppi =
new(std::nothrow) T*[height];
1313 pool =
new(std::nothrow) T[width * height];
1317 for(
int i = 0; i < height; i++)
1319 *(ppi + i) = curPtr;
1327template <
typename T> Sint32 GameField::delete2DArray(T** Array)