?? role.cpp
字號:
#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;
}
//-----------------------------------------------------------------------------
// 狀態(tài)類實現(xiàn)
//-----------------------------------------------------------------------------
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)
{
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -