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

📄 cgameappui.cpp

📁 symbian 的一个 二维飞行游戏 源码 及相关技术文章
💻 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 + -