📄 level.cpp
字号:
#include "Level.h"
#include "LevelParser.h"
#include "Player.h"
#include "Ghost.h"
const TInt KMapBlockWidth = 64;
const TInt KMapBlockHeight = 64;
const TReal64 KLevelStartDisplayTime = 1.0;
const TReal64 KLevelCompleteDisplayTime = 3.0;
const TReal64 KGameOverDisplayTime = 3.0;
const TReal64 KBacklightBlinkInterval = 0.05;
CLevel::CLevel(CExampleApplication& aApp)
: iApp(aApp),
iSettings(aApp.Settings())
{
}
CLevel::~CLevel()
{
// delete sprite arrays
DeleteSpriteArray(iSprites);
DeleteSpriteArray(iGhosts);
DeleteSpriteArray(iBonuses);
DeleteSpriteArray(iTrees);
if (iPlayer)
{
delete iPlayer;
iPlayer = NULL;
}
ReleaseTreeLayers(iTree01Layers);
ReleaseTreeLayers(iTree02Layers);
iApp.ReleaseBitmapAndContext(iTextBuffer, iTextBufferContext);
if (iLevelName)
{
delete iLevelName;
iLevelName = NULL;
}
if (iBlocks)
{
delete [] iBlocks;
iBlocks = NULL;
}
if (iBackLight)
{
iBackLight->Release();
iBackLight = NULL;
}
}
void CLevel::DeleteSpriteArray(RArray<CSpriteBase*>& aArray)
{
TInt i;
for (i=0; i<aArray.Count(); i++)
{
delete aArray[i];
}
aArray.Reset();
aArray.Close();
}
TInt CLevel::Init(const TDesC& aFilename, TReal64 aTotalMoney)
{
iTotalMoney = aTotalMoney;
iBackBufferSize = iApp.BackBufferSize();
TInt error;
// create tree image layers
CreateTreeLayers( 7,
iApp.Bitmap(KBitmapTree1),
iApp.Mask(KBitmapTree1),
100.0,
&iTree01Layers);
CreateTreeLayers( 4,
iApp.Bitmap(KBitmapTree2),
iApp.Mask(KBitmapTree2),
30.0,
&iTree02Layers);
CLevelParser* parser = new (ELeave) CLevelParser;
error = parser->Init(aFilename);
if (error != KErrNone)
{
return error;
}
TInt i;
TPoint pos;
TBuf8<256> tmp;
// read map name
if (parser->FindNextTag(_L8("NAME")))
{
parser->GetTagData(tmp);
// convert name from 8bit buffer to unicode
iLevelName = HBufC::NewL(tmp.Length());
TFileName tmpname;
tmpname.SetLength(tmp.Length());
for (i=0; i<tmp.Length(); i++)
{
tmpname[i] = tmp[i];
}
*iLevelName = tmpname;
}
// read level total money and waste speed
iRemainingMoney = 1000.0;
iMoneyWasteSpeed = 10.0;
if (parser->FindNextTag(_L8("MONEY")))
{
TInt money, wastespeed;
parser->GetNextTagInt(money);
parser->GetNextTagInt(wastespeed);
iRemainingMoney = (TReal64)money;
iMoneyWasteSpeed = (TReal64)wastespeed;
}
// read map size
if (parser->FindNextTag(_L8("SIZE")))
{
parser->GetNextTagInt(iMapWidth);
parser->GetNextTagInt(iMapHeight);
}
// initialise the map blocks
if (iMapWidth == 0 || iMapHeight == 0)
{
delete parser;
return KErrCorrupt;
}
const TInt numblocks = iMapWidth * iMapHeight;
iBlocks = new TMapBlock[numblocks];
if (iBlocks == NULL)
{
return KErrNoMemory;
}
// read misc map items
TInt fileposition = parser->Position();
while (parser->FindNextTag(_L8("GRASS")))
{
// add some grass
AddBush(LoadCoordinate(*parser));
}
// read bonuses
parser->SetPosition(fileposition);
while (parser->FindNextTag(_L8("BONUS_MONEY")))
{
// add bonus
AddBonus(LoadPixelCoordinate(*parser), KBitmapBonusMoney, KBitmapBonusMoney);
}
parser->SetPosition(fileposition);
while (parser->FindNextTag(_L8("BONUS_POWER")))
{
// add bonus
AddBonus(LoadPixelCoordinate(*parser), KBitmapBonusPower, KBitmapBonusPower);
}
parser->SetPosition(fileposition);
while (parser->FindNextTag(_L8("BONUS_WATER")))
{
// add bonus
AddBonus(LoadPixelCoordinate(*parser), KBitmapBonusWater, KBitmapBonusWater);
}
// create player
iPlayer = new CPlayer(iApp, *this);
iPlayer->Init(iApp.Bitmap(KBitmapPlayer),
iApp.Mask(KBitmapPlayer));
iPlayer->SetMaxSpeed(0.0);
// ghosts
// read ghosts
TPoint startpos, endpos;
TInt extraparam;
parser->SetPosition(fileposition);
while (parser->FindNextTag(_L8("GHOST_RED")))
{
// add red ghost
startpos = LoadPixelCoordinate(*parser);
parser->GetNextTagInt(extraparam);
AddGhost(startpos, endpos, extraparam, KBitmapGhostRed);
}
parser->SetPosition(fileposition);
while (parser->FindNextTag(_L8("GHOST_GREEN")))
{
// add green ghost
startpos = LoadPixelCoordinate(*parser);
endpos = LoadPixelCoordinate(*parser);
parser->GetNextTagInt(extraparam);
AddGhost(startpos, endpos, extraparam, KBitmapGhostGreen);
}
parser->SetPosition(fileposition);
while (parser->FindNextTag(_L8("GHOST_BLUE")))
{
// add blue ghost
startpos = LoadPixelCoordinate(*parser);
parser->GetNextTagInt(extraparam);
AddGhost(startpos, startpos, extraparam, KBitmapGhostBlue);
}
// read block values
parser->SetPosition(fileposition);
if (parser->FindNextTag(_L8("BLOCKS")))
{
TInt blockx = 0;
TInt blocky = 0;
for (i=0; i<numblocks; i++)
{
TInt id = 0;
if (!parser->GetNextTagInt(id))
{
// failed to read map block value
delete parser;
return KErrCorrupt;
}
else
{
// link block bitmap with its id
iBlocks[i].iID = id;
switch (iBlocks[i].iID)
{
case KMapBlockGravel:
iBlocks[i].iBitmap = iApp.Bitmap(KBitmapBlock0);
break;
case KMapBlockGrass:
iBlocks[i].iBitmap = iApp.Bitmap(KBitmapBlock1);
break;
case KMapBlockWater:
iBlocks[i].iBitmap = iApp.Bitmap(KBitmapBlock2);
break;
case KMapBlockTree01:
iBlocks[i].iBitmap = iApp.Bitmap(KBitmapBlock1);
pos.iX = blockx * KMapBlockWidth + (KMapBlockWidth >> 1);
pos.iY = blocky * KMapBlockHeight + (KMapBlockHeight >> 1);
AddTree(pos, &iTree01Layers);
break;
case KMapBlockTree02:
iBlocks[i].iBitmap = iApp.Bitmap(KBitmapBlock1);
pos.iX = blockx * KMapBlockWidth + (KMapBlockWidth >> 1);
pos.iY = blocky * KMapBlockHeight + (KMapBlockHeight >> 1);
AddTree(pos, &iTree02Layers);
break;
default:
iBlocks[i].iBitmap = NULL;
}
}
// keep track of the current block indices
if (++blockx >= iMapWidth)
{
blockx = 0;
blocky++;
}
}
}
fileposition = parser->Position();
parser->SetPosition(fileposition);
while (parser->FindNextTag(_L8("BUILDING")))
{
// TODO: add building
parser->GetTagData(tmp);
}
// read startpos
parser->SetPosition(fileposition);
while (parser->FindNextTag(_L8("START")))
{
// set player startpos
pos = LoadPixelCoordinate(*parser);
iPlayer->SetPosition(TVector2(pos.iX, pos.iY));
iCamera.iX = iPlayer->Position().iX - (iBackBufferSize.iWidth >> 1);
iCamera.iY = iPlayer->Position().iY - (iBackBufferSize.iHeight >> 1);
CheckCameraLimits();
}
// read goal pos
parser->SetPosition(fileposition);
while (parser->FindNextTag(_L8("GOAL")))
{
// set player goal block
iGoalBlock = LoadCoordinate(*parser);
}
delete parser;
// init backlight control
ReturnCode ret = CRuntime::CreateInstance( iBackLight );
if ( ret != OK )
{
iBackLight = NULL;
}
// create buffer for text drawing
error = iApp.CreateBitmapAndContext( TSize(iBackBufferSize.iWidth, 128),
iTextBuffer,
iTextBufferContext);
if (error != KErrNone)
{
return error;
}
iApp.DrawTextToBitmap( iTextBuffer,
iTextBufferContext,
*iLevelName,
iApp.BigFont(),
KRgbWhite);
UpdateInfoAreaText(iRemainingMoney, iTotalMoney);
iApp.SetAudioVolume(KAudioFileWater1, 0);
iApp.SetAudioVolume(KAudioFileMove, 0);
iApp.PlayAudio(KAudioFileMove, ETrue);
iApp.PlayAudio(KAudioFileWater1, ETrue);
iStateTimer = 0.0;
iLevelState = ELevelStateStarting;
return KErrNone;
}
TPoint CLevel::LoadCoordinate(CLevelParser& aParser)
{
TPoint pos;
aParser.GetNextTagInt(pos.iX);
aParser.GetNextTagInt(pos.iY);
return pos;
}
TPoint CLevel::LoadPixelCoordinate(CLevelParser& aParser)
{
TPoint pos;
aParser.GetNextTagInt(pos.iX);
aParser.GetNextTagInt(pos.iY);
pos.iX = pos.iX * KMapBlockWidth + (KMapBlockWidth >> 1);
pos.iY = pos.iY * KMapBlockHeight + (KMapBlockHeight>> 1);
return pos;
}
void CLevel::CheckCameraLimits()
{
// camera limits
if (iCamera.iX < 0.0)
{
iCamera.iX = 0.0;
}
if (iCamera.iY < 0.0)
{
iCamera.iY = 0.0;
}
const TInt xlimit = iMapWidth * KMapBlockWidth - iBackBufferSize.iWidth;
const TInt ylimit = iMapHeight * KMapBlockHeight - iBackBufferSize.iHeight;
if (iCamera.iX > xlimit)
{
iCamera.iX = xlimit;
}
if (iCamera.iY > ylimit)
{
iCamera.iY = ylimit;
}
}
EAppUpdateState CLevel::Update(const TReal64 aFrametime)
{
// camera tries to follow the player
iBackBufferSize = iApp.BackBufferSize();
const TReal64 cameraspeed = 6.0;
const TReal64 camerawanttox = iPlayer->Position().iX - (iBackBufferSize.iWidth >> 1);
const TReal64 camerawanttoy = iPlayer->Position().iY - (iBackBufferSize.iHeight >> 1);
if (iCamera.iX < camerawanttox)
{
iCamera.iX += ((camerawanttox - iCamera.iX) * cameraspeed) * aFrametime;
}
else if (iCamera.iX > camerawanttox)
{
iCamera.iX -= ((iCamera.iX - camerawanttox) * cameraspeed) * aFrametime;
}
if (iCamera.iY < camerawanttoy)
{
iCamera.iY += ((camerawanttoy - iCamera.iY) * cameraspeed) * aFrametime;
}
else if (iCamera.iY > camerawanttoy)
{
iCamera.iY -= ((iCamera.iY - camerawanttoy) * cameraspeed) * aFrametime;
}
CheckCameraLimits();
// update water animation
const TReal64 wateranimationspeed = 2.0;
iWaterAnimationPhase += wateranimationspeed * aFrametime;
if (iWaterAnimationPhase >= 4.0)
{
iWaterAnimationPhase = 0.0;
}
// update array of sprites
if (iSettings->iGraphicsDetail > 2)
{
TInt i;
for (i=0; i<iSprites.Count(); i++)
{
CSpriteBase* sprite = iSprites[i];
sprite->Update(aFrametime);
}
}
// update player
iPlayer->Update(aFrametime);
iStateTimer += aFrametime;
iInfoAreaUpdateTimer += aFrametime;
if (iInfoAreaUpdateTimer > 1.0)
{
if (iShowFPS)
{
TBuf<32> msg;
msg.Format(_L("FPS: %d"), iApp.Fps());
iApp.SetInfoAreaText(msg, EFalse);
}
else
{
UpdateInfoAreaText(iRemainingMoney, iTotalMoney);
}
iInfoAreaUpdateTimer = 0.0;
}
// blink the backlight
if (iBackLight && iBlinkCount > 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -