📄 level.cpp
字号:
{
iBlinkInterval -= aFrametime;
if (iBlinkInterval < 0.0)
{
iBlinkInterval = KBacklightBlinkInterval;
iBlinkCount--;
if ((iBlinkCount & 1) == 0)
{
iBackLight->SetLightOn(PRIMARY_DISPLAY, 0);
}
else
{
iBackLight->SetLightOff(PRIMARY_DISPLAY, 0);
}
}
}
switch (iLevelState)
{
case ELevelStateRunning:
UpdateGame(aFrametime);
break;
case ELevelStateStarting:
iPlayer->SetMaxSpeed(0.0);
if (iStateTimer > KLevelStartDisplayTime && iStateTimer < KLevelStartDisplayTime + 1.0)
{
iApp.DrawTextToBitmap( iTextBuffer,
iTextBufferContext,
KTextGameGo,
iApp.BigFont(),
KRgbRed);
iStateTimer = KLevelStartDisplayTime + 1.0;
iLevelState = ELevelStateRunning;
}
break;
case ELevelStateComplete:
{
iPlayer->SetMaxSpeed(0.0);
iPlayer->SetScrollSpeed(10.0);
const TReal64 moneytransfer = iRemainingMoney / KLevelCompleteDisplayTime * aFrametime;
iTotalMoney += moneytransfer;
iTempRemainingMoney -= moneytransfer;
UpdateInfoAreaText(iTempRemainingMoney, iTotalMoney);
if (iStateTimer >= KLevelCompleteDisplayTime)
{
// start next level
iApp.StopAudio(KAudioFileMove);
iApp.StopAudio(KAudioFileWater1);
iApp.StopAudio(KAudioFileGhost);
return EAppUpdateStateInitGame;
}
}
break;
case ELevelStateGameOver:
iPlayer->SetMaxSpeed(0.0);
if (iStateTimer >= KGameOverDisplayTime)
{
// check if player got new high score
CHighScores* scores = iApp.HighScores();
THighScoreItem item;
item.iScore = iTotalMoney;
iApp.StopAudio(KAudioFileMove);
iApp.StopAudio(KAudioFileWater1);
iApp.StopAudio(KAudioFileGhost);
if (scores->Add(item, EFalse) >= 0)
{
// new high score archieved
iApp.SetLastGameScore(iTotalMoney);
return EAppUpdateStateInitNewHighScore;
}
else
{
return EAppUpdateStateInitMenu;
}
}
break;
};
return EAppUpdateStateContinue;
}
void CLevel::UpdateGame(TReal64 aFrametime)
{
TInt i;
// update current bonus timer
if (iCurrentBonus)
{
iBonusTimer -= aFrametime;
if (iBonusTimer <= 0.0)
{
// bonus has run out of time
iCurrentBonus = 0;
}
}
// update enemies
for (i=0; i<iGhosts.Count(); i++)
{
CSpriteBase* sprite = iGhosts[i];
sprite->Update(aFrametime);
}
// check if player hits the bonuses
TPoint playerblock = SpriteBlock(*iPlayer);
for (i=0; i<iBonuses.Count(); i++)
{
CSpriteBase* bonus = iBonuses[i];
TPoint bonusblock = SpriteBlock(*bonus);
if ( playerblock.iX == bonusblock.iX &&
playerblock.iY == bonusblock.iY)
{
iApp.RePlayAudio(KAudioFileBonus);
if (bonus->Id() == KBitmapBonusMoney)
{
// player got some more money
// add 100 bucks
iRemainingMoney += 100.0;
}
else if (bonus->Id() == KBitmapBonusPower)
{
iCurrentBonus = KBitmapBonusPower;
iBonusTimer = 20.0;
}
else if (bonus->Id() == KBitmapBonusWater)
{
iCurrentBonus = KBitmapBonusWater;
iBonusTimer = 20.0;
}
iBonuses.Remove(i);
break;
}
}
// check player block
TInt movesoundvolume = TInt(iPlayer->MovementSpeed() * 0.2);
if (movesoundvolume > 10)
{
movesoundvolume = 10;
}
TInt blockid = iBlocks[playerblock.iY * iMapWidth + playerblock.iX].iID;
if (blockid == KMapBlockGrass)
{
// slow down on grass
iPlayer->SetMaxSpeed(30.0);
iPlayer->SetScrollSpeed(10.0);
iApp.SetAudioVolume(KAudioFileMove, movesoundvolume);
iApp.SetAudioVolume(KAudioFileWater1, 0);
}
else if (blockid == KMapBlockWater)
{
iApp.PlayAudio(KAudioFileWater2);
iApp.SetAudioVolume(KAudioFileMove, 0);
iApp.SetAudioVolume(KAudioFileWater1, movesoundvolume);
if (iCurrentBonus != KBitmapBonusWater)
{
BlinkBacklight();
// player is in water, losing money FAST
iRemainingMoney -= 300.0 * aFrametime;
if (iRemainingMoney < 0.0)
{
iRemainingMoney = 0.0;
}
iPlayer->SetMaxSpeed(10.0);
iPlayer->SetScrollSpeed(10.0);
}
}
else if (blockid == KMapBlockTree01 ||
blockid == KMapBlockTree02)
{
iPlayer->SetMaxSpeed(10.0);
iPlayer->SetScrollSpeed(10.0);
}
else
{
// normal gravel block
iPlayer->SetMaxSpeed(200.0);
iPlayer->SetScrollSpeed(1.0);
iApp.SetAudioVolume(KAudioFileMove, movesoundvolume);
iApp.SetAudioVolume(KAudioFileWater1, 0);
}
// check if player has reached the goal
if (playerblock.iX == iGoalBlock.iX && playerblock.iY == iGoalBlock.iY)
{
iApp.PlayAudio(KAudioFileLevelComplete);
iStateTimer = 0.0;
iApp.DrawTextToBitmap( iTextBuffer,
iTextBufferContext,
KTextGameLevelComplete,
iApp.BigFont(),
KRgbWhite);
iTempRemainingMoney = iRemainingMoney;
iLevelState = ELevelStateComplete;
}
// check if player hits the ghosts (if power bonus is not active)
if (iCurrentBonus != KBitmapBonusPower)
{
for (i=0; i<iGhosts.Count(); i++)
{
CSpriteBase* ghost = iGhosts[i];
if (ghost->IsVisible(iCamera))
{
if (ghost->Collision(*iPlayer))
{
BlinkBacklight();
iApp.PlayAudio(KAudioFileGhost, EFalse);
iRemainingMoney -= 50.0 * aFrametime; // ghost stole 10 bucks
if (iRemainingMoney < 0.0)
{
iRemainingMoney = 0.0;
}
break;
}
}
}
}
// decrease amount of money left
iRemainingMoney -= iMoneyWasteSpeed * aFrametime;
if (iRemainingMoney <= 0.0)
{
iRemainingMoney = 0.0;
// out of money, game over
iApp.PlayAudio(KAudioFileFail);
iLevelState = ELevelStateGameOver;
iStateTimer = 0.0;
iApp.DrawTextToBitmap( iTextBuffer,
iTextBufferContext,
KTextGameOver,
iApp.BigFont(),
KRgbRed);
}
}
void CLevel::UpdateInfoAreaText(const TReal64 aLevelMoney,
const TReal64 aTotalMoney)
{
TBuf<128> msg;
msg.Format(KTextGameMoney, aLevelMoney, aTotalMoney);
iApp.SetInfoAreaText(msg, EFalse);
}
void CLevel::Draw(IGraphicsContext& aContext)
{
// draw the blockmap
TInt i, j, tmp;
TMapBlock *block;
TInt startY, startX, toY, toX;
startX = (TInt)iCamera.iX / KMapBlockWidth;
startY = (TInt)iCamera.iY / KMapBlockHeight;
toX = startX + (iBackBufferSize.iWidth / KMapBlockWidth) + 2;
toY = startY + (iBackBufferSize.iHeight / KMapBlockWidth) + 2;
if (startX < 0)
{
startX = 0;
}
if (startY < 0)
{
startY = 0;
}
if (toX > iMapWidth)
{
toX = iMapWidth;
}
if (toY > iMapHeight)
{
toY = iMapHeight;
}
TInt waterframeindex = KBitmapBlock2 + (TInt)iWaterAnimationPhase;
IBitmap* waterframe = iApp.Bitmap(waterframeindex);
if ((TInt)(startY * KMapBlockHeight - iCamera.iY) > 0)
{
// map area is not filling the entire screen
aContext.Clear(0x00005500);
}
for (i=startY; i<toY; i++)
{
tmp = i * iMapWidth;
for (j=startX; j<toX; j++)
{
block = &iBlocks[tmp + j];
// draw block
if (block->iBitmap)
{
CPoint pos( (TInt)(j * KMapBlockWidth - iCamera.iX),
(TInt)(i * KMapBlockHeight - iCamera.iY) );
if (block->iID == 2)
{
// animated water block
waterframe->Lock();
aContext.BitBlit( pos,
*waterframe);
waterframe->Unlock();
}
else
{
// non animated block
block->iBitmap->Lock();
aContext.BitBlit( pos,
*block->iBitmap);
block->iBitmap->Unlock();
}
}
}
}
// draw bonuses
for (i=0; i<iBonuses.Count(); i++)
{
CSpriteBase* sprite = iBonuses[i];
if (sprite->IsVisible(iCamera))
{
sprite->Draw(aContext, iCamera);
}
}
// draw array of sprites
if (iSettings->iGraphicsDetail > 2)
{
for (i=0; i<iSprites.Count(); i++)
{
CSpriteBase* sprite = iSprites[i];
if (sprite->IsVisible(iCamera))
{
sprite->Draw(aContext, iCamera);
}
}
}
// draw player & ghosts
iPlayer->Draw(aContext, iCamera);
// draw array of ghosts
for (i=0; i<iGhosts.Count(); i++)
{
CSpriteBase* sprite = iGhosts[i];
if (sprite->IsVisible(iCamera))
{
sprite->Draw(aContext, iCamera);
}
}
if (iSettings->iGraphicsDetail > 2)
{
for (i=0; i<iTrees.Count(); i++)
{
CSpriteBase* sprite = iTrees[i];
if (sprite->IsVisible(iCamera))
{
sprite->Draw(aContext, iCamera);
}
}
}
// draw radar
DrawRadar(TRect(10, 10, 74, 74));
// draw current bonus indicator
if (iCurrentBonus)
{
IBitmap* bonusbitmap = NULL;
switch (iCurrentBonus)
{
case KBitmapBonusPower:
bonusbitmap = iApp.Bitmap(KBitmapBonusPower);
break;
case KBitmapBonusWater:
bonusbitmap = iApp.Bitmap(KBitmapBonusWater);
break;
}
TInt blink = (TInt)(iBonusTimer * 5.0);
if (bonusbitmap && (blink & 1))
{
CSize bmsize = bonusbitmap->GetSize();
bonusbitmap->Lock();
CPoint pos;
pos.mX = iBackBufferSize.iWidth - bmsize.mX - 10;
pos.mY = 10;
aContext.BitBlitTransparent(pos, *bonusbitmap, 0);
bonusbitmap->Unlock();
}
}
// draw texts
if ( iLevelState == ELevelStateStarting ||
iLevelState == ELevelStateGameOver ||
iLevelState == ELevelStateComplete ||
(iLevelState == ELevelStateRunning && iStateTimer < KLevelStartDisplayTime + 2.0))
{
// draw text buffer
ReturnCode ret;
CSize textbuffersize = iTextBuffer->GetSize();
CPoint center;
center.mX = ((iBackBufferSize.iWidth >> 1) - (textbuffersize.mX >> 1));
center.mY = ((iBackBufferSize.iHeight >> 1) - (textbuffersize.mY >> 1));
ret = iTextBuffer->Lock();
if ( ret == OK )
{
ret = aContext.BitBlitTransparent( center,
*iTextBuffer,
0);
ret = iTextBuffer->Unlock();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -