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

📄 mopoidgameengine.cpp

📁 mopoid game symbian os application development
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	// Store the sound we're about to play so that we will only start one
	// sound in case more than one things happen at the same time.
	TMopoidSounds playSound = ENumSounds;

	// Move to a new temponary pos
	//if (iBall.Move(iThisFrameStep))
	//	playSound = ESoundHit;
	// Do not play a sound for a wall collision for now
	iBall.Move(iThisFrameStep);

	// Check collision with panel
	if (iBall.CheckPanelCollision(iPanel, iThisFrameStep))
		playSound = ESoundBounce;

	// Check collision with bricks
	TBrick::TBrickType brickColl = iBall.CheckBrickCollisionL(iGrid,
			iThisFrameStep, TBall::ECenter);
	// Also do a collision check for both sides of the ball, if no hit was found yet.
	// As we only handle one collision at once, we still check the center of the ball first to make
	// sure the main brick is hit when it's not clear which one is the main target.
	if (brickColl == TBrick::EBrickInactive)
		{
		brickColl = iBall.CheckBrickCollisionL(iGrid, iThisFrameStep,
				TBall::ELeft);
		if (brickColl == TBrick::EBrickInactive)
			{
			brickColl = iBall.CheckBrickCollisionL(iGrid, iThisFrameStep,
					TBall::ERight);
			}
		}

	// Check if a brick has been removed.
	if (brickColl == TBrick::EBrickNormal)
		{
		// Brick has been destroyed!
		iSettings->iScore += iSettings->iBlockNormalDestroyScore;
		}

	if (iGrid->GetNumBricks() == 0)
		{
		// Played through level...
		if (iSettings->iLevel < iSettings->iAvailableLevels)
			{
			// We've got another level...
			iSettings->iGameStatus = CMopoidSettings::ENewLevel;
			iSettings->iLevel ++;
			iSettings->iScore += iSettings->iScoreLevelCleared;
			iLevels.LoadLevelL(iFs, (iSettings->iLevel), iGrid, iSettings);
			SetScreenSize(iSettings->iScreenSize);
			PauseGame();
			ResetBallAndPanel();
			}
		else
			{
			// Played through game
			iSettings->iGameStatus = CMopoidSettings::EFinished;
			iSettings->iScore += iSettings->iScoreGameFinished;
			PauseGame();
			}
		}

	// If any brick was hit (doesn't matter if it was destroyed), play a sound
	if (brickColl != TBrick::EBrickInactive)
		playSound = ESoundHit;

	// Let's play the sound!
	if (playSound != ENumSounds)
		{
		TRAPD(error, iSoundManager->PlayL(playSound))
		;
		}

	// Check if we're still alive
	if (iBall.CheckDeath(iPanel))
		{
		// No, the ball has passed below the lower border.
		PauseGame();
		iSettings->iLives --;
		iSettings->iScore += iSettings->iScoreLiveLost;
		// Check if game is over.
		if (iSettings->iLives == 0)
			iSettings->iGameStatus = CMopoidSettings::EDied;
		else
			iSettings->iGameStatus = CMopoidSettings::ELifeLost;
		}

	// Copy temp pos to real pos
	iBall.ConvertToPos();
	}

// -----------------------------------------------------------------------
const TPoint CMopoidGameEngine::ConvToScreenCoord(const TPoint& aGameCoord) const
	{
	return TPoint( (TInt)((aGameCoord.iX - iSettings->iGameRectX)
			/ iSettings->iGameRectWidth * iSettings->iDrawRectWidth
			+ iSettings->iDrawRectX), (TInt)((aGameCoord.iY
			- iSettings->iGameRectY) / iSettings->iGameRectHeight
			* iSettings->iDrawRectHeight + iSettings->iDrawRectY));
	}

// -----------------------------------------------------------------------
void CMopoidGameEngine::DrawFrame() const
	{
	if (!iBackBufferBmpGc)
		return;

	// Clear back buffer
	iBackBufferBmpGc->SetPenStyle(CGraphicsContext::ENullPen);
	iBackBufferBmpGc->SetBrushColor(KRgbBlack);
	iBackBufferBmpGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
	iBackBufferBmpGc->DrawRect(iSettings->iScreenRect);
	//iBackBufferBmpGc->SetBrushColor( KRgbBlack);
	//iBackBufferBmpGc->DrawRect(iSettings->iDrawRect);

	// Set brush style to none so that transparency is drawn as transparent and not with a color (!)
	iBackBufferBmpGc->SetBrushStyle(CGraphicsContext::ENullBrush);

	// Put ball first, so that it is behind other objects should it be that at any time
	TPoint ballSpritePos(iBall.iPos.iX - iSettings->iBallSizeHalf.iWidth,
			iBall.iPos.iY - iSettings->iBallSizeHalf.iHeight);
	// TODO: Draw ball
	iBackBufferBmpGc->BitBltMasked(ConvToScreenCoord(ballSpritePos),
			iSpriteHandler->GetSprite(MopoidShared::ESpriteBall),
			iSpriteHandler->GetSprite(MopoidShared::ESpriteBall)->SizeInPixels(),
			iSpriteHandler->GetSprite(MopoidShared::ESpriteBallM), EFalse);

	// Draw bricks
	for (TInt x=0; x<iSettings->iGridCols; x++)
		{
		for (TInt y=0; y<iSettings->iGridRows; y++)
			{
			// Check if there is a brick to draw at this position
			if (iGrid->DrawBrickAtPos(x, y))
				{
				// Draw according bitmap.
				MopoidShared::TSpriteIds spriteId;
				switch (iGrid->GetBrickTypeAtPos(x, y))
					{
					case TBrick::EBrickNormal:
						spriteId = MopoidShared::ESpriteBrickNormal;
						break;
					case TBrick::EBrickDouble:
						spriteId = MopoidShared::ESpriteBrickDouble;
						break;
					case TBrick::EBrickIndestructible:
						spriteId = MopoidShared::ESpriteBrickIndestructible;
						break;
					case TBrick::EBrickMoving:
						spriteId = MopoidShared::ESpriteBrickMoving;
						break;
					case TBrick::EBrickHarderBrick:
						spriteId = MopoidShared::ESpriteBrickHarderBrick;
						break;
					case TBrick::EBrickSofterBrick:
						spriteId = MopoidShared::ESpriteBrickSofterBrick;
						break;
					default:
						spriteId = MopoidShared::ESpriteBrickNormal;
					}
				// TODO: Draw bricks
				iBackBufferBmpGc->BitBlt(
						ConvToScreenCoord(iGrid->ConvertGridToXY(x, y)),
						iSpriteHandler->GetSprite(spriteId));
				}
			}
		}

	// TODO: Draw Panel
	iBackBufferBmpGc->BitBltMasked(ConvToScreenCoord(iPanel.iPos),
			iSpriteHandler->GetSprite(MopoidShared::ESpritePanel),
			iSpriteHandler->GetSprite(MopoidShared::ESpritePanel)->SizeInPixels(),
			iSpriteHandler->GetSprite(MopoidShared::ESpritePanelM), EFalse);

	TRAPD(err, DrawTextL());
	}

// -----------------------------------------------------------------------
void CMopoidGameEngine::DrawTextL() const
	{
	// HUD
	iBackBufferBmpGc->SetPenStyle(CGraphicsContext::ESolidPen);
	iBackBufferBmpGc->SetPenColor(KRgbRed);
	iBackBufferBmpGc->UseFont(iSettings->iFontUsed);
	TBuf<30> tempStr;
	
	CEikonEnv* env = CEikonEnv::Static();

	const TInt yTextStartBottom = iSettings->iDrawRect.iTl.iY
			- iSettings->iTextBaselineOffset;

	// High Score
	env->ReadResourceL(tempStr, R_HIGHSCORE);
	tempStr.AppendNum(iSettings->iHighScore);
	iBackBufferBmpGc->DrawText(tempStr, TPoint(5, yTextStartBottom));

	// Score
	env->ReadResourceL(tempStr, R_SCORE);
	tempStr.AppendNum(iSettings->iScore);
	iBackBufferBmpGc->DrawText(tempStr, TPoint(5, yTextStartBottom
			- iSettings->iTextYOffset));

	// Level
	env->ReadResourceL(tempStr, R_LEVEL);
	tempStr.AppendNum(iSettings->iLevel);
	iBackBufferBmpGc->DrawText(tempStr, iSettings->iScreenRect,
			yTextStartBottom, CGraphicsContext::ERight, 3);

	// Lives
	env->ReadResourceL(tempStr, R_LIVES);
	tempStr.AppendNum(iSettings->iLives);
	iBackBufferBmpGc->DrawText(tempStr, iSettings->iScreenRect,
			yTextStartBottom - iSettings->iTextYOffset,
			CGraphicsContext::ERight, 3);

	// TODO: Uncomment code block

	// Draw a line between status messages and play area
	iBackBufferBmpGc->DrawLine(iSettings->iDrawRect.iTl, TPoint(
			iSettings->iDrawRect.iBr.iX, iSettings->iDrawRect.iTl.iY));

	// Draw a line at the right and left border
	if (iSettings->iDrawRect.iTl.iX > 0)
		{
		iBackBufferBmpGc->DrawLine(iSettings->iDrawRect.iTl, TPoint(
				iSettings->iDrawRect.iTl.iX, iSettings->iDrawRect.iBr.iY));
		iBackBufferBmpGc->DrawLine(iSettings->iDrawRect.iBr, TPoint(
				iSettings->iDrawRect.iBr.iX, iSettings->iDrawRect.iTl.iY));
		}

	// Title
	iBackBufferBmpGc->SetPenColor(TRgb(240, 200, 50));
	env->ReadResourceL(tempStr, R_TITLE);
	iBackBufferBmpGc->DrawText(tempStr, iSettings->iScreenRect,
			iSettings->iTextYOffset, CGraphicsContext::ECenter, 3);

	// Status messages
	TBool displayStatus = ETrue;
	switch (iSettings->iGameStatus)
		{
		case CMopoidSettings::ELifeLost:
			{
			env->ReadResourceL(tempStr, R_LIFELOST);
			}
			break;
		case CMopoidSettings::EDied:
			{
			env->ReadResourceL(tempStr, R_GAMEOVER);
			}
			break;
		case CMopoidSettings::EStarted:
		case CMopoidSettings::ENewLevel:
			{
			env->ReadResourceL(tempStr, R_ENTERLEVEL);
			tempStr.AppendNum(iSettings->iLevel);
			break;
			}
		case CMopoidSettings::EFinished:
			{
			env->ReadResourceL(tempStr, R_FINISHED);
			}
			break;
		default:
			displayStatus = EFalse;
		}
	// If there is a status message to display, show it to the user.
	if (displayStatus)
		{
		iBackBufferBmpGc->SetPenColor(KRgbRed);
		iBackBufferBmpGc->UseFont(CEikonEnv::Static()->TitleFont());
		iBackBufferBmpGc->DrawText(tempStr, iSettings->iScreenRect,
				iSettings->iScreenRect.Height() / 4 * 3, CGraphicsContext::ECenter);
		}

	}

// -----------------------------------------------------------------------
void CMopoidGameEngine::PauseGame()
	{
	// Update highscore
	if (iSettings->iScore > iSettings->iHighScore)
		{
		iSettings->iHighScore = iSettings->iScore;
		TRAPD(err, SaveGameProgressL())
		;
		}

	iSettings->iGamePaused = ETrue;

	// Stop the timer. The active object will be stopped by the DoFrame-function
	// after the next update.
	StopTimer();
	}

// -----------------------------------------------------------------------
void CMopoidGameEngine::ResumeGameL()
	{
	if (iSettings->iGameStatus == CMopoidSettings::EFinished
			|| iSettings->iGameStatus == CMopoidSettings::EDied)
		{
		// Don't resume the game, we've already played through it / we're dead.
		return;
		}

	// Make sure that the pause does not affect the regular score decrease interval
	TTime curFrameTime;
	curFrameTime.UniversalTime();
	TTimeIntervalMicroSeconds tStepMicroS =
			curFrameTime.MicroSecondsFrom(iLastFrameTime);
	iLastScoreDecreaseTime += tStepMicroS;

	iLastFrameTime.UniversalTime();
	iSettings->iGamePaused = EFalse;

	// If we were waiting for the user to do something, switch back to
	// the normal play-mode
	if (iSettings->iGameStatus == CMopoidSettings::EStarted
			|| iSettings->iGameStatus == CMopoidSettings::ENewLevel
			|| iSettings->iGameStatus == CMopoidSettings::ELifeLost)
		{
		ResetBallAndPanel();
		iSettings->iGameStatus = CMopoidSettings::EPlaying;
		}

	// Start the point-decreasing + backlight timer
	StartTimerL();
	}

//------------------------------------------------------------------------------
void CMopoidGameEngine::SaveGameProgressL()
	{
	// Add the path to the filename
	RBuf fileName;
	fileName.CleanupClosePushL();
	
	// TODO: Add the private directoy to the filename and store
	// the complete URI in the fileName descriptor.
	// The name of the file itself is stored in KMopoidDataFile.
	NCommonFunctions::AddPrivateDirL(iFs, KMopoidDataFile, fileName);

	// TODO: Open a file store
	CFileStore* store = CDirectFileStore::ReplaceLC(iFs, fileName, EFileWrite);
	store->SetTypeL(KDirectFileStoreLayoutUid);

	// TODO: Create the stream
	RStoreWriteStream stream;
	TStreamId id = stream.CreateLC(*store);

	// TODO: Write file version number
	stream.WriteInt32L(MOPOID_FILE_VERSION_NUMBER);
	// TODO: Write highscore
	stream.WriteInt32L(iSettings->iHighScore);
	// TODO: Write sound level (later step)
	stream.WriteInt32L(iSettings->iSoundLevel);

	// TODO: Commit the changes to the stream
	stream.CommitL();
	CleanupStack::PopAndDestroy(&stream);

	// TODO: Set the stream in the store and commit the store
	store->SetRootL(id);
	store->CommitL();
	CleanupStack::PopAndDestroy(store);
	CleanupStack::PopAndDestroy(&fileName);

	}

//------------------------------------------------------------------------------
void CMopoidGameEngine::LoadGameProgressL()
	{
	RBuf fileName;
	fileName.CleanupClosePushL();
	
	// TODO: Add the private directoy to the filename and store
	// the complete URI in the fileName descriptor.
	// The name of the file itself is stored in KMopoidDataFile.
	NCommonFunctions::AddPrivateDirL(iFs, KMopoidDataFile, fileName);

	// TODO: Open the file store in read mode
	CFileStore* store = CDirectFileStore::OpenLC(iFs, fileName, EFileRead);

	// TODO: Open the data stream inside the store
	RStoreReadStream stream;
	stream.OpenLC(*store, store->Root());

	// TODO: Read all the data
	TInt versionNumber = stream.ReadInt32L();
	if (versionNumber != MOPOID_FILE_VERSION_NUMBER)
		User::Leave(KErrNotFound);

	iSettings->iHighScore = stream.ReadInt32L();
	iSettings->iSoundLevel = stream.ReadInt32L();

	// TODO: Delete all the remaining stuff on the cleanup stack
	// (store, stream)
	CleanupStack::PopAndDestroy(&stream);
	CleanupStack::PopAndDestroy(store);
	CleanupStack::PopAndDestroy(&fileName);

	}

⌨️ 快捷键说明

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