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

📄 level.cpp

📁 RGA: Biowaste Game Example This C++ application demonstrates how to create a 2D mobile game for S60
💻 CPP
📖 第 1 页 / 共 3 页
字号:

#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 + -