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

📄 cgametetris.cpp

📁 Symbian开发提高的一个很好的实例,其实现了一个非常好理解的Symbian游戏开发流程
💻 CPP
字号:
// 2005-8-31 修正了按键响应慢的错误
#include <e32base.h>
#include <eikenv.h>
#include <e32Math.h>

#include "CGameTetris.h"
#include <images.mbg>


// construct and destruct

// NewL()
CGameTetris* CGameTetris::NewL()
{
	CGameTetris* self = new (ELeave) CGameTetris;
	CleanupStack::PushL(self);

	self->ConstructL();

	CleanupStack::Pop(self);

	return self;
}


// CGameTetris()
CGameTetris::CGameTetris() : iGrid()
{}


// ~
CGameTetris::~CGameTetris()
{
	iBmpBlock.DeleteAll();
	delete iBmpBackground;
}

void CGameTetris::ConstructL()
{
	// load game resource
	LoadResL();

	// Make the seed
	TTime time;
	time.HomeTime();
	iSeed = time.Int64();
}

////////////////////////////////////////////////////////////////////////////////

// Method

// handel all key relatively
TBool CGameTetris::Command(TInt aCommand)
{
	switch(aCommand)
	{
		case EKeyRightArrow :			// right
		case '6' :
		{
			MoveTo(iBlockPos + TPoint(1, 0));	
		}return 1;

		case EKeyLeftArrow :			// left
		case '4' :
		{
			MoveTo(iBlockPos + TPoint(-1, 0));
		}return 1;

		case EKeyUpArrow :				// up
		case '2' :
		case '5' :
		case 63557 :
		{
			Rotate();
		}return 1;

		case EKeyDownArrow :			// down
		case '8' :
		{
			while(MoveTo(iBlockPos + TPoint(0, 1)));
		}return 1;

		default:return 0;
	}
}

// move down the block automatic
TInt8 CGameTetris::Run()
{
	TInt8 flag = 0;				// default not update view
	
	if(!iStateRunning)			// game is not running
	{
		iStateRunning = 1;
		StartNewGame();
	}
	else
	{
		if(!iDelay)
		{
			if(!MoveTo(iBlockPos + TPoint(0, 1)))	// if can't move down the block
			{
				if(!FixBlock())		// check if the block is out of bound
				{
					iStateRunning = 0;
					return 1;		// Game over
				}
				TInt eliminate = CheckRows();
				
				if(eliminate)
				{
					Calculate(eliminate);
					if(eliminate == 4)
						iStateWellDone = 1;	// well done
					iStateClearRow = 1;	//  explode sound
				}

				NewBlock();		// create a new one
			}
			flag = 2;			// update view
		}
	
		iDelay = iDelay ? --iDelay : 10-iLevel;
	}

	return flag;
}

// Draw()
void CGameTetris::Draw(CFbsBitGc* aBackBufferGc)
{
	TInt xPos, yPos;
	TUint8 i, j;
	// draw background
	aBackBufferGc->BitBlt(TPoint(0, 0), iBmpBackground);

	// draw blocks
	yPos = 0;
	TFixedArray<TUint8, KGridX> arr;
	for(i = 0; i < KGridY; i++)
	{
		xPos = 9;
		GetRowContent(i, arr);
		for(j = 0; j < KGridX; j++)
		{
			TUint8 blockType = arr[j];
			if(blockType)
			{
				TPoint pos = TPoint(xPos, yPos);
		 		aBackBufferGc->BitBlt(pos, iBmpBlock.At(blockType%COLORNUM));
			}
			xPos += 9;
		}
		yPos += 10;
	}

	// draw Info
	const CFont* font;
	font = CEikonEnv::Static()->NormalFont();
	aBackBufferGc->UseFont(font);
	aBackBufferGc->SetPenColor(TRgb(215, 136, 20));
	aBackBufferGc->SetBrushStyle(CGraphicsContext::ENullBrush);

	TBuf<6> info;
	// score
	info.Num(iStateScore);
	aBackBufferGc->DrawText(info, TRect(TPoint(122, 90), TSize(45, 15)), 15, CGraphicsContext::ECenter, 0);
	// line
	info.Num(iLine);
	aBackBufferGc->DrawText(info, TRect(TPoint(122, 118), TSize(45, 15)), 15, CGraphicsContext::ECenter, 0);
	// Level
	info.Num(iLevel);
	aBackBufferGc->DrawText(info, TRect(TPoint(122, 145), TSize(45, 15)), 15, CGraphicsContext::ECenter, 0);

	aBackBufferGc->DiscardFont();

	// draw Next Block
	aBackBufferGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
	aBackBufferGc->SetBrushColor(KRgbBlack);
	yPos = 29;
	for(i = 0; i < 4; i++)
	{
		xPos = 130;
		for(j = 0; j < 4; j++)
		{
			if((iBlockNext.RowMask(i) & (1<<(3-j))))
				aBackBufferGc->DrawRect(TRect(TPoint(xPos, yPos), TSize(6, 6)));
			xPos += 7;
		}
		yPos += 7;
	}
}

////////////////////////////////////////////////////////////////////////////////

// Other Methods

// MoveTo()			Move the Block to a new position if possible
TBool CGameTetris::MoveTo(const TPoint& aNewPos)
{
	if(iGrid.DoesCollide(iBlock, aNewPos))
		return 0;

	iBlockPos = aNewPos;		// don't update View here to make Model Independent

	return 1;					// Move successful
}

// Rotate()
void CGameTetris::Rotate()
{
	if(iStateRotateDir == 0)
		iStateRotateDir = -1;
	iBlock.Rotate(iStateRotateDir);		// default state , deasil

	if(iGrid.DoesCollide(iBlock, iBlockPos))
		iBlock.Rotate( (TInt8)-iStateRotateDir );	// rotate back	
}


// NewBlock()
void CGameTetris::NewBlock()
{
	iBlock		= iBlockNext;
	iBlockNext	= TBlock::RandomBlock(iSeed, iStateDifficulty);

	iBlockPos     = TPoint(4, -3);
}

// StartNewGame()
void CGameTetris::StartNewGame()
{
	// Game State
	iLevel				= 1;
	iLine				= 0;
	iStateScore			= 0;
	//iStateRotateDir	= 0;
	//iStateDifficulty	= 0;

	// create new Grid
	iGrid			= TGrid::NewGrid();
	// Start Lines
	if(iStateStartLines)
		StartLines(iStateStartLines);
		//StartLines(18);
	// create a block
	iBlockNext	= TBlock::RandomBlock(iSeed, iStateDifficulty);

	NewBlock();

	iDelay = 0;
}

// GetRowContent()			
void CGameTetris::GetRowContent(TUint8 aRow, TFixedArray<TUint8, KGridX>& aRowContent)
{
	int i;

	for(i = 0; i < KGridX; i++)
	{
		if(IsBlock(TPoint(i, aRow))) 
			aRowContent[i] = iBlock.Type();
		else 
			aRowContent[i] = iGrid.iContent[aRow][i];
	}
}

// if the position is a block
TBool CGameTetris::IsBlock(const TPoint& aPos) const
{
	if(TRect(iBlockPos, TSize(4, 4)).Contains(aPos))
		return (iBlock.RowMask(aPos.iY-iBlockPos.iY) & (1<<(3-aPos.iX+iBlockPos.iX))) > 0;

	return false;
}

// FixBlock()	-- fix the block  -- be called if the current block can't move 
// @ return 0	-- game over
// @ return 1	-- continue game and put the block into the content
TBool CGameTetris::FixBlock()
{
	TInt i;
	// check if it is outside the board
	for (i = 0; i < -iBlockPos.iY; i++)
		if (iBlock.RowMask(i))
			return 0;

	iGrid.PutBlock(iBlock, iBlockPos);
		return 1;
}

// 
TInt CGameTetris::CheckRows()
{
	TInt offset=0, i, j;

	for (i = KGridY-1; i >= 0; i--)
	{
		if (iGrid.iMask[i]==0xffffU)
		{
			offset++;
			iLine++;
			continue;
		}

		if (offset > 0)
		{
			iGrid.iMask[i+offset]=iGrid.iMask[i];
			for (j = 0; j < KGridX; j++)
				iGrid.iContent[i+offset][j]=iGrid.iContent[i][j];
		}
	}

	for (i = 0; i < offset; i++)
	{
		iGrid.iMask[i] = 0x003f;
		for (j=0; j < KGridX; j++)
			iGrid.iContent[i][j] = 0;
	}

	return offset;		// row's num to eliminate
}

void CGameTetris::Calculate(TInt rows)
{
	switch(rows)
	{
		case 1:
		{
			iStateScore += 10;
		}break;

		case 2:
		{
			iStateScore += 25;
		}break;

		case 3:
		{
			iStateScore += 50;
		}break;

		case 4:
		{
			iStateScore += 80;
			iStateWellDone = ETrue;
		}break;

		default:break;
	}
	iStateClearRow = ETrue;
	iStateScore += iStateDifficulty * 15;
	iStateScore += iStateStartLines;
	iStateScore += iLevel * 2;

	if(iStateScore >= 500 * iLevel)
	{
		iLevel++;
		iStateLevelUp = ETrue;
	}
	if(iLevel > 10)
	{
		iLevel = 0;
		iStateDifficulty++;
		iStateDifficulty %= 3;
	}
	
}
// 
void CGameTetris::LoadResL()
{
	// Load bmps from mmp file
	_LIT(KPathName, "\\System\\Apps\\Tetris\\images.mbm");
	
	CEikonEnv* eikonEnv = CEikonEnv::Static();
	
	// Load Blocks
	iBmpBlock.At(0) = eikonEnv->CreateBitmapL(KPathName, EMbmImages1);
	iBmpBlock.At(1) = eikonEnv->CreateBitmapL(KPathName, EMbmImages2);
	iBmpBlock.At(2) = eikonEnv->CreateBitmapL(KPathName, EMbmImages3);
	iBmpBlock.At(3) = eikonEnv->CreateBitmapL(KPathName, EMbmImages4);
	iBmpBlock.At(4) = eikonEnv->CreateBitmapL(KPathName, EMbmImages5);
	iBmpBlock.At(5) = eikonEnv->CreateBitmapL(KPathName, EMbmImages6);
	iBmpBlock.At(6) = eikonEnv->CreateBitmapL(KPathName, EMbmImages7);
	iBmpBlock.At(7) = eikonEnv->CreateBitmapL(KPathName, EMbmImages8);
	iBmpBlock.At(8) = eikonEnv->CreateBitmapL(KPathName, EMbmImages9);
	// Load background
	iBmpBackground = eikonEnv->CreateBitmapL(KPathName, EMbmImagesBackground24);
}

void CGameTetris::StartLines(TUint8 aLines)
{
	if(aLines >= 19)
		return ;
	
	TInt i, j;
	for(i = KGridY - 1; i >= KGridY - aLines; --i)
	{
		for(j = 0; j < KGridX; ++j)
		{
			TInt content = Math::Rand(iSeed) % 2;
			if(content)
			{
				iGrid.iContent[i][j] = (TInt8)(Math::Rand(iSeed) % BLOCKNUM + 1);
			
				iGrid.iMask[i] |= (1 << (15 - j));
			}
		}
	}

}

⌨️ 快捷键说明

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