CGameTetris.cpp
上传用户:snevogroup
上传日期:2008-06-06
资源大小:432k
文件大小:8k
- // 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));
- }
- }
- }
- }