playingsubstates.cpp

来自「VIGASOCO (VIdeo GAmes SOurce COde) Windo」· C++ 代码 · 共 343 行

CPP
343 行
字号
// 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"


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;
			}
		}
	}
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?