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

📄 jewelengine.cpp

📁 symbian下的泡泡龙游戏源码,手机游戏开放新手学习的好资料
💻 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 + -