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

📄 appstatemenu.cpp

📁 RGA: Biowaste Game Example This C++ application demonstrates how to create a 2D mobile game for S60
💻 CPP
字号:

#include "AppStateMenu.h"
#include "AppStateHelpScreen.h"
#include "AppStateSettingsScreen.h"
#include "ExampleApplication.h"


const TInt KMenuStateMain = 0;
const TInt KMenuStateHighScores = 1;


CAppStateMenu::CAppStateMenu(CExampleApplication& aApp)
	: CAppState(aApp),
	  iNextState(EAppUpdateStateContinue),
	  iMenuState(KMenuStateMain),
	  iHighScoreHighlight(-1)
	{

	}


CAppStateMenu::~CAppStateMenu()
	{
	if (iExtraScreen)
		{
		delete iExtraScreen;
		iExtraScreen = NULL;
		}
	
	if (iMenu)
		{
		delete iMenu;
		iMenu = NULL;
		}
	
	if (iBknd)
		{
		iBknd->Release();
		iBknd = NULL;
		}
	}


TInt CAppStateMenu::Init()
	{
	TInt error;
	
	error = LoadBackground();
	if (error != KErrNone)
		{
		return error;
		}
	
	error = InitMenu();
	if (error != KErrNone)
		{
		return error;
		}
	
	return KErrNone;
	}


TInt CAppStateMenu::LoadBackground()
	{
	if (iBknd)
		{
		iBknd->Release();
		iBknd = NULL;
		}
	
	// create & load the menu background
	TInt error;
	ReturnCode ret;
	ret = CRuntime::CreateInstance( iBknd );
	if ( ret != OK )
		{
		return App().RGAErrorToSymbianError(ret);
		}
	
	TFileName filename;
	
	if (App().BackBufferSize().iWidth < App().BackBufferSize().iHeight)
		{
		// portrait mode
		App().BuildFilepath(KPathMenuBkndPortrait, filename);
		}
	else
		{
		// landscape mode
		App().BuildFilepath(KPathMenuBkndLandscape, filename);
		}

	error = App().LoadImage(*iBknd, filename);
	if (error != KErrNone)
		{
		iBknd->Release();
		iBknd = NULL;
		return error;
		}
	
	return KErrNone;
	}


TInt CAppStateMenu::InitMenu()
	{
	// create new menu object
	TInt error;
	iMenu = new (ELeave) CGameMenu( App() );
	error = iMenu->Init();
	if (error != KErrNone)
		{
		return error;
		}
	
	// add menu items
	TMenuItem item;
	item.iID = KMenuIdStartGame;
	item.iText = KTextMenuStartGame;
	iMenu->AddMenuItem(item);
	
	item.iID = KMenuIdHighScores;
	item.iText = KTextMenuHighScores;
	iMenu->AddMenuItem(item);
	
	item.iID = KMenuIdSettings;
	item.iText = KTextMenuSettings;
	iMenu->AddMenuItem(item);

	item.iID = KMenuIdHelp;
	item.iText = KTextMenuHelp;
	iMenu->AddMenuItem(item);
	
	item.iID = KMenuIdExit;
	item.iText = KTextMenuExit;
	iMenu->AddMenuItem(item);
	
	InitMenuPos();
	return KErrNone;
	}


void CAppStateMenu::InitMenuPos()
	{
	// compute position for the menu, center of screen
	// little bit down
	TSize bbsize = App().BackBufferSize();
	iMenuWantTo.iX = (bbsize.iWidth >> 1) - (iMenu->Size().iWidth >> 1);
	iMenuWantTo.iY = (bbsize.iHeight >> 1) - (iMenu->Size().iHeight >> 1) + 30.0;

	iMenuPos = iMenuWantTo;
	
	
	// set menu randomly 'out of the screen'
	// menu position is interpolated to
	// 'iMenuWantTo' coordinate
	TInt menustartposx = App().RandInt(0, 2);
	TInt menustartposy = App().RandInt(0, 2);
	if (menustartposx == 2 && menustartposy == 2)
		{
		menustartposx = 0;
		}
	
	if (menustartposx == 0)
		{
		// start from right side
		iMenuPos.iX = bbsize.iWidth;
		}
	else if (menustartposx == 1)
		{
		// start from left side
		iMenuPos.iX = -iMenu->Size().iWidth;
		}

	if (menustartposy == 0)
		{
		// start from bottom side
		iMenuPos.iY = bbsize.iHeight;
		}
	else if (menustartposy == 1)
		{
		// start from top side
		iMenuPos.iY = -iMenu->Size().iHeight;
		}
	
	iMenu->SetPosition(TPoint( (TInt)(iMenuPos.iX), (TInt)(iMenuPos.iY) ) );
	}


EAppUpdateState CAppStateMenu::Update(const TReal64& aFrametime)
	{
	if (iExtraScreen)
		{
		EAppUpdateState state = iExtraScreen->Update(aFrametime);
		if (state != EAppUpdateStateContinue)
			{
			delete iExtraScreen;
			iExtraScreen = NULL;
			}
		}
	else if (iMenu)
		{
		iMenu->Update(aFrametime);
		
		// interpolate menu position to 'iMenuWantTo' coordinate
		const TReal movespeed = 6.0;
		if (iMenuPos.iX < iMenuWantTo.iX)
			{
			iMenuPos.iX += ((iMenuWantTo.iX - iMenuPos.iX) * movespeed) * aFrametime;
			}
		else if (iMenuPos.iX > iMenuWantTo.iX)
			{
			iMenuPos.iX -= ((iMenuPos.iX - iMenuWantTo.iX) * movespeed) * aFrametime;
			}
		if (iMenuPos.iY < iMenuWantTo.iY)
			{
			iMenuPos.iY += ((iMenuWantTo.iY - iMenuPos.iY) * movespeed) * aFrametime;
			}
		else if (iMenuPos.iY > iMenuWantTo.iY)
			{
			iMenuPos.iY -= ((iMenuPos.iY - iMenuWantTo.iY) * movespeed) * aFrametime;
			}
		
		iMenu->SetPosition(TPoint( (TInt)(iMenuPos.iX), (TInt)(iMenuPos.iY) ) );
		
		if (iNextState != EAppUpdateStateContinue)
			{
			// we're about to exit the menu, scroll the menu out
			// before exiting
			TSize bbsize = App().BackBufferSize();
			iMenuWantTo.iY = bbsize.iHeight + 100;
			
			if (iMenuPos.iY < bbsize.iHeight)
				{
				return EAppUpdateStateContinue;
				}
			}
		}
	
	return iNextState;
	}


void CAppStateMenu::Draw(IGraphicsContext& aContext)
	{
	CPoint bkndpos(0, 0);
	TSize bbsize = App().BackBufferSize();
	
	if (iBknd->GetSize().mX != bbsize.iWidth)
		{
		// menu background has different size than back buffer
		// draw menu background centered
		aContext.Clear(0);
		bkndpos.mX = (bbsize.iWidth >> 1) - (iBknd->GetSize().mX >> 1);
		bkndpos.mY = (bbsize.iHeight >> 1) - (iBknd->GetSize().mY >> 1);
		}

	// draw menu backgound image
	ReturnCode ret;
	if (iBknd)
		{
		ret = iBknd->Lock();
		if (ret == OK)
			{
			ret = aContext.BitBlit(bkndpos, *iBknd);
			iBknd->Unlock();
			}
		}
	
	if (iExtraScreen)
		{
		iExtraScreen->Draw(aContext);
		}
	else
		{
		switch (iMenuState)
			{
			case KMenuStateMain:
				// draw the menu
				if (iMenu)
					{
					iMenu->Draw(aContext);
					}
				break;
				
			case KMenuStateHighScores:
				DrawHighScores();
				break;
			}
		}
	}


void CAppStateMenu::DrawHighScores()
	{
	// blend background image
	App().BlendRect(TRect(	0,
			0,
			App().BackBufferSize().iWidth,
			App().BackBufferSize().iHeight));
	
	CHighScores* scores = App().HighScores();
	CGraphicsContext* context = App().SystemGc( App().BackBuffer() );
	const CFont* font = App().SmallFont();
	const TInt fontheight = font->FontMaxHeight();
	
	context->UseFont(font);
	context->SetPenColor(KRgbGreen);
	
	TInt i;
	TInt x = (App().BackBufferSize().iWidth >> 5);
	TInt y = (App().BackBufferSize().iHeight >> 2) + fontheight;

	TBuf<128> msg;
	for (i=0; i<scores->MaxItems(); i++)
		{
		if (i == iHighScoreHighlight)
			{
			context->SetPenColor(KRgbRed);
			}
		
		THighScoreItem& item = scores->Score(i);

		msg.Format(_L("%d:"), i + 1);
		context->DrawText(msg, TPoint(x, y));

		context->DrawText(item.iName, TPoint(x + fontheight * 2, y));
		
		msg.Format(_L("$%.2f"), item.iScore);
		context->DrawText(msg, TPoint(x + fontheight * 9, y));
		y += fontheight;
		
		if (i == iHighScoreHighlight)
			{
			context->SetPenColor(KRgbGreen);
			}
		}
	
	context->DiscardFont();
	App().ApplySystemGc();
	}


void CAppStateMenu::KeyDown(TUint32 aKeyCode)
	{
	if (iExtraScreen)
		{
		iExtraScreen->KeyDown(aKeyCode);
		}
	else if (iMenu)
		{
		iMenu->KeyDown(aKeyCode);
		
		
		// handle menu selection keys
		if (	aKeyCode == INPUT_KEY_OK ||
				aKeyCode == INPUT_KEY_LSK ||
				aKeyCode == INPUT_KEY_RSK)
			{
			if (iMenuState == KMenuStateMain)
				{
				// menu item selected
				switch (iMenu->SelectedMenuItemId())
					{
					case KMenuIdStartGame:
						iNextState = EAppUpdateStateInitGame;
						break;
						
					case KMenuIdHighScores:
						OpenHighScoresTable(KErrNotFound);
						break;
						
					case KMenuIdSettings:
						iExtraScreen = new CAppStateSettingsScreen(App());
						iExtraScreen->Init();
						break;
						
					case KMenuIdHelp:
						iExtraScreen = new CAppStateHelpScreen(App());
						iExtraScreen->Init();
						break;
						
					case KMenuIdExit:
						iNextState = EAppUpdateStateExit;
						break;
					}
				}
			else if (iMenuState == KMenuStateHighScores)
				{
				// go back to main menu
				iMenuState = KMenuStateMain;
				}
			}
		}
	}


void CAppStateMenu::DisplayOrientationChanged()
	{
	if (iExtraScreen)
		{
		iExtraScreen->DisplayOrientationChanged();
		}
	
	LoadBackground();
	InitMenuPos();
	}


void CAppStateMenu::OpenHighScoresTable(TInt aHighlightIndex)
	{
	iHighScoreHighlight = aHighlightIndex;
	iMenuState = KMenuStateHighScores;
	iMenu->SelectMenuItem(KMenuIdHighScores);
	}

⌨️ 快捷键说明

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