📄 jewelengine.cpp
字号:
/*
* ============================================================================
* Name : CJewelEngine from JewelEngine.h
* Part of : Jewel
* Created : 02.10.2005 by Thosing
* Implementation notes:
* Version : 0.1
* Copyright: Another
* ============================================================================
*/
#include "JewelEngine.h"
#include "f32file.h"
#include <e32math.h>
//default constructor
void CJewelEngine::ConstructL(CJewelView* aJewelView) {
iGameView=aJewelView;
//jewel 7 kinds
for(int i=0; i<BOARD_SIZE_X*BOARD_SIZE_Y; i++) {
iBoardJewels[i]=Math::Random()%7;
}
iCurrentPos.SetXY(0, 0);
iJewelSelected=EFalse;
iLife=100;
//kill
iKillList = new(ELeave)CArrayFixFlat<TInt>(32);
GetMarks();
//time
iTimer = CPeriodic::NewL(EPriorityHigh);
iTimer->Start(1000000, 1000000, TCallBack(Tick, this));
//game status
iGameOver=EFalse;
}
//destructor
CJewelEngine::~CJewelEngine() {
if(iKillList) delete iKillList;
if(iTimer) delete iTimer;
}
//key
void CJewelEngine::KeyPressed(TInt aScanCode) {
if(iJewelSelected) {
TPoint swapWith=iCurrentPos;
switch(aScanCode) {
case EStdKeyLeftArrow: case EStdKeyNkp4: case '4'://left
if(iCurrentPos.iX>0) --swapWith.iX;
break;
case EStdKeyRightArrow: case EStdKeyNkp6: case '6': //right
if(iCurrentPos.iX<BOARD_SIZE_X-1) ++swapWith.iX;
break;
case EStdKeyUpArrow: case EStdKeyNkp2: case '2': //up
if(iCurrentPos.iY>0) --swapWith.iY;
break;
case EStdKeyDownArrow: case EStdKeyNkp8: case '8': //down
if(iCurrentPos.iY<BOARD_SIZE_Y-1) ++swapWith.iY;
break;
}
iJewelSelected=EFalse;
//draw board
FlushGameboard();
TInt posA=swapWith.iY*BOARD_SIZE_X+swapWith.iX;
TInt posB=iCurrentPos.iY*BOARD_SIZE_X+iCurrentPos.iX;
if(swapWith!=iCurrentPos) {
iGameView->SawpEffect(posA, posB); //swap effect
SwapJewels(posA, posB);
TInt marks=GetMarks();
if(marks>0) {
iLife+=marks;
iMark+=marks;
if(iLife>100) iLife=100;
FlushGameboard();
} else {
iGameView->SawpEffect(posA, posB);
SwapJewels(posA, posB);
}
}
} else {
switch(aScanCode) {
case EStdKeyLeftArrow: case EStdKeyNkp4: case '4':
if(iCurrentPos.iX>0) --iCurrentPos.iX;
break;
case EStdKeyRightArrow: case EStdKeyNkp6: case '6':
if(iCurrentPos.iX<BOARD_SIZE_X-1) ++iCurrentPos.iX;
break;
case EStdKeyUpArrow: case EStdKeyNkp2: case '2':
if(iCurrentPos.iY>0) --iCurrentPos.iY;
break;
case EStdKeyDownArrow: case EStdKeyNkp8: case '8':
if(iCurrentPos.iY<BOARD_SIZE_Y-1) ++iCurrentPos.iY;
break;
case EStdKeyEnter: case EStdKeyNkp5: case '5':
iJewelSelected=ETrue;
break;
}
FlushGameboard();
}
}
void CJewelEngine::FlushGameboard() {
iGameView->DrawBoard(iBoardJewels, iCurrentPos.iY*BOARD_SIZE_Y+iCurrentPos.iX, iJewelSelected);
iGameView->DrawDeferred();
}
void CJewelEngine::Delay(TInt64 aMicroSecond, TBool aRedraw) {
TTime tm1, tm2;
tm1.HomeTime();
tm2.HomeTime();
while(tm1.MicroSecondsFrom(tm2).Int64()<=aMicroSecond) {
tm1.HomeTime();
if(aRedraw)
iGameView->DrawNow();
}
}
//mark
TBool CJewelEngine::IsJewelMasked(TInt aPos) {
TInt element=aPos/sizeof(TUint);
TInt offset=aPos%sizeof(TUint);
return (iBoardMask[element] & ((TUint)1<<offset));
}
void CJewelEngine::SetJewelMasked(TInt aPos) {
TInt element=aPos/sizeof(TUint);
TInt offset=aPos%sizeof(TUint);
iBoardMask[element] |= ((TUint)1<<offset);
}
void CJewelEngine::MaskJewelsAll(TBool aMask) {
for(TInt i=0; i<BOARD_SIZE_X * BOARD_SIZE_Y / sizeof(TUint); i++) {
if(aMask)
iBoardMask[i]=~((TUint)0);
else
iBoardMask[i]=0;
}
}
//kill
TBool CJewelEngine::GetKillList(TInt aPos) {
TBool bRet=EFalse;
TInt px=aPos%BOARD_SIZE_X, py=aPos/BOARD_SIZE_Y;
TInt curID=BoardJewel(aPos);
TInt ix=px, iy=py;
while(BoardJewel(--ix, py)==curID) {}
++ix;
if(curID==BoardJewel(ix+1, py) && curID==BoardJewel(ix+2, py)) {
bRet=ETrue;
while(BoardJewel(ix, py)==curID) {
iKillList->AppendL(py*BOARD_SIZE_X+ix);
SetJewelMasked(py*BOARD_SIZE_X+ix);
ix++;
}
}
while(BoardJewel(px, --iy)==curID) {}
++iy;
if(curID==BoardJewel(px, iy+1) && curID==BoardJewel(px, iy+2)) {
bRet=ETrue;
while(BoardJewel(px, iy)==curID) {
iKillList->AppendL(iy*BOARD_SIZE_X+px);
SetJewelMasked(iy*BOARD_SIZE_X+px);
iy++;
}
}
return bRet;
}
TBool CJewelEngine::GetKillListAll() {
TBool bRet=EFalse;
for(TInt i=0; i<BOARD_SIZE_X*BOARD_SIZE_Y; i++) {
if(IsJewelMasked(i)) continue;
if(GetKillList(i)) bRet=ETrue;
}
MaskJewelsAll(EFalse);
return bRet;
}
// Flash jewels which are killed.
void CJewelEngine::FlashKilled() {
TPoint saveCurPos=iCurrentPos;
iCurrentPos=TPoint(-1, 0);
for(TInt i=0; i<FLASH_KILL_TIMES; i++) {
for(TInt j=0; j<iKillList->Count(); j++)
SetJewelMasked((*iKillList)[j]);
FlushGameboard();
Delay(5000, ETrue);
MaskJewelsAll(EFalse);
FlushGameboard();
Delay(5000, ETrue);
}
MaskJewelsAll(EFalse);
iCurrentPos=saveCurPos;
}
//Drop Jewels based on iKillList
void CJewelEngine::Drop() {
//delete killed jewels
for(TInt i=0; i<iKillList->Count(); i++) {
iBoardJewels[(*iKillList)[i]]=-1;
}
//move above down
TBool stillNeed=ETrue;
while(stillNeed) {
stillNeed=EFalse;
for(TInt pos=BOARD_SIZE_X*BOARD_SIZE_Y-1; pos>=0; pos--) {
if(iBoardJewels[pos]>=0) continue;
if(pos>=BOARD_SIZE_X) {
iBoardJewels[pos]=iBoardJewels[pos-BOARD_SIZE_X];
iBoardJewels[pos-BOARD_SIZE_X]=-1;
if(iBoardJewels[pos]==-1) stillNeed=ETrue;
} else { //First line
iBoardJewels[pos]=Math::Random() % NUM_OF_JEWELS;
}
}
}
FlushGameboard();
}
TInt CJewelEngine::GetMarks() {
TInt marks=0;
while(GetKillListAll()) {
marks+=iKillList->Count();
FlashKilled();
Drop();
iKillList->Reset();
}
return marks*marks/3;
}
//time tick
void CJewelEngine::NextTick() {
iLife--;
if(iLife<=0) {
iTimer->Cancel();
iGameOver=ETrue;
iLife=0;
//high score
if(Marks()>LoadHighScore())
SaveHighScore(Marks());
}
FlushGameboard();
}
void CJewelEngine::SaveHighScore(TInt hs) {
RFile rf;
RFs rfs;
rfs.Connect();
if(rf.Open(rfs, _L("highscore.dat"), EFileWrite)!=KErrNone)
rf.Create(rfs, _L("highscore.dat"), EFileWrite);
TBuf8<10> highScore;
highScore.Num(hs);
rf.Write(highScore);
rf.Close();
rfs.Close();
}
TInt CJewelEngine::LoadHighScore() {
RFile rf;
RFs rfs;
TBuf8<10> highScore;
rfs.Connect();
if(rf.Open(rfs, _L("highscore.dat"), EFileRead)==KErrNone) {
rf.Read(highScore);
rf.Close();
}
rfs.Close();
TInt ret=0;
TInt len=highScore.Length();
for(TInt i=0; i<len; i++) {
ret*=10;
ret+=highScore[i]-'0';
}
return ret;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -