/
trilirium
/
Pacman
Обзор
Документация
Войти
/
trilirium
/
Pacman
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
PlayingSubstates.cpp
343 строки
9 KB
Trilirium
first commit
19 июн 2026, 11:07
19 июн 2026, 11:07
d44591e
Код
Авторство
О чём код?
// PlayingSubstates.cpp // ///////////////////////////////////////////////////////////////////////////// #include "PlayingSubstates.h" #include "PlayingState.h" #include "Difficulty.h" #include "Game.h" #include "Ghost.h" #include "../InputHandler.h" #include "Video.h" #include "Writer.h" using namespace Puckman; void PlayingInitPlayerLevelDataSubstate::run() { theGame->initPlayersLevelData(); // increment substate theGame->states[PLAYING]->substate++; } void PlayingInitRemainingDataSubstate::run() { // if we're in demo, change to substate 9 if (theGame->state == DEMO){ theGame->states[PLAYING]->substate = 9; } else { // clears game state theGame->initGameState(); // removes player one string and restores CRAM data Writer::printString(0x83); Video::restorePlayerTextCRAM(); // init pacman and ghosts positions, tile positions, orientation vars and sprite data theGame->initCharacterState(false); // init ghost movement inside home counter and set red ghost to go for pacman theGame->cntGhostsMovHome = 0x55; theGame->ghost[RED]->substate = 1; // set difficulty settings according to the current settings Difficulty::setDifficultySettings(0); Video::drawLevelFruits(); // init lives CRAM and display lives Video::initLivesCRAM(); Video::drawLives(theGame->levelState[0].displayedLives); // schedules a substate change in two seconds theScheduler->addScheduledTask(new Task(0, Task::TEN_HUNDREDTHS, 20)); // removes ready message in two seconds theScheduler->addScheduledTask(new Task(6, Task::TEN_HUNDREDTHS, 20)); // increment substate theGame->states[PLAYING]->substate++; } } void PlayingInitLevelAndDifficultySubstate::run() { // clear gameplay area and init CRAM with special values Video::clearVRAM(true); Video::initCRAM(1); // draw the game level Video::drawGameLevel(); // clears game state theGame->initGameState(); // clear level pills (why???) Video::clearLevelPills(); // draw active player pills Video::drawPlayerPills(); // init positions, tile positions, orientation vars and sprite data theGame->initCharacterState(false); // init ghost movement inside home counter and set red ghost to go for pacman theGame->cntGhostsMovHome = 0x55; theGame->ghost[RED]->substate = 1; // set difficulty settings according to the current settings Difficulty::setDifficultySettings(0); Video::drawLevelFruits(); // writes ready string Writer::printString(6); // schedules a substate change in two seconds theScheduler->addScheduledTask(new Task(0, Task::TEN_HUNDREDTHS, 20)); // if we're not playing, print actual credit configuration and overwrite ready with game over if (theGame->state != PLAYING){ Writer::printString(5); Writer::printCredits(); } else { // init lives CRAM and display lives Video::initLivesCRAM(); Video::drawLives(theGame->levelState[0].displayedLives); // removes ready message in two seconds theScheduler->addScheduledTask(new Task(6, Task::TEN_HUNDREDTHS, 20)); } // increments substate theGame->states[PLAYING]->substate++; } // change to demo mode void PlayingInitDemoSubstate::run() { theGame->states[DEMO]->substate = 0; theGame->states[PLAYING]->substate = 0; theGame->numberOfPlayers = 0; theGame->currentPlayer = 1; theGame->state = DEMO; } void PlayingContinueLevelSubstate::run() { theGame->states[PLAYING]->substate = 3; } void PlayingInitCutsceneSubstate::run() { // clear gameplay area and CRAM Video::clearVRAM(true); Video::clearCRAM(); // clears game state theGame->initGameState(); // clear level pills Video::clearLevelPills(); // init positions, tile positions, orientation vars and sprite data theGame->initCharacterState(true); // init ghost movement inside home counter theGame->cntGhostsMovHome = 0x55; // set difficulty settings for cutscene Difficulty::setDifficultySettings(0x13); Video::drawLevelFruits(); // schedules a substate change in 0.3 seconds theScheduler->addScheduledTask(new Task(0, Task::TEN_HUNDREDTHS, 3)); // increments substate theGame->states[PLAYING]->substate++; } void PlayingStopSoundAndWaitSubstate::run() { Task *t = new Task(0, Task::TEN_HUNDREDTHS, 20); // schedules a substate change in two seconds theScheduler->addScheduledTask(t); // increments level state theGame->states[PLAYING]->substate++; // TODOSOUND: stop sound } void PlayingCutsceneSubstate::run() { // TODOSOUND: stop and start sound int index = theGame->levelState[0].currentLevel; if (index > 0x14) index = 0x14; // execute cutscene ((PlayingState *)theGame->states[PLAYING])->cutScene[index]->run(); } void PlayingPrepareNextLevelDataSubstate::run() { // TODOSOUND: stop sound // clear level flags and counters theGame->levelState[0].firstFruit = false; theGame->levelState[0].secondFruit = false; theGame->levelState[0].eatenPills = 0; theGame->levelState[0].pinkGhostHomeCounter = 0; theGame->levelState[0].blueGhostHomeCounter = 0; theGame->levelState[0].orangeGhostHomeCounter = 0; theGame->levelState[0].easierFlag = false; // init pills theGame->levelState[0].initPills(); // increments level state theGame->states[PLAYING]->substate++; // increments level and difficulty theGame->levelState[0].currentLevel++; if (theGame->levelState[0].diffEntry != 20){ theGame->levelState[0].diffEntry++; } } void PlayingChangeCRAMSubstate::run() { Video::initCRAM(2); // schedules a substate change in 0.2 seconds theScheduler->addScheduledTask(new Task(0, Task::TEN_HUNDREDTHS, 2)); // reset ghosts positions for (int i = 0; i < 4; i++){ theGame->ghost[i]->posX = theGame->ghost[i]->posY = 0; } theGame->states[PLAYING]->substate++; } void PlayingRestoreCRAMSubstate::run() { Video::initCRAM(0); // schedules a substate change in 0.2 seconds theScheduler->addScheduledTask(new Task(0, Task::TEN_HUNDREDTHS, 2)); theGame->states[PLAYING]->substate++; } void PlayingMainGameLoopSubstate::run() { // if rack test is set, finish the level if ((theInputHandler->getInput(0) & 0x10) == 0){ theGame->states[PLAYING]->substate = 0x0e; Video::clearLevelPills(); return; } // if pacman has eaten all the pills, finish the level, otherwise keep simulating if (theGame->levelState[0].eatenPills == 0xf4){ theGame->states[PLAYING]->substate = 0x0c; } else { // main game loop // handle collisions theGame->moveAndHandleCollisions(); theGame->moveAndHandleCollisions(); // if there's too much inactivity, make ghosts go out of home theGame->checkGhostsExitHomeInactivity(); // update ghosts theGame->moveGhostAtHome(); theGame->updateGhostAnimCounters(); theGame->checkForOrienationChange(); theGame->setGhostsColors(); theGame->setDeadGhostsColor(); // change big pill state if necessary theGame->updateSuperPillState(); // TODOSOUND: modifies the sound of the channel depending of the remaining pills theGame->checkDisplayFruit(); } } void PlayingPacmanDeadSubstate::run() { theGame->levelState[0].easierFlag = true; // save pills configuration theGame->savePillsConfiguration(); theGame->states[PLAYING]->substate++; if ((theGame->levelState[0].lives > 0) || (theGame->numberOfPlayers == 0) || (theGame->levelState[1].lives == 0)){ theGame->states[PLAYING]->substate++; } else { // the game arrives here if the active player has died while the other is alive // print player one or two game over Writer::printString(0x03 + theGame->currentPlayer); Writer::printString(0x05); // schedules a substate change in two seconds theScheduler->addScheduledTask(new Task(0, Task::TEN_HUNDREDTHS, 20)); } } void PlayingCheckForGameOverSubstate::run() { bool gameOver = false; // if it's a 1 player game and we've run out of lives, game over if (theGame->numberOfPlayers == 0){ if (theGame->levelState[0].lives == 0){ // print game over and actual credit configuration Writer::printCredits(); Writer::printString(0x05); // schedules a substate change in two seconds theScheduler->addScheduledTask(new Task(0, Task::TEN_HUNDREDTHS, 20)); // change substate theGame->states[PLAYING]->substate++; } else { // change substate theGame->states[PLAYING]->substate = 9; } } else { // if it's a 2 player game the other player has lives if (theGame->levelState[1].lives != 0){ // swap players theGame->levelState[0].swapState(&theGame->levelState[1]); theGame->currentPlayer = theGame->currentPlayer ^ 1; // change substate theGame->states[PLAYING]->substate = 9; } else { if (theGame->levelState[0].lives == 0){ // print game over and actual credit configuration Writer::printCredits(); Writer::printString(0x05); // schedules a substate change in two seconds theScheduler->addScheduledTask(new Task(0, Task::TEN_HUNDREDTHS, 20)); // change substate theGame->states[PLAYING]->substate++; } else { // change substate theGame->states[PLAYING]->substate = 9; } } } }