📄 cgameappui.cpp
字号:
// Copyright 2002 Kenneth Guy,
//
// CGameAppUi.cpp
/** \file CGameAppUi.cpp
implementation of class CGameAppUi */
//
#include <eikappui.h>
#include <eikapp.h>
#include <eikdoc.h>
#include <eikenv.h>
#include <uikon.hrh>
#include <eikmfne.h>
#include <eikdialg.h>
#include <eikon.hrh>
#include <eikmenup.h>
#include <eikmenub.h>
#include <ckninfo.h>
#include <eikdll.h>
#include "CGameAppUi.h"
#include "CGameAppView.h"
#include "CGameApplication.h"
#include "CGameDocument.h"
#include "CGameState.h"
#include "CScoreDialog.h"
#include "CHighScores.h"
/** 2nd phase construction.
Create the game state, appview and game framework */
void CGameAppUi::ConstructL() {
BaseConstructL();
iGameState=((CGameDocument*)iDocument)->GameState();
iAppView=new(ELeave) CGameAppView;
iAppView->ConstructL(ClientRect(), iGameState);
iGame= CGameFramework::NewL();
iFrameworkState=CGameFramework::EDied;
iLevel=0;
iMapNo=0;
iGameState->SetState(CGameState::ENoGame);
iIrListenAppUi=CIrListenAppUi::NewL(ECmdIRListen,
iEikonEnv->AppUiFactory()->MenuBar()->HotKeyTable());
}
/** destructor */
CGameAppUi::~CGameAppUi() {
delete iAppView;
delete iGame;
}
/** handle a menu item or cba button press.
This will start/continue or cancel games by calling CGameFramework
\param aCommand these will be defined in #TGameMenuCommands
*/
void CGameAppUi::HandleCommandL(TInt aCommand) {
switch (aCommand) {
case ECmdStartGame:
case ECmdContinueGame:
{
if(iGameState->State()==CGameState::ENoGame ||
iGameState->State()==CGameState::ENextLevel) {
LoadLevelL();
}
// play a game
// reset if we aren't starting the next level or have a paused game
CGameFramework::TGameState state=
iGame->RunL(iGameState->State()==CGameState::ENoGame ? ETrue : EFalse);
switch(state) {
case CGameFramework::EPaused:
iGameState->SetState(CGameState::EPaused);
break;
case CGameFramework::ELevelCompleted:
if(NextLevelL()==EFalse) {
// congrats dialog
CEikDialog* dialog = new (ELeave) CEikDialog();
dialog->ExecuteLD(R_FINISHED_DIALOG);
iGameState->SetState(CGameState::ENoGame);
} else {
iGameState->SetState(CGameState::ENextLevel);
}
break;
case CGameFramework::EDied:
iGameState->SetState(CGameState::ENoGame);
break;
}
// either died, or completed the game
if(iGameState->State()==CGameState::ENoGame) {
iMapNo=0;
iLevel=0;
iGameState->SetState(CGameState::ENoGame);
if(iGameState->HighScores().GoodEnough(iGame->Score())) {
CScoreDialog::RunDlgLD(iGameState->HighScores(),iGame->Score());
}
}
}
break;
case ECmdCancelGame:
switch(iGameState->State()) {
case CGameState::ENoGame:
break;
case CGameState::EPaused: // paused so we need to let the thread end
iGame->CancelL();
iMapNo=0;
iLevel=0;
iGameState->SetState(CGameState::ENoGame);
iFrameworkState=CGameFramework::EDied;
break;
case CGameState::ENextLevel: // then set level to start
iMapNo=0;
iLevel=0;
iGameState->SetState(CGameState::ENoGame);
iFrameworkState=CGameFramework::EDied;
iAppView->DrawNow();
break;
}
break;
case ECmdHelp:
HelpDialogL();
break;
case ECmdAbout:
AboutDialogL();
break;
case ECmdLaunchLogApp:
LaunchLogL();
break;
case ECmdIRListen:
iIrListenAppUi->ToggleListeningL();
break;
case EEikCmdExit:
Exit();
break;
}
}
/** Launch the log application
A Standard 9210 application has an option to launch the
log application from the tools menu.
*/
void CGameAppUi::LaunchLogL() {
_LIT(KLogViewerAppFileName,"\\System\\Apps\\Logview\\Logview.app");
TFileName dll;
Dll::FileName(dll);
TParse parse;
parse.Set(KLogViewerAppFileName,&dll,NULL);
CApaCommandLine* cmdLine=CApaCommandLine::NewLC();
cmdLine->SetCommandL(EApaCommandRun);
cmdLine->SetLibraryNameL(parse.FullName());
EikDll::StartAppL(*cmdLine);
CleanupStack::PopAndDestroy(cmdLine);
}
/** Update menu items from game state.
This function is called before a menu is displayed, so it is
used to dim out the functions not available depending on the
game state. It is also used to add the IR Recive menu item.
\param aMenuId resource id of the menu to be displayed
\param aMenuPane menu being displayed
*/
void CGameAppUi::DynInitMenuPaneL(TInt aMenuId,CEikMenuPane* aMenuPane) {
if (aMenuId == R_GAME_GAME_MENU) {
switch(iGameState->State()) {
case CGameState::ENoGame:
aMenuPane->SetItemDimmed(ECmdCancelGame,ETrue);
aMenuPane->SetItemDimmed(ECmdContinueGame,ETrue);
aMenuPane->SetItemDimmed(ECmdStartGame,EFalse);
break;
case CGameState::EPaused:
case CGameState::ENextLevel:
aMenuPane->SetItemDimmed(ECmdCancelGame,EFalse);
aMenuPane->SetItemDimmed(ECmdContinueGame,EFalse);
aMenuPane->SetItemDimmed(ECmdStartGame,ETrue);
break;
}
} else if (aMenuId==R_GAME_TOOLS_MENU) {
iIrListenAppUi->DisplayIrListenMenuItemL(*aMenuPane,
aMenuPane->MenuItemIndex(ECmdLaunchLogApp)+1);
}
}
/** 2nd uid of a level file.
The 1st uid will be the application ui, the third will be a level number */
const TUid KLevelTypeUid={1};
/** 2nd uid of a map file.
The 1st uid will be the application ui, the third the number level number
this map is associated with */
const TUid KMapTypeUid={2};
/** Set iMapNo and iLevel to next level.
Searches the directory the dll came from for level and map files.
If there is another level/map file combination available it sets
iMapNo and iLevel to that otherwise sets them to zero.
\return ETrue if another level was found EFalse otherwise
*/
TBool CGameAppUi::NextLevelL() {
TBool anotherLevel=EFalse;
TParse parse;
parse.Set(Application()->DllName(),NULL,NULL);
RFs fs;
User::LeaveIfError(fs.Connect());
CleanupClosePushL(fs);
// get a list of all the level files, ie files with first uid
// KUidExampleGame and second uid KLevelTypeUid,
TUidType levelType(KUidExampleGame,KLevelTypeUid);
CDir* dir=NULL;
User::LeaveIfError(fs.GetDir(parse.DriveAndPath(),levelType,ESortByUid | EAscending,dir));
CleanupStack::PushL(dir);
while(iLevel < dir->Count() && anotherLevel==EFalse) {
TUid levelId=(*dir)[iLevel].MostDerivedUid();
CDir* mapDir=NULL;
// get a list of all map files for this level, ie with first uid
// KUidExampleGame, second uid KMapTypeUid, and third ui levelId
TUidType mapType(KUidExampleGame,KMapTypeUid,levelId);
User::LeaveIfError(fs.GetDir(parse.DriveAndPath(),mapType,ESortByName | EAscending,mapDir));
// if we have another map for this level use it,
if(iMapNo+1<mapDir->Count()) {
iMapNo++;
anotherLevel=ETrue;
} else {
// else try the next level
iMapNo=-1;
iLevel++;
}
delete mapDir;
}
CleanupStack::PopAndDestroy(2,&fs); // dir
if(anotherLevel==EFalse) {
// back to first level
iLevel=0;
iMapNo=0;
}
return anotherLevel;
}
/** Load level defined by iMapNo and iLevel
Searches the directory the dll came from for level and map files and
tries to load the correct one.
*/
void CGameAppUi::LoadLevelL() {
TParse parse;
parse.Set(Application()->DllName(),NULL,NULL);
RFs fs;
User::LeaveIfError(fs.Connect());
CleanupClosePushL(fs);
// get a list of all the level files, ie files with first uid
// KUidExampleGame and second uid KLevelTypeUid,
TUidType levelType(KUidExampleGame,KLevelTypeUid);
CDir* dir=NULL;
User::LeaveIfError(fs.GetDir(parse.DriveAndPath(),levelType,ESortByUid | EAscending,dir));
CleanupStack::PushL(dir);
if(iLevel >= dir->Count()) {
iLevel=0;
User::Leave(KErrNotFound);
}
TUid levelId=(*dir)[iLevel].MostDerivedUid();
CDir* mapDir=NULL;
// get a list of all map files for this level, ie with first uid
// KUidExampleGame, second uid KMapTypeUid, and third ui levelId
TUidType mapType(KUidExampleGame,KMapTypeUid,levelId);
User::LeaveIfError(fs.GetDir(parse.DriveAndPath(),mapType,ESortByName | EAscending,mapDir));
CleanupStack::PushL(mapDir);
if(iMapNo >= mapDir->Count()) {
iMapNo=0;
User::Leave(KErrNotFound);
}
// get the file entries for the level and map files
const TEntry& levelEntry=(*dir)[iLevel];
const TEntry& mapEntry=(*mapDir)[iMapNo];
// get the full path and file names of the level and map files
HBufC* levelFileName= HBufC::NewLC(levelEntry.iName.Length()+
parse.DriveAndPath().Length());
levelFileName->Des().Append(parse.DriveAndPath());
levelFileName->Des().Append(levelEntry.iName);
HBufC* mapFileName= HBufC::NewLC(mapEntry.iName.Length()+
parse.DriveAndPath().Length());
mapFileName->Des().Append(parse.DriveAndPath());
mapFileName->Des().Append(mapEntry.iName);
// pass the filenames to CGameFramework::LoadLevelL()
// reset the ship if it is a new game.
if(iGameState->State()==CGameState::ENoGame)
iGame->LoadLevelL(*levelFileName,*mapFileName,ETrue);
else //iGameState->State()==CGameState::ENextLevel
iGame->LoadLevelL(*levelFileName,*mapFileName,EFalse);
CleanupStack::PopAndDestroy(5,&fs); // dir, mapDir,levelFileName,mapFileName
}
/** Tell the user about the game */
void CGameAppUi::HelpDialogL() {
CEikonEnv* eikonEnv=CEikonEnv::Static();
HBufC *title= eikonEnv->AllocReadResourceL(R_HELP_DIALOG_TITLE);
CleanupStack::PushL(title);
HBufC *body= eikonEnv->AllocReadResourceL(R_HELP_DIALOG_BODY);
CleanupStack::PushL(body);
CCknInfoDialog::RunDlgLD(*title,*body);
CleanupStack::PopAndDestroy(2,title); // body
}
/** Tell the user who wrote the game */
void CGameAppUi::AboutDialogL() {
CEikonEnv* eikonEnv=CEikonEnv::Static();
HBufC *title= eikonEnv->AllocReadResourceL(R_ABOUT_DIALOG_TITLE);
CleanupStack::PushL(title);
HBufC *body= eikonEnv->AllocReadResourceL(R_ABOUT_DIALOG_BODY);
CleanupStack::PushL(body);
CCknInfoDialog::RunDlgLD(*title,*body);
CleanupStack::PopAndDestroy(2,title); // body
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -