正文

贪食蛇2005-09-27 15:50:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/wojiele/5418.html

分享到:

#include "UnitSnake.h"
//---------------------------------------------------------------------------
TSnakeBuf::TWall TSnakeBuf::Wall0[]={{-1}};
TSnakeBuf::TWall TSnakeBuf::Wall1[]={{5,10,23,10},{-1}};
TSnakeBuf::TWall TSnakeBuf::Wall2[]={{10,5,10,16},{18,5,18,16},{-1}};
TSnakeBuf::TWall TSnakeBuf::Wall3[]={{10,5,10,16},{18,5,18,16},{ 5,10,23,10},{-1}};
TSnakeBuf::TWall TSnakeBuf::Wall4[]={{ 5,6,23, 6},{5,14,23,14},{-1}};
TSnakeBuf::TWall TSnakeBuf::Wall5[]={{ 5,6,23, 6},{5,14,23,14},{14, 7,14,13},{-1}};
TSnakeBuf::TWall TSnakeBuf::Wall6[]={{10,0,10,16},{18,5,18,20},{-1}};
TSnakeBuf::TWall TSnakeBuf::Wall7[]={{ 0,6,23, 6},{5,14,27,14},{-1}};
TSnakeBuf::TWall TSnakeBuf::Wall8[]={{ 6,5, 6,20},{20,5,20,20},{13, 0,13,16},{-1}};
TSnakeBuf::TWall TSnakeBuf::Wall9[]={{ 0,6,15, 6},{21,0,21, 9},{12,14,27,14},{6,12,6,20},{-1}};
TSnakeBuf::TWall *TSnakeBuf::Walls[]={TSnakeBuf::Wall0,TSnakeBuf::Wall1,TSnakeBuf::Wall2,TSnakeBuf::Wall3,TSnakeBuf::Wall4,TSnakeBuf::Wall5,TSnakeBuf::Wall6,TSnakeBuf::Wall7,TSnakeBuf::Wall8,TSnakeBuf::Wall9};
//---------------------------------------------------------------------------
TSnakeBuf::TBmpPos TSnakeBuf::BmpPos[] =
{
  // Wall  Bean Super Head  Horz  Vert  CrnUL CrnUR CrnDL CrnDR TailU TailD TailL TailR Stage
  {{{4,1},{4,2},{5,2},{5,1},{4,0},{5,0},{0,1},{1,1},{0,2},{1,2},{3,1},{2,2},{2,1},{3,2},{5,2}}},
  {{{0,0},{1,0},{3,0},{2,0},{2,0},{2,0},{2,0},{2,0},{2,0},{2,0},{2,0},{2,0},{2,0},{2,0},{3,0}}},
};
//---------------------------------------------------------------------------
TSnakeBuf::TSnakeBuf()
{
  _Snake = 0;
  _iBeanNo = 0;
  _iStageBeans = 200;
  _iScore = 0;
  _bGameOver = false;
  _bEndStage = false;
  memset(_Units,0,sizeof(_Units));
  memset(_DispBuf,0,sizeof(_DispBuf));
}
//---------------------------------------------------------------------------
TSnakeBuf::~TSnakeBuf()
{
  ClearSnake();
}
//---------------------------------------------------------------------------
void TSnakeBuf::ClearSnake(void)
{
  if(_Snake)
   {
     TSnakeNode *toDel;
     _Snake->Prev->Next=0;
     while(_Snake)
      {
        toDel=_Snake;
        _Snake=_Snake->Next;
        delete toDel;
      }
     _Snake=0;
   }
}
//---------------------------------------------------------------------------
void TSnakeBuf::InitSnake(void)
{
  ClearSnake();
  _Snake = new TSnakeNode;
  TSnakeNode *nd = new TSnakeNode;

  _Snake->x = UnitX/2;
  _Snake->y = UnitY-2;
  _Snake->Next = nd;
  _Snake->Prev = nd;

  nd->x = UnitX/2;
  nd->y = UnitY-1;
  nd->Next = _Snake;
  nd->Prev = _Snake;
}
//---------------------------------------------------------------------------
void TSnakeBuf::StepMove(int d)
{
  if((_Snake)&&(d)&&(!_bGameOver)&&(!_bEndStage))
   {
     TSnakeNode NewPos = *_Snake;
     switch(d)
      {
        case sdUp   : NewPos.y--; break; //up
        case sdDown : NewPos.y++; break; //down
        case sdLeft : NewPos.x--; break; //left
        case sdRight: NewPos.x++; break; //right
        default     : return; //do nothing
      }
     if((NewPos.x<0)||(NewPos.y<0)||(NewPos.x>=UnitX)||(NewPos.y>=UnitY))
      {
        _bGameOver = true;
        return;
      }
     if(GetDispBuf(NewPos.x,NewPos.y)==sbnWall)
      {
        _bGameOver = true;
        return;
      }
     if((GetDispBuf(NewPos.x,NewPos.y)>=sbnHead)&&(GetDispBuf(NewPos.x,NewPos.y)<sbnStage))
      {
        _bGameOver = true;
        return;
      }

     bool bEat = GetUnit(NewPos.x,NewPos.y)==sbnBean || GetUnit(NewPos.x,NewPos.y)==sbnStage;
     SetUnit(NewPos.x,NewPos.y,sbnNone);
     if(bEat)
      {
        TSnakeNode *NewNode = new TSnakeNode;
        NewNode->x = NewPos.x;
        NewNode->y = NewPos.y;
        NewNode->Next = _Snake;
        NewNode->Prev = _Snake->Prev;
        _Snake->Prev->Next = NewNode;
        _Snake->Prev=NewNode;
        _Snake = NewNode;
        _iScore += ssEat;
      }
     else
      {
        _Snake = _Snake->Prev;
        _Snake->x = NewPos.x;
        _Snake->y = NewPos.y;
      }
     DrawSnake();

     if(bEat)
      if(!GenBean())
      {
        _bEndStage = true;
        _iScore += ssStage;
      }
   }
}
//---------------------------------------------------------------------------
int TSnakeBuf::GetDispBuf(int x, int y)
{
  if((x>=0) && (x<UnitX) && (y>=0) && (y<UnitY))
    return _DispBuf[y][x];
  return 0;
}
//---------------------------------------------------------------------------
int TSnakeBuf::GetUnit(int x, int y)
{
  if((x>=0) && (x<UnitX) && (y>=0) && (y<UnitY))
    return _Units[y][x];
  return 0;
}
//---------------------------------------------------------------------------
void TSnakeBuf::SetUnit(int x, int y, int n)
{
  if((x>=0) && (x<UnitX) && (y>=0) && (y<UnitY))
    _Units[y][x] = n;
}
//---------------------------------------------------------------------------
void TSnakeBuf::DrawSnake(void)
{
  memcpy(_DispBuf,_Units,sizeof(_Units));
  if(_Snake)
   {
     TSnakeNode *lpNode = _Snake->Next;
     _DispBuf[_Snake->y][_Snake->x]=sbnHead;

     while((lpNode)&&(lpNode!=_Snake))
      {
        if(lpNode->Next==_Snake)
         {
           if(lpNode->y==lpNode->Prev->y)
             _DispBuf[lpNode->y][lpNode->x] = (lpNode->x<lpNode->Prev->x?sbnTailL:sbnTailR);
           else
             _DispBuf[lpNode->y][lpNode->x] = (lpNode->y<lpNode->Prev->y?sbnTailU:sbnTailD);
         }
        else if(lpNode->y==lpNode->Prev->y)
         {
           if(lpNode->y>lpNode->Next->y)
             _DispBuf[lpNode->y][lpNode->x]=(lpNode->x<lpNode->Prev->x)?sbnCornDL:sbnCornDR;
           else if(lpNode->y<lpNode->Next->y)
             _DispBuf[lpNode->y][lpNode->x]=(lpNode->x<lpNode->Prev->x)?sbnCornUL:sbnCornUR;
           else
             _DispBuf[lpNode->y][lpNode->x]=sbnHorz;
         }
        else
         {
           if(lpNode->x<lpNode->Next->x)
             _DispBuf[lpNode->y][lpNode->x]=(lpNode->y<lpNode->Prev->y)?sbnCornUL:sbnCornDL;
           else if(lpNode->x>lpNode->Next->x)
             _DispBuf[lpNode->y][lpNode->x]=(lpNode->y<lpNode->Prev->y)?sbnCornUR:sbnCornDR;
           else
             _DispBuf[lpNode->y][lpNode->x]=sbnVert;
         }
        lpNode = lpNode->Next;
      }
   }
}
//---------------------------------------------------------------------------
void TSnakeBuf::InitStage(int StgNum)
{
  _iBeanNo = 0;
  _bGameOver = false;
  _bEndStage = false;
  memset(_Units,0,sizeof(_Units));
  memset(_DispBuf,0,sizeof(_DispBuf));
  GenWalls(StgNum);
  InitSnake();
  DrawSnake();
  GenBean();
}
//---------------------------------------------------------------------------
void TSnakeBuf::ClearScore(void)
{
  _iScore = 0;
}
//---------------------------------------------------------------------------
bool TSnakeBuf::GenBean(void)
{
  if(++_iBeanNo<=_iStageBeans)
   {
     int x = random(UnitX);
     int y = random(UnitY);

     while(GetDispBuf(x,y))
      {
        x = random(UnitX);
        y = random(UnitY);
      }

     SetUnit(x,y,_iBeanNo==_iStageBeans?sbnStage:sbnBean);
     return true;
   }
  return false;
}
//---------------------------------------------------------------------------
void TSnakeBuf::GenWalls(int StgNum)
{
  int StNo=StgNum%StageCount;
  TWall *lpWall = Walls[StNo];
  for(int i=0; lpWall[i].x1>=0; i++)
   {
     if(lpWall[i].x1==lpWall[i].x2)
      {
        for(int y=lpWall[i].y1; y<=lpWall[i].y2; y++)
         {
           SetUnit(lpWall[i].x1,y,sbnWall);
         }
      }
     else
      {
        for(int x=lpWall[i].x1; x<=lpWall[i].x2; x++)
         {
           SetUnit(x,lpWall[i].y1,sbnWall);
         }
      }
   }
}
//---------------------------------------------------------------------------
bool TSnakeBuf::fGetRunning(void)
{
  return ((_Snake)&&(!_bGameOver)&&(!_bEndStage));
}
//---------------------------------------------------------------------------
__fastcall TSnakeTimer::TSnakeTimer():TThread(false)
{
  dwTimeToWait = 300;
  hTimer = NULL;
  OnTimer = NULL;
  iSkipUserEvent = 0;
  FreeOnTerminate = true;
}
//---------------------------------------------------------------------------
void __fastcall TSnakeTimer::DestroyTimer(void)
{
  OnTimer = NULL;
  Terminate();
  SetEvent(hTimer);
}
//---------------------------------------------------------------------------
void __fastcall TSnakeTimer::SyOnStart(void)
{
  dwWaitTime = dwTimeToWait;
  iSkipUserEvent = 0;
  hTimer = CreateEvent(NULL, true, false, NULL);
}
//---------------------------------------------------------------------------
void __fastcall TSnakeTimer::SyOnExit(void)
{
  CloseHandle(hTimer);
}
//---------------------------------------------------------------------------
void __fastcall TSnakeTimer::SyOnTimer(void)
{
  if((OnTimer)&&(!iSkipUserEvent))
   {
     try
      {
        OnTimer(this);
      }
     catch(Exception &e)
      {
        //ignore user's error
      }
   }
  if(iSkipUserEvent>0)
    iSkipUserEvent--;
  ResetEvent(hTimer);
}
//---------------------------------------------------------------------------
void __fastcall TSnakeTimer::Execute(void)
{
  Synchronize(SyOnStart);
  while(!Terminated)
   {
     WaitForSingleObject(hTimer,dwWaitTime);
     if(!Terminated)
      {
        Synchronize(SyOnTimer);
      }
   }
  Synchronize(SyOnExit);
}
//---------------------------------------------------------------------------
void __fastcall TSnakeTimer::fSetInterval(DWORD dwIntv)
{
  dwWaitTime = dwTimeToWait = dwIntv;
  iSkipUserEvent = 1;
  TriggerTimer();
}
//---------------------------------------------------------------------------
void __fastcall TSnakeTimer::TriggerTimer(int iWait)
{
  if(hTimer)
   {
     if(iWait>0)
       iSkipUserEvent = iWait+1;
     SetEvent(hTimer);
   }
}
//---------------------------------------------------------------------------

阅读(5284) | 评论(3)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

loading...
您需要登录后才能评论,请 登录 或者 注册