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

📄 role.cpp

📁 泡泡堂单机版(含ASL游戏引擎源码 泡泡堂单机版(含ASL游戏引擎源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "role.h"
#include "map.h"
#include "sound.h"
#include "game.h"

CRole ROLE[ROLE_NUM];

CRole::CRole(void)
: m_pState(NULL)
{
	New();
}

CRole::~CRole(void)
{
	SAFE_DELETE(m_pState);
}

ASLBitmap CRole::m_bmBigPopo;
ASLBitmap CRole::m_bmSlowTurtle;
ASLBitmap CRole::m_bmFastTurtle;
ASLBitmap CRole::m_bmOwl;
ASLBitmap CRole::m_bmFastUFO;

void CRole::LoadSharedBitmap(ASLFile *pFile)
{
	ASLIni ini;
	ASLFileLoader loader;
	ASLFile *pFilePic;
	POINT ptHot;

	ini.Load(pFile);
	ini.SetSection("Shared");
	loader.SetDirApp("Pic");

	ptHot.x = ini.SafeReadInteger("BigPopoHotX");
	ptHot.y = ini.SafeReadInteger("BigPopoHotY");
	pFilePic = loader.Load(ini.SafeReadString("BigPopo").c_str());
	m_bmBigPopo.LoadBMP(pFilePic);
	m_bmBigPopo.SetBlock(9, 1);
	m_bmBigPopo.SetColorKey(clFuchsia);
	m_bmBigPopo.SetHotspot(ptHot);

	ptHot.x = ini.SafeReadInteger("SlowTurtleHotX");
	ptHot.y = ini.SafeReadInteger("SlowTurtleHotY");
	pFilePic = loader.Load(ini.SafeReadString("SlowTurtle").c_str());
	m_bmSlowTurtle.LoadBMP(pFilePic);
	m_bmSlowTurtle.SetBlock(2, 4);
	m_bmSlowTurtle.SetColorKey(clFuchsia);
	m_bmSlowTurtle.SetHotspot(ptHot);

	ptHot.x = ini.SafeReadInteger("FastTurtleHotX");
	ptHot.y = ini.SafeReadInteger("FastTurtleHotY");
	pFilePic = loader.Load(ini.SafeReadString("FastTurtle").c_str());
	m_bmFastTurtle.LoadBMP(pFilePic);
	m_bmFastTurtle.SetBlock(2, 4);
	m_bmFastTurtle.SetColorKey(clFuchsia);
	m_bmFastTurtle.SetHotspot(ptHot);

	ptHot.x = ini.SafeReadInteger("OwlHotX");
	ptHot.y = ini.SafeReadInteger("OwlHotY");
	pFilePic = loader.Load(ini.SafeReadString("Owl").c_str());
	m_bmOwl.LoadBMP(pFilePic);
	m_bmOwl.SetBlock(2, 4);
	m_bmOwl.SetColorKey(clFuchsia);
	m_bmOwl.SetHotspot(ptHot);

	ptHot.x = ini.SafeReadInteger("FastUFOHotX");
	ptHot.y = ini.SafeReadInteger("FastUFOHotY");
	pFilePic = loader.Load(ini.SafeReadString("FastUFO").c_str());
	m_bmFastUFO.LoadBMP(pFilePic);
	m_bmFastUFO.SetBlock(2, 4);
	m_bmFastUFO.SetColorKey(clFuchsia);
	m_bmFastUFO.SetHotspot(ptHot);	
}

void CRole::Load(ASLFile *pFile)
{
	ASLIni ini;
	ASLFileLoader loader;
	POINT ptHot;
	
	ini.Load(pFile);
	ini.SetSection("Role");
	loader.SetDirApp("Pic");

	// 加载主图
	ptHot.x = ini.SafeReadInteger("MainHotX");
	ptHot.y = ini.SafeReadInteger("MainHotY");
	m_bmMain.LoadBMP(loader.Load(ini.SafeReadString("Main").c_str()));
	m_bmMain.SetBlock(6, 4);
	m_bmMain.SetHotspot(ptHot);
	m_bmMain.SetColorKey(clFuchsia);

	// 加载阴影
	ptHot.x = ini.SafeReadInteger("ShadowHotX");
	ptHot.y = ini.SafeReadInteger("ShadowHotY");
	m_bmShadow.LoadBMP(loader.Load(ini.SafeReadString("Shadow").c_str()));
	m_bmShadow.SetHotspot(ptHot);
	m_bmShadow.SetColorKey(clFuchsia);

	// 加载开始动画
	ptHot.x = ini.SafeReadInteger("StartHotX");
	ptHot.y = ini.SafeReadInteger("StartHotY");
	m_bmStart.LoadBMP(loader.Load(ini.SafeReadString("Start").c_str()));
	m_bmStart.SetBlock(10, 1);
	m_bmStart.SetHotspot(ptHot);
	m_bmStart.SetColorKey(clFuchsia);

	// 加载一般动画
	ptHot.x = ini.SafeReadInteger("AniHotX");
	ptHot.y = ini.SafeReadInteger("AniHotY");
	m_bmAni.LoadBMP(loader.Load(ini.SafeReadString("Ani").c_str()));
	m_bmAni.SetBlock(8, 1);
	m_bmAni.SetHotspot(ptHot);
	m_bmAni.SetColorKey(clFuchsia);

	// 加载死亡动画
	ptHot.x = ini.SafeReadInteger("DieHotX");
	ptHot.y = ini.SafeReadInteger("DieHotY");
	m_bmDie.LoadBMP(loader.Load(ini.SafeReadString("Die").c_str()));
	m_bmDie.SetBlock(11, 1);
	m_bmDie.SetHotspot(ptHot);
	m_bmDie.SetColorKey(clFuchsia);

	// 加载坐骑动画
	ptHot.x = ini.SafeReadInteger("RideHotX");
	ptHot.y = ini.SafeReadInteger("RideHotY");
	m_bmRide.LoadBMP(loader.Load(ini.SafeReadString("Ride").c_str()));
	m_bmRide.SetBlock(4, 1);
	m_bmRide.SetHotspot(ptHot);
	m_bmRide.SetColorKey(clFuchsia);
}

void CRole::Start(void)
{
	ChangeState(new CRoleStateStart(this));
}

void CRole::New(void)
{
	m_nCellX = 1;
	m_nCellY = 1;
	m_nOffsetX = 0;
	m_nOffsetY = 0;
	m_Direction = drDown;
	m_nPushTime = 0;
	m_bMoving = false;
	m_bFlying = false;
	m_bDead = false;

	m_Ability.nUsedPopo = 0;
	m_Ability.nPopoMax = 1;
	m_Ability.nPopoPower = 1;
	m_Ability.nSpeed = 3;
	m_Ability.bKick = false;
	m_Ability.Vehicle = vtNone;

	SAFE_DELETE(m_pState);
}

void CRole::Draw(void) const
{
	int x = (m_nCellX-1) * CELL_SIZE + SCENE_LEFT + m_nOffsetX;
	int y = m_nCellY * CELL_SIZE + SCENE_TOP + m_nOffsetY;
	
	m_pState->Draw(x, y);
}

void CRole::Update(float fDelta)
{
	m_pState->Update(fDelta);
}

void CRole::Move(Direction dir)
{
	m_bMoving = true;
	if (m_Direction != dir)
	{
		m_nPushTime = 0;
		m_Direction = dir;
	}
}

void CRole::LayPopo(void)
{
	RoleState rs = m_pState->Type();

	if ((rs == rsNormal || rs == rsIdle) && m_Ability.nUsedPopo < m_Ability.nPopoMax && 
		(MAP[m_nCellY][m_nCellX].Type == itNone || MAP[m_nCellY][m_nCellX].Type == itGift))
	{
		m_Ability.nUsedPopo++;
		
		CPopo *pPopo = (CPopo*)FACTORY.MakeFixedItem(0);
		pPopo->SetPosition(m_nCellY, m_nCellX);
		pPopo->SetPower(m_Ability.nPopoPower);
		pPopo->SetOwner(this);
		SAFE_DELETE(MAP[m_nCellY][m_nCellX].pItem);
		MAP[m_nCellY][m_nCellX].pItem = pPopo;
		MAP[m_nCellY][m_nCellX].Type = itPopo;

		SOUND.Play(snLay);
	}
}

void CRole::Win(void)
{
	ChangeState(new CRoleStateWin(this));
}

void CRole::Normal(void)
{
	RoleState rs = m_pState->Type();
	if (rs == rsNormal && m_Ability.Vehicle != vtNone || rs == rsOnRide)
	{
		ChangeState(new CRoleStateOnDismount(this));
	}
	else if (rs == rsTraped || rs == rsOnTrap)
	{
		ChangeState(new CRoleStateOnSave(this));
	}
}

//-----------------------------------------------------------------------------
// Private Functions

template <Direction dr>
CRole::WalkProperty CRole::GetWalkProperty(void)
{
	int x = m_nCellX, y = m_nCellY;

	switch (dr)
	{
	case drUp: y--; break;
	case drDown: y++; break;
	case drLeft: x--; break;
	case drRight: x++; break;
	case drUpLeft: y--; x--; break;
	case drUpRight: y--; x++; break;
	case drDownLeft: y++; x--; break;
	case drDownRight: y++; x++; break;
	}

	if (MAP[y][x].Type == itFirm || MAP[y][x].Type == itPopo)
	{
		return wpStop;
	}
	else if (MAP[y][x].Type == itSolid || MAP[y][x].Type == itBox)
	{
		return m_bFlying ? wpNone : wpStop;
	}
	else if (MAP[y][x].Type == itNone && MAP[y][x].Blind == btTent)
	{
		return wpTent;
	}
	else
	{
		return wpNone;
	}
}

template <Direction dr>
void CRole::Push(void)
{
	int x = m_nCellX, y = m_nCellY;

	switch (dr)
	{
	case drUp: y--; break;
	case drDown: y++; break;
	case drLeft: x--; break;
	case drRight: x++; break;
	case drUpLeft: y--; x--; break;
	case drUpRight: y--; x++; break;
	case drDownLeft: y++; x--; break;
	case drDownRight: y++; x++; break;
	}

	if (MAP[y][x].Type == itBox)
	{
		m_nPushTime++;
		if (m_nPushTime >= 20)
		{
			m_nPushTime = 0;
			ASSERT(MAP[y][x].pItem != NULL);
			((CBox*)MAP[y][x].pItem)->Move(dr);
		}
	}
	else if (MAP[y][x].Type == itPopo && m_Ability.bKick && !m_bFlying)
	{
		ASSERT(MAP[y][x].pItem != NULL);
		((CPopo*)MAP[y][x].pItem)->Move(dr);
	}
}

void CRole::UpdateMoveUp(int nSpeed)
{
	WalkProperty up, upleft, upright, left, right;

	up			= GetWalkProperty<drUp>();
	upleft		= GetWalkProperty<drUpLeft>();
	upright		= GetWalkProperty<drUpRight>();
	left		= GetWalkProperty<drLeft>();
	right		= GetWalkProperty<drRight>();

	if (m_nOffsetY > 0)
	{
		m_nOffsetY -= nSpeed;
		if (m_nOffsetY < 0 && up != wpNone)
		{
			m_nOffsetY = 0;
		}
	}
	else
	{
		switch (up)
		{
		case wpStop:
			if (m_nOffsetX < -10 && left == wpNone && upleft <= wpTent)
			{
				m_nOffsetX -= nSpeed;
			}
			else if (m_nOffsetX > 10 && right == wpNone && upright <= wpTent)
			{
				m_nOffsetX += nSpeed;
			}
			else
			{
				Push<drUp>();
			}
			break;

		case wpTent:
			if (m_nOffsetX == 0)
			{
				m_nOffsetY -= nSpeed;
			}
			else if (m_nOffsetX < 0)
			{
				m_nOffsetX = min(m_nOffsetX + nSpeed, 0);
			}
			else if (m_nOffsetX > 0)
			{
				m_nOffsetX = max(m_nOffsetX - nSpeed, 0);
			}
			break;

		case wpNone:
			if (m_nOffsetX < 0 && upleft == wpNone ||
				m_nOffsetX > 0 && upright == wpNone ||
				m_nOffsetX == 0)
			{
				m_nOffsetY -= nSpeed;
			}
			else if (m_nOffsetX < 0 && upleft != wpNone)
			{
				m_nOffsetX = min(m_nOffsetX + nSpeed, 0);
			}
			else if (m_nOffsetX > 0 && upright != wpNone)
			{
				m_nOffsetX = max(m_nOffsetX - nSpeed, 0);
			}
		}
	}

	AdjustCell();	
}

void CRole::UpdateMoveDown(int nSpeed)
{
	WalkProperty down, downleft, downright, left, right;

	down		= GetWalkProperty<drDown>();
	downleft	= GetWalkProperty<drDownLeft>();
	downright	= GetWalkProperty<drDownRight>();
	left		= GetWalkProperty<drLeft>();
	right		= GetWalkProperty<drRight>();

	if (m_nOffsetY < 0)
	{
		m_nOffsetY += nSpeed;
		if (m_nOffsetY > 0 && down != wpNone)
		{
			m_nOffsetY = 0;
		}
	}
	else
	{		
		switch (down)
		{
		case wpStop:
			if (m_nOffsetX < -10 && left == wpNone && downleft <= wpTent)
			{
				m_nOffsetX -= nSpeed;
			}
			else if (m_nOffsetX > 10 && right == wpNone && downright <= wpTent)
			{
				m_nOffsetX += nSpeed;
			}
			else
			{
				Push<drDown>();
			}
			break;

		case wpTent:
			if (m_nOffsetX == 0)
			{
				m_nOffsetY += nSpeed;
			}
			else if (m_nOffsetX < 0)
			{
				m_nOffsetX = min(m_nOffsetX + nSpeed, 0);
			}
			else if (m_nOffsetX > 0)
			{
				m_nOffsetX = max(m_nOffsetX - nSpeed, 0);
			}
			break;
		
		case wpNone:
			if (m_nOffsetX < 0 && downleft == wpNone ||
				m_nOffsetX > 0 && downright == wpNone ||
				m_nOffsetX == 0)
			{
				m_nOffsetY += nSpeed;
			}
			else if (m_nOffsetX < 0 && downleft != wpNone)
			{
				m_nOffsetX = min(m_nOffsetX + nSpeed, 0);
			}
			else if (m_nOffsetX > 0 && downright != wpNone)
			{
				m_nOffsetX = max(m_nOffsetX - nSpeed, 0);
			}
		}
	}

	AdjustCell();
}

void CRole::UpdateMoveLeft(int nSpeed)
{
	WalkProperty left, downleft, upleft, down, up;
	left		= GetWalkProperty<drLeft>();
	downleft	= GetWalkProperty<drDownLeft>();
	upleft		= GetWalkProperty<drUpLeft>();
	down		= GetWalkProperty<drDown>();
	up			= GetWalkProperty<drUp>();

	if (m_nOffsetX > 0)
	{
		m_nOffsetX -= nSpeed;
		if (m_nOffsetX < 0 && left != wpNone)
		{
			m_nOffsetX = 0;
		}
	}
	else if (MAP[m_nCellY][m_nCellX].Blind != btTent)
	{
		if (left != wpNone)
		{
			if (m_nOffsetY < -10 && up == wpNone && upleft <= wpTent)
			{
				m_nOffsetY -= nSpeed;
			}
			else if (m_nOffsetY > 10 && down == wpNone && downleft <= wpTent)
			{
				m_nOffsetY += nSpeed;
			}
			else
			{
				Push<drLeft>();
			}
		}
		else
		{			
			if (m_nOffsetY < 0 && (upleft != wpNone || up == wpTent))
			{
				m_nOffsetY = min(m_nOffsetY + nSpeed, 0);
			}
			else if (m_nOffsetY > 0 && (downleft != wpNone || down == wpTent))
			{
				m_nOffsetY = max(m_nOffsetY - nSpeed, 0);
			}
			else if (m_nOffsetY < 0 && upleft == wpNone ||
				m_nOffsetY > 0 && downleft == wpNone ||
				m_nOffsetY == 0)
			{
				m_nOffsetX -= nSpeed;
			}
		}
	}

	AdjustCell();
}

void CRole::UpdateMoveRight(int nSpeed)
{
	WalkProperty right, downright, upright, down, up;

	right		= GetWalkProperty<drRight>();
	downright	= GetWalkProperty<drDownRight>();
	upright		= GetWalkProperty<drUpRight>();
	down		= GetWalkProperty<drDown>();
	up			= GetWalkProperty<drUp>();

	if (m_nOffsetX < 0)
	{
		m_nOffsetX += nSpeed;
		if (m_nOffsetX > 0 && right != wpNone)
		{
			m_nOffsetX = 0;
		}
	}
	else if (MAP[m_nCellY][m_nCellX].Blind != btTent)
	{
		if (right != wpNone)
		{
			if (m_nOffsetY < -10 && up == wpNone && upright <= wpTent)
			{
				m_nOffsetY -= nSpeed;
			}
			else if (m_nOffsetY > 10 && down == wpNone && downright <= wpTent)
			{
				m_nOffsetY += nSpeed;
			}
			else
			{
				Push<drRight>();
			}
		}
		else
		{			
			if (m_nOffsetY < 0 && (upright != wpNone || up == wpTent))
			{
				m_nOffsetY = min(m_nOffsetY + nSpeed, 0);
			}
			else if (m_nOffsetY > 0 && (downright != wpNone || down == wpTent))
			{
				m_nOffsetY = max(m_nOffsetY - nSpeed, 0);
			}
			else if (m_nOffsetY < 0 && upright == wpNone ||
				m_nOffsetY > 0 && downright == wpNone ||
				m_nOffsetY == 0)
			{
				m_nOffsetX += nSpeed;
			}
		}
	}

	AdjustCell();
}

void CRole::AdjustCell(void)
{
	if (m_nOffsetX < -CELL_SIZE/2)
	{
		m_nCellX--;
		m_nOffsetX += CELL_SIZE;
	}
	else if (m_nOffsetX > CELL_SIZE/2)
	{
		m_nCellX++;
		m_nOffsetX -= CELL_SIZE;
	}
	else if (m_nOffsetY < -CELL_SIZE/2)
	{
		m_nCellY--;
		m_nOffsetY += CELL_SIZE;
	}
	else if (m_nOffsetY > CELL_SIZE/2)
	{
		m_nCellY++;
		m_nOffsetY -= CELL_SIZE;		
	}
	else
	{
		return;
	}
	
	EnterNewCell();
}

void CRole::EnterNewCell(void)
{
	// 草丛摆动
	if (MAP[m_nCellY][m_nCellX].Blind >= btBush)
	{
		MAP[m_nCellY][m_nCellX].pBlindage->Waggle();
	}
}

void CRole::ChangeState(CRoleState *pState)
{
	SAFE_DELETE(m_pState);
	m_pState = pState;
}


//-----------------------------------------------------------------------------
// 状态类实现
//-----------------------------------------------------------------------------
void CRoleState::CheckChange(void)
{
	Cell *pCell = &MAP[m_pRole->m_nCellY][m_pRole->m_nCellX];

	if (pCell->Type == itGift && !m_pRole->m_bFlying)
	{
		ASSERT(pCell->pItem != NULL);

		SOUND.Play(snGet);

		const Ability ab = ((CGift*)pCell->pItem)->GetAbility();
		SAFE_DELETE(pCell->pItem);
		pCell->Type = itNone;
		
		Ability &abRole = m_pRole->m_Ability;
		abRole.nPopoMax += ab.nPopoMax;
		abRole.nPopoPower = min(abRole.nPopoPower + ab.nPopoPower, MAX_POWER);
		abRole.nSpeed = min(abRole.nSpeed + ab.nSpeed, MAX_SPEED);
		abRole.bKick = abRole.bKick || ab.bKick;
		if (abRole.Vehicle == vtNone && ab.Vehicle != vtNone)
		{
			abRole.Vehicle = ab.Vehicle;
			m_pRole->m_nOffsetX = 0;
			m_pRole->m_nOffsetY = 0;
			if (ab.Vehicle == vtFastUFO || ab.Vehicle == vtSlowUFO)
			{
				m_pRole->m_bFlying = true;
			}
			ChangeState(new CRoleStateOnRide(m_pRole));
			return;
		}
	}

	if (pCell->Explosion.Status != 0)
	{
		if (m_pRole->m_Ability.Vehicle == vtNone)
		{

⌨️ 快捷键说明

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