📄 mopoidgameengine.cpp
字号:
/*
* ============================================================================
* Name : CMopoidGameEngine from MopoidGameEngine.cpp
* Part of : Mopoid
* Created : 16.01.2004 by Andreas Jakl / Mopius - http://www.mopius.com/
* Description:
* The game-engine. Handles the control of the gameflow.
* Version : 1.02
* Copyright:
* 'Mopoid' is free software; you can redistribute
* it and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* 'Mopoid' is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 'Mopoid'; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ============================================================================
*/
#include "MopoidGameengine.h"
// -----------------------------------------------------------------------
// Construct engine object (private)
// -----------------------------------------------------------------------
CMopoidGameEngine::CMopoidGameEngine(CMopoidContainer* aOwningControl)
:
iKeyHandler(),
iSettings(),
iHaveFocus(ETrue),
iOwningControl(aOwningControl),
iGrid(),
iPanel(),
iBall()
{
}
// -----------------------------------------------------------------------
// Destroy Engine Object
// -----------------------------------------------------------------------
CMopoidGameEngine::~CMopoidGameEngine()
{
// Delete active object
DELETE_AND_NULL(iUpdateAO);
StopTimer();
// Sound Manager
DELETE_AND_NULL(iSoundManager);
// Delete bitmaps
DELETE_AND_NULL(iBackBufferBmp);
DELETE_AND_NULL(iBackBufferBmpGc);
DELETE_AND_NULL(iBackBufferBmpDrawingDevice);
DELETE_AND_NULL(iLevels);
DELETE_AND_NULL(iSpriteHandler);
CleanupComponents();
}
// -----------------------------------------------------------------------
// leaving construction methods
// -----------------------------------------------------------------------
CMopoidGameEngine* CMopoidGameEngine::NewL(CMopoidContainer* aOwningControl)
{
CMopoidGameEngine* self = CMopoidGameEngine::NewLC(aOwningControl);
CleanupStack::Pop(self);
return self;
}
CMopoidGameEngine* CMopoidGameEngine::NewLC(CMopoidContainer* aOwningControl)
{
CMopoidGameEngine* self = new (ELeave) CMopoidGameEngine(aOwningControl);
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
// -----------------------------------------------------------------------
// Construction leaving function (public)
// -----------------------------------------------------------------------
void CMopoidGameEngine::ConstructL()
{
InitComponentsL();
// Initialize random number seed
iLastFrameTime.UniversalTime();
iRandSeed = iLastFrameTime.Int64();
// Create backbuffer-bitmap (fullscreen)
TRect screenRect = CEikonEnv::Static()->EikAppUi()->ApplicationRect();
iBackBufferBmp = new (ELeave) CFbsBitmap;
User::LeaveIfError(iBackBufferBmp->Create(screenRect.Size(), EColor64K));
iBackBufferBmpDrawingDevice = CFbsBitmapDevice::NewL( iBackBufferBmp );
User::LeaveIfError( iBackBufferBmpDrawingDevice->CreateContext(iBackBufferBmpGc) );
// Initialize graphics
iSpriteHandler = CSpriteHandler::NewL();
// Load high score and settings
TRAPD(err, LoadGameProgressL());
if (err != KErrNone && err != KErrNotFound)
User::Leave(err);
// Load Sounds
LoadSoundsL();
// Remove comment below
// Set sizes of elements
iBall.iSize = (iSpriteHandler->GetSprite(MopoidShared::ESpriteBall))->SizeInPixels();
iBall.iSizeHalf = TSize(iBall.iSize.iWidth / 2, iBall.iSize.iHeight / 2);
iPanel.iSize = (iSpriteHandler->GetSprite(MopoidShared::ESpritePanel))->SizeInPixels();
iPanel.iSizeHalf = TSize(iPanel.iSize.iWidth / 2, iPanel.iSize.iHeight / 2);
// Set grid
iGrid.iUpperLeft.SetXY(0, 50);
iGrid.iBrickSize = (iSpriteHandler->GetSprite(MopoidShared::ESpriteBrickNormal))->SizeInPixels();
iGrid.Init();
// Load Levels
iLevels = new (ELeave) CMopoidLevels();
iLevels->ParseLevelFileL();
// Reset data
StartNewGame();
// initialize active object
iUpdateAO = CUpdateAO::NewL(*this, CActive::EPriorityIdle);
//iUpdateAO->Start();
}
//------------------------------------------------------------------------------
void CMopoidGameEngine::LoadSoundsL()
{
iSoundManager = new (ELeave) CSoundManager();
_LIT(KSnd1, "hit.wav");
iSoundManager->LoadSoundFileL(KSnd1, ESoundHit);
_LIT(KSnd2, "bounce.wav");
iSoundManager->LoadSoundFileL(KSnd2, ESoundBounce);
iSoundManager->SetVolume(iSettings.iSoundLevel);
}
void CMopoidGameEngine::SetSoundLevelL(TBool aOnOff)
{
// Only do something when the sound setting has been changed
iSettings.iSoundLevel = (aOnOff) ? 2 : 0;
iSoundManager->SetVolume(iSettings.iSoundLevel);
// Save the configuration changes immediately
SaveGameProgressL();
}
void CMopoidGameEngine::StartNewGame()
{
ResetBallAndPanel();
iSettings.iGameStatus = TMopoidSettings::EStarted;
iSettings.iLevel = 1;
iSettings.iLives = 3;
iSettings.iScore = 0;
iSettings.iBricksRemaining = iGrid.LoadLevel(iLevels->iLevels[(iSettings.iLevel-1)]);
iLastFrameTime.UniversalTime();
// Update our back buffer bitmap so that it shows the new scene and
// status message
DoFrame();
}
void CMopoidGameEngine::ResetBallAndPanel()
{
// Set ball
iBall.iXnew = (SCREEN_WIDTH / 2);
iBall.iYnew = 180.0 - iPanel.iSize.iHeight + iBall.iSizeHalf.iHeight;
iBall.iVx = Math::FRand(iRandSeed) * 8 - 5;
iBall.iVy = -6.0;
iBall.ConvertToPos();
// Set panel
TInt panelXPos = (SCREEN_WIDTH / 2 - iPanel.iSize.iWidth / 2);
iPanel.iPos = TPoint(panelXPos, 180);
iPanel.iX = panelXPos;
}
// -----------------------------------------------------------------------
// Initialisation function (private)
// Creates and initializes components owned by this engine.
// NOTE: Maintained by CBuilder Designer
// -----------------------------------------------------------------------
void CMopoidGameEngine::InitComponentsL()
{
/* 27.11.04 21:14 */
}
// -----------------------------------------------------------------------
// Routine that cleans up engine components owned by this Engine
// NOTE: Maintained by CBuilder Designer
// -----------------------------------------------------------------------
void CMopoidGameEngine::CleanupComponents()
{
/* 27.11.04 21:14 */
}
// -----------------------------------------------------------------------
void CMopoidGameEngine::StartTimerL()
{
// tickInterval in microseconds: 5000000 equals to 5 seconds
const TTimeIntervalMicroSeconds32 KTickInterval = 5000000;
iPeriodicTimer = CPeriodic::NewL(CActive::EPriorityLow);
iPeriodicTimer->Start(KTickInterval, KTickInterval, TCallBack(TimerCallBack, this));
}
//------------------------------------------------------------------------------
void CMopoidGameEngine::StopTimer()
{
// If the timer object exists, cancel and stop it.
if (iPeriodicTimer)
{
iPeriodicTimer->Cancel();
DELETE_AND_NULL(iPeriodicTimer);
}
}
//------------------------------------------------------------------------------
TInt CMopoidGameEngine::TimerCallBack(TAny* aObject)
{
// Call non-static method
return ((CMopoidGameEngine*)aObject)->DoCallBack();
}
//------------------------------------------------------------------------------
TInt CMopoidGameEngine::DoCallBack()
{
// Decrease score every x seconds.
if (iSettings.iGameStatus == TMopoidSettings::EPlaying &&
!iSettings.iGamePaused)
{
// Decrease score
iSettings.iScore -= 5;
// Refresh back light
User::ResetInactivityTime();
// Call again
return ETrue;
}
else
{
// Only do all that when the user is really playing!
return EFalse;
}
}
// -----------------------------------------------------------------------
TBool CMopoidGameEngine::RepeatedAction(void)
{
// Calculate the next frame.
return(DoFrame());
}
// -----------------------------------------------------------------------
void CMopoidGameEngine::CancelAsyncs(void)
{
//iSoundManager->StopAll();
}
// -----------------------------------------------------------------------
TBool CMopoidGameEngine::DoFrame(void)
{
// Check how much time has passed since we calculated the last frame
CalcTimeDifference();
// Animate panel
AnimatePanel();
// Animate ball
AnimateBall();
// Update back buffer
DrawFrame();
// Send event to system that it should do a redraw
iOwningControl->DrawDeferred();
// Only continue when we're playing.
if (iSettings.iGamePaused || iSettings.iGameStatus != TMopoidSettings::EPlaying)
{
// Make sure that pause is activated, in case we're displaying a new level message.
iSettings.iGamePaused = ETrue;
return EFalse;
}
// Send back that we want to be called again.
return ETrue;
}
// -----------------------------------------------------------------------
void CMopoidGameEngine::CalcTimeDifference()
{
TTime curFrameTime;
curFrameTime.UniversalTime();
TTimeIntervalMicroSeconds tStepMicroS = curFrameTime.MicroSecondsFrom(iLastFrameTime);
iThisFrameStep = tStepMicroS.Int64().GetTReal() / 100000.0;
// Security check if the pause between two frames was too long - limit it
// so that the ball can't jump around too much and pass through bricks.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -