/
trilirium
/
Pacman
Обзор
Документация
Войти
/
trilirium
/
Pacman
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
RedGhost.cpp
179 строк
5 KB
Trilirium
first commit
19 июн 2026, 11:07
19 июн 2026, 11:07
d44591e
Код
Авторство
О чём код?
// RedGhost.cpp // ///////////////////////////////////////////////////////////////////////////// #include "RedGhost.h" #include "Difficulty.h" #include "Game.h" #include "GameState.h" #include "GhostMoveAtHomeActions.h" #include "GhostMoveWhenKilledActions.h" #include "../Operations.h" #include "Pacman.h" #include "Path.h" #include "Video.h" using namespace Puckman; ///////////////////////////////////////////////////////////////////////////// // initialization and cleanup ///////////////////////////////////////////////////////////////////////////// RedGhost::RedGhost() : Ghost(RED) { resetState(); // fills the actions arrays moveAtHomeAction = new GhostAction*[2]; moveAtHomeAction[0] = new GhostExitHomeAction(); moveAtHomeAction[1] = new GhostNopAction(); moveWhenKilledAction = new GhostAction*[3]; moveWhenKilledAction[0] = new GhostNopAction(); moveWhenKilledAction[1] = new GhostGoHomeAction(); moveWhenKilledAction[2] = new GhostEnterHomeAndEndAction(); } RedGhost::~RedGhost() { // deallocates the actions arrays for (int i = 0; i < 2; i++){ delete moveAtHomeAction[i]; } delete[] moveAtHomeAction; for (int i = 0; i < 3; i++){ delete moveWhenKilledAction[i]; } delete[] moveWhenKilledAction; } void RedGhost::resetState() { Ghost::resetState(); movDiffFlag1Pattern = movDiffFlag2Pattern = 0; } void RedGhost::initState(bool special) { Ghost::initState(special); if (!special){ posX = 0x80; posY = 0x64; tilePosX = actualTilePosX = 0x2e; tilePosY = actualTilePosY = 0x2c; movOffsX = prevMovOffsX = 1; movOffsY = prevMovOffsY = 0; orientation = prevOrientation = LEFT; } } ///////////////////////////////////////////////////////////////////////////// // red ghost AI ///////////////////////////////////////////////////////////////////////////// void RedGhost::run() { // if it's going for pacman and alive if ((substate != 0) && (state == 0)){ // check if we have to set the difficulty flags theGame->updateDifficultyFlags(); // check if we have to move // 0x1b is set at the tunnels if (theGame->CRAM[Video::tilePos2ScreenCoord(actualTilePosX, actualTilePosY)] == 0x1b) { // check if we have to move according to the movement bit pattern movTunnelPattern = Operations::rotateLeft<UINT32, 32>(movTunnelPattern); if ((movTunnelPattern & 0x01) == 0) return; } else if (panicMode){ // check if we have to move according to the movement bit pattern movPanicPattern = Operations::rotateLeft<UINT32, 32>(movPanicPattern); if ((movPanicPattern & 0x01) == 0) return; } else if (theGame->secondDiffFlag){ // check if we have to move according to the movement bit pattern movDiffFlag2Pattern = Operations::rotateLeft<UINT32, 32>(movDiffFlag2Pattern); if ((movDiffFlag2Pattern & 0x01) == 0) return; } else if (theGame->firstDiffFlag){ // check if we have to move according to the movement bit pattern movDiffFlag1Pattern = Operations::rotateLeft<UINT32, 32>(movDiffFlag1Pattern); if ((movDiffFlag1Pattern & 0x01) == 0) return; } else { // check if we have to move according to the movement bit pattern movNormalPattern = Operations::rotateLeft<UINT32, 32>(movNormalPattern); if ((movNormalPattern & 0x01) == 0) return; } // move move(); } } void RedGhost::moveInNormalState() { // in odd orientation changes indexes, when first difficulty flag is set, // or if we are in demo mode, try to go to pacman position if (((theGame->indexOrientationChanges & 0x01) == 0x01) || (theGame->firstDiffFlag) || (theGame->states[PLAYING]->substate != 3)){ destTilePosX = theGame->pacman->tilePosX; destTilePosY = theGame->pacman->tilePosY; Path::calcPath(tilePosX, tilePosY, orientation, destTilePosX, destTilePosY, movOffsX, movOffsY, orientation); } else { // searchs the best direction to choose to go to the upper left corner destTilePosX = 0x20; destTilePosY = 0x20; Path::calcPath(tilePosX, tilePosY, orientation, 0x22, 0x1d, movOffsX, movOffsY, orientation); } } ///////////////////////////////////////////////////////////////////////////// // animation ///////////////////////////////////////////////////////////////////////////// void RedGhost::selectProperAnimation() { // in the second cutscene, change ghost animation if necessary if (theGame->cutsceneState[1] >= 0x0a){ color = 0x1d; sprite = (theGame->cutsceneState[1] >= 0x0c) ? 0x33 : 0x32; } else if (theGame->cutsceneState[2] >= 1){ // change ghost animation in the third cutscene if (theGame->cutsceneState[2] >= 3){ // set "naked" ghost sprite number sprite = 0x0c + ((posX >> 3) & 0x01); } else { // set "fixed" ghost sprite number sprite = 0x08 + theGame->ghostsAnimationFrame; } } else { Ghost::selectProperAnimation(); } } void RedGhost::draw() { // if we're in third cutscene, draw naked ghost if (theGame->cutsceneState[2] >= 3){ // draw ghost's sprites Sprite spr1(posX, posY, sprite, color); Sprite spr2(posX - 8, posY, sprite - 2, 0x1e); theGame->sprites.push_back(spr1); theGame->sprites.push_back(spr2); // clear sprite attributes flipX = flipY = false; priority = 0; } else { Ghost::draw(); } }