⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 redghost.cpp

📁 VIGASOCO (VIdeo GAmes SOurce COde) Windows port (v0.01)
💻 CPP
字号:
// 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"

/////////////////////////////////////////////////////////////////////////////
// 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();
	}
}

⌨️ 快捷键说明

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