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

📄 cmenu.cpp

📁 Symbian开发提高的一个很好的实例,其实现了一个非常好理解的Symbian游戏开发流程
💻 CPP
字号:
#include <avkon.hrh>
#include <eikenv.h>
#include <gdi.h>
#include <aknutils.h>

#include "CMenu.h"
#include <images.mbg>
#include <Tetris.rsg>


// Construct and destruct

// NewL()
CMenu* CMenu::NewL(CFbsBitGc* aFbsBitGc)
{
	CMenu* self = new (ELeave) CMenu(aFbsBitGc);
	CleanupStack::PushL(self);

	self->ConstructL();

	CleanupStack::Pop();

	return self;
}

// ~
CMenu::~CMenu()
{
	delete iBitmap;

	iSettingStr.DeleteAll();
//	iSettingStr.Reset();
	
	// cannot delete twice
	iMenuItemTxt.At(EOptions_RotateDir) = NULL;
	iMenuItemTxt.At(ESound_Sounds)	= NULL;
	iMenuItemTxt.At(ESound_Music)	= NULL;
	iMenuItemTxt.At(ESound_Volume)	= NULL;
	iMenuItemTxt.At(EDifficulty_StartLines)	= NULL;
	iMenuItemTxt.At(EDifficulty_AddBrick)	= NULL;
	iMenuItemTxt.At(EDifficulty_Done)		= NULL;
	iMenuItemTxt.At(EPause_Sound)	= NULL;
	

	iMenuItemTxt.DeleteAll();
	//iMenuItemTxt.Reset();
}


// CMenu
CMenu::CMenu(CFbsBitGc* aFbsBitGc) : iGc(aFbsBitGc)
{}

// ConsturctL
void CMenu::ConstructL()
{
	//iLabel = new (ELeave) CEikLabel;
	//iLabel->SetTextL(_L("ahhadkjdjfkldsajfkijoewijfioewjf"));
	_LIT(KPathName, "\\System\\Apps\\Tetris\\images.mbm");
	iBitmap = CEikonEnv::Static()->CreateBitmapL(KPathName, EMbmImagesLogo);

	LoadResL();		// Load menu resouce and position

	ResetPos();
}

///////////////////////////////////////////////////////////////////////////////
// Other Method

// Draw
void CMenu::Draw()
{
	// draw background
	DrawBg();

	if(iMenuState == ECreditPage)
	{	
		//iLabel->DrawNow();
		const CFont* font;
		font = CEikonEnv::Static()->TitleFont();
		iGc->UseFont(font);
		
		iGc->DrawText(_L("Tetris v1.2"), TPoint(60, 30));
		iGc->DrawText(_L("It's my #1 Symbian game, so"), TPoint(20, 60));
		iGc->DrawText(_L("it's written 100% from scratch!"), TPoint(10, 80));
		iGc->DrawText(_L("Suggestions, comments, or bug"), TPoint(10, 100));
		iGc->DrawText(_L("reports are welcome!"), TPoint(10, 120));
		iGc->DrawText(_L("My email : cofd.eric@163.com"), TPoint(10, 140));
		iGc->DrawText(_L("Thank you for playing!"), TPoint(10, 160));
		iGc->DrawText(_L("CArt Studio 2005"), TPoint(45, 200));

		iGc->DiscardFont();
		return;
	}
	if(iMenuState == EHighScorePage)
		return;			// don't draw here

	// use default
	if(iMenuState == ENonePage)
	{
		iMenuState = EMainPage;
		iMenuItem  = EStart;
		return;
	}

	// Get an alternative font
	_LIT(KMyFontName,"Roman");
	CFont* myFont;
	TFontSpec myFontSpec(KMyFontName, 1);

	myFontSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold);

	CBitmapDevice* screenDevice=CEikonEnv::Static()->ScreenDevice();
	screenDevice->GetNearestFontInTwips(myFont,myFontSpec);
	iGc->UseFont(myFont);
	
	// draw menu page
	DrawPage(iMenuPagePos[iMenuState].iX, iMenuPagePos[iMenuState].iY);

	// Draw the Blink frame and white selected txt
	iGc->SetPenColor(TRgb(250, 250, 250));
	
	iBlink++;
	
	if((iBlink >= 2 && iBlink <= 5) || (iBlink >= 18 && iBlink <= 21)) 
		iGc->SetPenColor(TRgb(220, 220, 220)); 
	else if((iBlink >= 6 && iBlink <= 9) || (iBlink >= 14 && iBlink <= 17))
		iGc->SetPenColor(TRgb(180, 180, 180)); 
	else if(iBlink >= 10 && iBlink <= 13)
		iGc->SetPenColor(TRgb(120, 120, 120));	
	else if(iBlink == 22)
		iBlink = 0;

	
	// dont't modify Frame's positon
	SetFrame(iMenuItem);
	if(iSelect)
	{
		iGc->SetBrushColor(TRgb(90, 90, 255));
		iGc->DrawPolygon(iPointList, 12, CGraphicsContext::EAlternate);
		iSelect = 0;
	}
	iGc->DrawPolyLineNoEndPoint(iPointList, 12);
	
	// highlight the text
	iGc->SetPenColor(KRgbWhite);
	iGc->DrawText(*iMenuItemTxt.At(iMenuItem), TRect(iPointList[2]+TPoint(1,1), iPointList[8]-TPoint(1,1)), 15, CGraphicsContext::ECenter, 0);
	
	// delete created Font
	iGc->DiscardFont();
	screenDevice->ReleaseFont(myFont);
}

// DrawBg()
void CMenu::DrawBg()
{
	iGc->SetBrushStyle(CFbsBitGc::ESolidBrush);
	
	iGc->SetFadingParameters(80, 255);
	iGc->SetFaded(1);
	
	iGc->SetBrushColor(KRgbBlack);
	iGc->Clear();

	iGc->BitBlt(iPos + TPoint(0, 69), iBitmap);
	iGc->BitBlt(iPos + TPoint(0, 208), iBitmap);

	iGc->BitBlt(iPos + TPoint(185, 69), iBitmap);
	iGc->BitBlt(iPos + TPoint(185, 208), iBitmap);

	iPos -= TPoint(4, 3);
	if(iPos.iY <= -139)
		iPos = TPoint(0, 0);
	
	iGc->SetFaded(0);
}

// DrawPage()
void CMenu::DrawPage(TInt aItemFrom, TInt aItemTo)
{
	if(aItemFrom == ENoneItem)
		return;
	TInt i;
	// draw the frame
	iGc->SetBrushColor(TRgb(45, 45, 130));
	iGc->SetPenColor(TRgb(20, 20, 120));

	for(i = aItemFrom; i <= aItemTo; i++)
	{
		SetFrameDynamic(i);
		iGc->DrawPolygon(iPointList, 12, CGraphicsContext::EAlternate);
	}
	iSpeed += 5;
	// draw the Txt
	iGc->SetPenColor(KRgbGray);
	for(i = aItemFrom; i <= aItemTo; i++)
	{	
		SetFrame(i);
		iGc->DrawText(*iMenuItemTxt.At(i), TRect(iPointList[2]+TPoint(1,1), iPointList[8]-TPoint(1,1)), 15, CGraphicsContext::ECenter, 0);
	}
}


// Command
// @return 1 denote quit the game
// @return 2 dentoe start the game
TInt32 CMenu::Command(TInt aCommand)
{
	switch(aCommand)
	{
		case 'q' :
		{
			if(iMenuState == EMainPage || iMenuState == EPausePage)
				break;
			iMenuState	= iPrevPage;
			ResetPos();
			iMenuItem	= iPrevItem;
		}return 5;

		case EStdKeyDevice5:
		case '5':
		case 63557:
		{
			switch(iMenuItem)
			{
				case EQuit:
					return 1;						// Quit
				case EStart :
				{
					iPrevPage = EPausePage;
					iMenuState = ENonePage;
					iPrevItem = EPause_Continue;						
				}return 2;							// Start the game
				case EPause_Continue:
				{
					iMenuState = ENonePage;
				}return 3;						// Continue the game
				case EOptions_Back:
				{
					iMenuState = EMainPage;
					ResetPos();
					iMenuItem	= EStart;	
				}return 11;							// set rotation
				case ESound_Done :
				{
					iMenuState = iPrevPage;
					ResetPos();
					iMenuItem = iPrevItem;						
				}return 12;							// set Sound
				case EDifficulty_Done :
				{	
					iMenuState = iPrevPage;
					ResetPos();
					iMenuItem = iPrevItem;					
				}return 13;							// set Difficulty

				case EOptions:
				{
					iPrevPage = EMainPage;
					iMenuState	= EOptionsPage;
					ResetPos();
					iPrevItem	= iMenuItem;
					iMenuItem	= EOptions_Sound;
				}break;
				case ECredit:
				{
					iPrevPage	= EMainPage;
					iMenuState	= ECreditPage;
					iPrevItem	= iMenuItem;
					iMenuItem	= -1;
				}break;;
				case EHighScore:
				{
					iPrevPage	= EMainPage;
					iMenuState	= EHighScorePage;
					iPrevItem	= iMenuItem;
					iMenuItem	= -1;	
				}return 4;
				
				// Options
				case EOptions_Sound:
				{
					iPrevPage = EOptionsPage;
					iMenuState = ESoundPage;
					ResetPos();
					iPrevItem = iMenuItem;
					iMenuItem = ESound_Sounds;
				}break;
				case EOptions_Difficulty:
				{
					iPrevPage = EOptionsPage;
					iMenuState = EDifficultyPage;
					ResetPos();
					iPrevItem = iMenuItem;
					iMenuItem = EDifficulty_StartLines;
				}break;
				
				// Pause page
				case EPause_Sound:
				{
					iPrevPage = EPausePage;
					iMenuState = ESoundPage;
					ResetPos();
					iPrevItem = iMenuItem;
					iMenuItem = ESound_Sounds;
				}break;
				case EPause_EndGame:
				{
					iMenuState = EMainPage;		// return to main page
					ResetPos();
					iMenuItem	= EStart;
				}break;
				
				case EOptions_RotateDir:
				case ESound_Sounds :
				case ESound_Music :
				case ESound_Volume :
				case EDifficulty_StartLines :
				case EDifficulty_AddBrick :
				{}break;

				default:
				{
					iMenuState	= iPrevPage;
					ResetPos();
					iMenuItem	= iPrevItem;
				}break;
			}
		}return 5;	
	
		case EKeyUpArrow :								// UP
		case '2' :
		{
			iMenuItem = iMenuItem <= iMenuPagePos[iMenuState].iX ? iMenuPagePos[iMenuState].iY : --iMenuItem;		
			// select the menu item
			iSelect = 1;	
		}return 0;

		case EKeyDownArrow :							// Down
		case '8' :
		{	
			iMenuItem = iMenuItem >= iMenuPagePos[iMenuState].iY ? iMenuPagePos[iMenuState].iX : ++iMenuItem;
			iSelect = 1;
		}return 0;
		
		case EKeyLeftArrow :							// Left
		case '4' :
		{
			TInt Item = Index(iMenuItem);
			if(Item == -1)
				break;
			iSetting[Item] = iSetting[Item] <= iSettingPos[Item].iX ? iSettingPos[Item].iY : --iSetting[Item];

			iMenuItemTxt.At(iMenuItem) = iSettingStr.At(iSetting[Item]);
		}break;

		case EKeyRightArrow :							// Right
		case '6' :
		{
			TInt Item = Index(iMenuItem);
			if(Item == -1)
				break;
			iSetting[Item] = iSetting[Item] >= iSettingPos[Item].iY ? iSettingPos[Item].iX : ++iSetting[Item];

			iMenuItemTxt.At(iMenuItem) = iSettingStr.At(iSetting[Item]);
		}break;

		// just hold on,wait for key
		default:
		{
			return 0;
		}break;
	}
	return 0;
}


// SetFrameDynamic()
void CMenu::SetFrameDynamic(TInt aMenuItem)
{
	TPoint&		pos = iCurrentMenuItemPos[aMenuItem];
	TPoint		aimPos = iMenuItemPos[aMenuItem];

	if(pos.iY < aimPos.iY)
	{
		pos.iY += iSpeed;
		if(pos.iY > aimPos.iY)
			pos.iY = aimPos.iY;
	}
	else if(pos.iY > aimPos.iY)
	{
		pos.iY -= iSpeed;
		if(pos.iY < aimPos.iY)
			pos.iY = aimPos.iY;
	
	}
	
	SetFrame(aMenuItem);
}

//
void CMenu::SetFrame(TInt aMenuItem)
{
	iPointList[0] = iCurrentMenuItemPos[aMenuItem] - TPoint(1, 0);
	iPointList[1] = iPointList[0] + TPoint( 33,  0);
	iPointList[2] = iPointList[1] + TPoint(  5, -8);
	iPointList[3] = iPointList[2] + TPoint(100,  0);
	iPointList[4] = iPointList[3] + TPoint(  5,  8);
	iPointList[5] = iPointList[4] + TPoint( 34,  0);
		
	iPointList[6] = iPointList[5] + TPoint( 0,  5);
	iPointList[7] = iPointList[4] + TPoint( 0,  5);
	iPointList[8] = iPointList[3] + TPoint( 0,  20);
	iPointList[9] = iPointList[2] + TPoint( 0,  20);
	iPointList[10] = iPointList[1] + TPoint( 0,  5);
	iPointList[11] = iPointList[0] + TPoint( 0,  5);
}

// LoadRes()
// Init Menu 's position and Txt
void CMenu::LoadResL()
{
	CEikonEnv* eikonEnv = CEikonEnv::Static();

	iMenuState	= EMainPage;
	iMenuItem	= EStart;

	iSettingStr[0] = eikonEnv->AllocReadResourceL(R_MENUITEM_ROTATION1);
	iSettingStr[1] = eikonEnv->AllocReadResourceL(R_MENUITEM_ROTATION2);
	iSettingStr[2] = eikonEnv->AllocReadResourceL(R_MENUITEM_SOUNDS1);
	iSettingStr[3] = eikonEnv->AllocReadResourceL(R_MENUITEM_SOUNDS2);
	iSettingStr[4] = eikonEnv->AllocReadResourceL(R_MENUITEM_MUSIC1);
	iSettingStr[5] = eikonEnv->AllocReadResourceL(R_MENUITEM_MUSIC2);
	iSettingStr[6] = eikonEnv->AllocReadResourceL(R_MENUITEM_VOLUME1);
	iSettingStr[7] = eikonEnv->AllocReadResourceL(R_MENUITEM_VOLUME2);
	iSettingStr[8] = eikonEnv->AllocReadResourceL(R_MENUITEM_VOLUME3);
	iSettingStr[9] = eikonEnv->AllocReadResourceL(R_MENUITEM_VOLUME4);
	iSettingStr[10] = eikonEnv->AllocReadResourceL(R_MENUITEM_STARTLINES1);
	iSettingStr[11] = eikonEnv->AllocReadResourceL(R_MENUITEM_STARTLINES2);
	iSettingStr[12] = eikonEnv->AllocReadResourceL(R_MENUITEM_STARTLINES3);
	iSettingStr[13] = eikonEnv->AllocReadResourceL(R_MENUITEM_STARTLINES4);
	iSettingStr[14] = eikonEnv->AllocReadResourceL(R_MENUITEM_ADDBRICK1);
	iSettingStr[15] = eikonEnv->AllocReadResourceL(R_MENUITEM_ADDBRICK2);
	iSettingStr[16] = eikonEnv->AllocReadResourceL(R_MENUITEM_ADDBRICK3);

	// settings start & end
	iSettingPos[0] = TPoint(0, 1);
	iSettingPos[1] = TPoint(2, 3);
	iSettingPos[2] = TPoint(4, 5);
	iSettingPos[3] = TPoint(6, 9);
	iSettingPos[4] = TPoint(10, 13);
	iSettingPos[5] = TPoint(14, 16);

	// Init
	iSetting[0]	= iSettingPos[0].iX;
	iSetting[1]	= iSettingPos[1].iX;
	iSetting[2]	= iSettingPos[2].iX;
	iSetting[3]	= iSettingPos[3].iX;
	iSetting[4]	= iSettingPos[4].iX;
	iSetting[5]	= iSettingPos[5].iX;
	// set menuPage's start & end item 
	iMenuPagePos[EMainPage] = TPoint(0, 4);
	iMenuPagePos[EOptionsPage] = TPoint(5, 8);
	iMenuPagePos[ESoundPage] = TPoint(9, 12);
	iMenuPagePos[EDifficultyPage] = TPoint(13, 15);
	iMenuPagePos[EPausePage] = TPoint(16, 18);
	iMenuPagePos[ECreditPage] = TPoint(ENoneItem, ENoneItem);
	iMenuPagePos[EHighScorePage] = TPoint(ENoneItem, ENoneItem);

	// Menu item Position
	iMenuItemPos[EStart]	= TPoint(0, 54);
	iMenuItemPos[EOptions]	= TPoint(0, 79);
	iMenuItemPos[ECredit]	= TPoint(0, 104);
	iMenuItemPos[EHighScore]= TPoint(0, 129);
	iMenuItemPos[EQuit]		= TPoint(0, 154);

	iMenuItemPos[EOptions_Sound]		= TPoint(0, 67);
	iMenuItemPos[EOptions_Difficulty]	= TPoint(0, 92);
	iMenuItemPos[EOptions_RotateDir]	= TPoint(0, 116);
	iMenuItemPos[EOptions_Back]			= TPoint(0, 141);

	iMenuItemPos[ESound_Sounds]	= TPoint(0, 67);
	iMenuItemPos[ESound_Music]	= TPoint(0, 92);
	iMenuItemPos[ESound_Volume]	= TPoint(0, 116);
	iMenuItemPos[ESound_Done]	= TPoint(0, 141);

	iMenuItemPos[EDifficulty_StartLines]	= TPoint(0, 74);
	iMenuItemPos[EDifficulty_AddBrick]		= TPoint(0, 104);
	iMenuItemPos[EDifficulty_Done]			= TPoint(0, 134);

	iMenuItemPos[EPause_Continue]	= TPoint(0, 79);
	iMenuItemPos[EPause_Sound]		= TPoint(0, 104);
	iMenuItemPos[EPause_EndGame]	= TPoint(0, 129);

	// Menu Item Txt
	iMenuItemTxt.At(EStart)		= eikonEnv->AllocReadResourceL(R_MENUITEM_START);
	iMenuItemTxt.At(EOptions)	= eikonEnv->AllocReadResourceL(R_MENUITEM_OPTIONS);
	iMenuItemTxt.At(ECredit)	= eikonEnv->AllocReadResourceL(R_MENUITEM_CREDIT);
	iMenuItemTxt.At(EHighScore)	= eikonEnv->AllocReadResourceL(R_MENUITEM_HIGHSCORE);
	iMenuItemTxt.At(EQuit)		= eikonEnv->AllocReadResourceL(R_MENUITEM_QUIT);

	iMenuItemTxt.At(EOptions_Sound)		= eikonEnv->AllocReadResourceL(R_MENUITEM_SOUND);
	iMenuItemTxt.At(EOptions_Difficulty)= eikonEnv->AllocReadResourceL(R_MENUITEM_DIFFICULTY);
	iMenuItemTxt.At(EOptions_RotateDir)	= iSettingStr.At(iSetting[0]);
	iMenuItemTxt.At(EOptions_Back)		= eikonEnv->AllocReadResourceL(R_MENUITEM_BACK);

	iMenuItemTxt.At(ESound_Sounds)	= iSettingStr.At(iSetting[1]);
	iMenuItemTxt.At(ESound_Music)	= iSettingStr.At(iSetting[2]);
	iMenuItemTxt.At(ESound_Volume)	= iSettingStr.At(iSetting[3]);
	iMenuItemTxt.At(ESound_Done)	= eikonEnv->AllocReadResourceL(R_MENUITEM_DONE);

	iMenuItemTxt.At(EDifficulty_StartLines)	= iSettingStr.At(iSetting[4]);
	iMenuItemTxt.At(EDifficulty_AddBrick)	= iSettingStr.At(iSetting[5]);
	iMenuItemTxt.At(EDifficulty_Done)		= iMenuItemTxt.At(ESound_Done);

	iMenuItemTxt.At(EPause_Continue)= eikonEnv->AllocReadResourceL(R_MENUITEM_CONTINUE);
	iMenuItemTxt.At(EPause_Sound)	= iMenuItemTxt.At(EOptions_Sound);
	iMenuItemTxt.At(EPause_EndGame)	= eikonEnv->AllocReadResourceL(R_MENUITEM_ENDGAME);
}


// ResetPos()
void CMenu::ResetPos()
{
	iSpeed = 1;

	TInt start	= iMenuPagePos[iMenuState].iX;
	TInt end	= iMenuPagePos[iMenuState].iY;

	for(TInt i = start; i <= end; i++)
		iCurrentMenuItemPos[i] = TPoint(0, 104);
}

// Index()
TInt CMenu::Index(TInt aMenuItem)
{
	switch(aMenuItem)
	{
		case EOptions_RotateDir :
			return 0;
		case ESound_Sounds :
			return 1;
		case ESound_Music :
			return 2;
		case ESound_Volume :
			return 3;
		case EDifficulty_StartLines :
			return 4;
		case EDifficulty_AddBrick :
			return 5;
		
		default: return -1;
	}
}

⌨️ 快捷键说明

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