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

📄 unittetris.cpp

📁 俄罗斯方块双打版
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//---------------------------------------------------------------------------
#ifndef STRICT
#  define STRICT
#endif

#include <vcl.h>
#pragma hdrstop

#include "UnitTetris.h"
#include "UnitEnterName.h"
#include "UnitAbout.h"
#include "UnitSpeed.h"
#include <stdio.h>
#include <mmsystem.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "VictorDDraw8"
#pragma resource "*.dfm"
TFormTetris *FormTetris;
//---------------------------------------------------------------------------
__fastcall TFormTetris::TFormTetris(TComponent* Owner)
    : TForm(Owner)
{
  Font->Name    = "宋体";
  Font->Charset = GB2312_CHARSET;
  Font->Size    = 9;

  _bSingle=false;
  LnLeft=LnRight=0;
  _bGameOverL = _bGameOverR=false;
  _iKeyDelay = 5;
  _iLeftDown = _iRightDown = 0;
  _iLeftLeft = _iLeftRight = 0;
  _iRightLeft = _iRightRight = 0;

  nSysTimeInterval = timeBeginPeriod(1);
  nTimerMainInterval = 400;
  nTimerDownInterval = 30;
  iTimerMainC0 = iTimerDownC0 = timeGetTime();
  iTimerMainC1 = iTimerDownC1 = timeGetTime();

  iFrames = 0;
  iFrmCnt = 0;
  *Str_L_Lines   = 0;
  *Str_L_Score   = 0;
  *Str_R_Lines   = 0;
  *Str_R_Score   = 0;
  *Str_Speed     = 0;
  *Str_HighScore = 0;
  *Str_Fps       = 0;

  LoadParams();
  Paused = false;
  Application->Title = "俄罗斯方块";
  Caption = Application->Title;

  if(!VictorDDraw81->Windowed)
   {
     SetWindowLong(Handle,GWL_STYLE,WS_POPUP);
     Left = 0;
     Top = 0;
     Width = VictorDDraw81->ScreenWidth;
     Height = VictorDDraw81->ScreenHeight;
     iSurfaceWidth = VictorDDraw81->ScreenWidth;
     iSurfaceHeight = VictorDDraw81->ScreenHeight;
   }
  else
   {
     iSurfaceWidth = ClientWidth;
     iSurfaceHeight = ClientHeight;
   }
  bDisplayEnabled = true;
  VictorDDraw81->Active = true;

  BkSur = new TDDrawSurface(VictorDDraw81->Display);
  SgSur = new TDDrawSurface(VictorDDraw81->Display);
  OvSur = new TDDrawSurface(VictorDDraw81->Display);
  PsSur = new TDDrawSurface(VictorDDraw81->Display);
  TtSur = new TDDrawSurface(VictorDDraw81->Display);

  InitSurfaces();
  LoadSurfaces();
}
//---------------------------------------------------------------------------
__fastcall TFormTetris::~TFormTetris()
{
  if(BkSur){delete BkSur; BkSur=NULL;}
  if(SgSur){delete SgSur; SgSur=NULL;}
  if(OvSur){delete OvSur; OvSur=NULL;}
  if(PsSur){delete PsSur; PsSur=NULL;}
  if(TtSur){delete TtSur; TtSur=NULL;}

  timeEndPeriod(nSysTimeInterval);
}
//---------------------------------------------------------------------------
void __fastcall TFormTetris::InitSurfaces(void)
{
  Graphics::TBitmap *Bmp = new Graphics::TBitmap;
    Bmp->Dormant();Bmp->FreeImage();Bmp->LoadFromResourceName(0,"BMP_BLOCKS");
    TtSur->Create(Bmp->Width,Bmp->Height);

    Bmp->Dormant();Bmp->FreeImage();Bmp->LoadFromResourceName(0,"BMP_PAUSED");
    PsSur->Create(Bmp->Width,Bmp->Height);

    Bmp->Dormant();Bmp->FreeImage();Bmp->LoadFromResourceName(0,"BMP_GMOVER");
    OvSur->Create(Bmp->Width,Bmp->Height);

    Bmp->Dormant();Bmp->FreeImage();Bmp->LoadFromResourceName(0,"BMP_SINGLE");
    SgSur->Create(Bmp->Width,Bmp->Height);

    BkSur->Create(iSurfaceWidth,iSurfaceHeight);
  delete Bmp;
}
//---------------------------------------------------------------------------
void __fastcall TFormTetris::LoadSurfaces(void)
{
  Graphics::TBitmap *Bmp = new Graphics::TBitmap;
    Bmp->Dormant();Bmp->FreeImage();Bmp->LoadFromResourceName(0,"BMP_BLOCKS");
    TtSur->DrawBitmap(Bmp->Handle);
    TtSur->ColorKey = (Bmp->Canvas->Pixels[Bmp->Width-1][Bmp->Height-1])&0x00ffffff;

    Bmp->Dormant();Bmp->FreeImage();Bmp->LoadFromResourceName(0,"BMP_PAUSED");
    PsSur->DrawBitmap(Bmp->Handle);
    PsSur->ColorKey = (Bmp->Canvas->Pixels[Bmp->Width-1][Bmp->Height-1])&0x00ffffff;

    Bmp->Dormant();Bmp->FreeImage();Bmp->LoadFromResourceName(0,"BMP_GMOVER");
    OvSur->DrawBitmap(Bmp->Handle);
    OvSur->ColorKey = (Bmp->Canvas->Pixels[Bmp->Width-1][Bmp->Height-1])&0x00ffffff;

    Bmp->Dormant();Bmp->FreeImage();Bmp->LoadFromResourceName(0,"BMP_SINGLE");
    SgSur->DrawBitmap(Bmp->Handle);
    SgSur->ColorKey = (Bmp->Canvas->Pixels[Bmp->Width-1][Bmp->Height-1])&0x00ffffff;

    int x0,y0,x1,y1;
    int bw, bh, ww = iSurfaceWidth, hh = iSurfaceHeight;
    HDC hDC;

    BkSur->DDrawSurface->Restore();
    BkSur->DDrawSurface->GetDC(&hDC);

    Bmp->Dormant();Bmp->FreeImage();Bmp->LoadFromResourceName(0,"BMP_BKGND");
    bw=Bmp->Width; bh=Bmp->Height;
    for(int y=0; y<hh; y+=bh)
     for(int x=0; x<ww; x+=bw)
      ::BitBlt(hDC,x,y,Bmp->Width,Bmp->Height,Bmp->Canvas->Handle,0,0,SRCCOPY);

    Bmp->Dormant();Bmp->FreeImage();Bmp->LoadFromResourceName(0,"BMP_KKBK");
    ww = TBaseTetris::MapXsize*BlockSize;
    hh = TBaseTetris::MapYsize*BlockSize;
    for(int y=0; y<hh; y+=bh)
     for(int x=0; x<ww; x+=bw)
      {
        bw=Bmp->Width<ww-x?Bmp->Width:ww-x;
        bh=Bmp->Height<hh-y?Bmp->Height:hh-y;
        ::BitBlt(hDC,BlockLL+x,BlockTop+y,bw,bh,Bmp->Canvas->Handle,0,0,SRCCOPY);
        ::BitBlt(hDC,BlockRL+x,BlockTop+y,bw,bh,Bmp->Canvas->Handle,0,0,SRCCOPY);
      }

     TCanvas *BkCanvas = new TCanvas;
     BkCanvas->Handle = hDC;
      for(int i=BlockLL; i<=BlockRL; i+=BlockRL-BlockLL)
       {
         x0=i-2; y0=BlockTop-2; x1=x0+ww+2; y1=y0+hh+2;
         BkCanvas->Pen->Color = TColor(RGB(128,128,128));
         BkCanvas->MoveTo(x0,y1); BkCanvas->LineTo(x0,y0); BkCanvas->LineTo(x1,y0);
         BkCanvas->Pen->Color = TColor(RGB(223,223,223));
         BkCanvas->MoveTo(x1,y0); BkCanvas->LineTo(x1,y1); BkCanvas->LineTo(x0,y1);
         BkCanvas->Pen->Color = TColor(RGB(64,64,64));
         BkCanvas->MoveTo(x0+1,y1-1); BkCanvas->LineTo(x0+1,y0+1); BkCanvas->LineTo(x1-1,y0+1);
         BkCanvas->Pen->Color = TColor(RGB(255,255,255));
         BkCanvas->MoveTo(x1-1,y0+1); BkCanvas->LineTo(x1-1,y1-1); BkCanvas->LineTo(x0+1,y1-1);
       }
    delete BkCanvas;

    BkSur->DDrawSurface->ReleaseDC(hDC);
  delete Bmp;
}
//---------------------------------------------------------------------------
void __fastcall TFormTetris::WndProc(Messages::TMessage &Message)
{
  TForm::WndProc(Message);
  if(Message.Msg==WM_MOVE)
   {
     if((VictorDDraw81->Active)&&(VictorDDraw81->Windowed))
       VictorDDraw81->UpdateBounds();
   }
}
//---------------------------------------------------------------------------
void __fastcall TFormTetris::DrawTetris(TDDrawDisplay *lpDisplay, TBaseTetris *lpTetris, int x0, int y0, bool bPlaySingle)
{
  int bw,ww = TBaseTetris::MapXsize*BlockSize;
  int bh,hh = TBaseTetris::MapYsize*BlockSize;
  RECT rc = {0,0,0,0};

  int n,p;
  rc.top = 0; rc.bottom = BlockSize;
  for(int y=0; y<TBaseTetris::MapYsize; y++)
   for(int x=0; x<TBaseTetris::MapXsize; x++)
    {
      if((n=lpTetris->DisplayBuffer->TetrisBuffer[y][x])>0)
       {
         if(n==16)if((p=lpTetris->TetrisBuffer->TetrisBuffer[y][x])>0)
          {
            rc.left = (p-1)*BlockSize;
            rc.right = rc.left + BlockSize;
            lpDisplay->Blt(x0+x*BlockSize,y0+y*BlockSize,TtSur->DDrawSurface,&rc,DDBLTFAST_SRCCOLORKEY);
          }

         rc.left = (n-1)*BlockSize;
         rc.right = rc.left + BlockSize;
         lpDisplay->Blt(x0+x*BlockSize,y0+y*BlockSize,TtSur->DDrawSurface,&rc,DDBLTFAST_SRCCOLORKEY);
       }
    }

  TDDrawSurface *lpSur = NULL;
  if(_bSingle&&!bPlaySingle)
    lpSur = SgSur;
  else if(lpTetris->GameOver)
    lpSur = OvSur;
  else if(Paused)
    lpSur = PsSur;

  if(lpSur)
   {
     bw = lpSur->SurfaceDesc.dwWidth;
     bh = lpSur->SurfaceDesc.dwHeight;
     rc.left=rc.top=0;
     rc.right=bw;rc.bottom=bh;
     lpDisplay->Blt(x0+(ww-bw)/2,y0+(hh-bh)/2,lpSur->DDrawSurface,&rc,DDBLTFAST_SRCCOLORKEY);
   }
}
//---------------------------------------------------------------------------
void __fastcall TFormTetris::DrawIncoming(TDDrawDisplay *lpDisplay, TBaseTetris *lpTetris, int x0, int y0)
{
  RECT rc;
  int n;

  rc.top = 0; rc.bottom = BlockSize;
  for(int y=0; y<4; y++)
   for(int x=0; x<4; x++)
    {
      if((n=lpTetris->IncomingUnits->un[lpTetris->IncomingUnits->r][y][x])>0)
       {
         rc.left = (n-1)*BlockSize;
         rc.right = rc.left + BlockSize;
         lpDisplay->Blt(x0+x*BlockSize,y0+y*BlockSize,TtSur->DDrawSurface,&rc,DDBLTFAST_SRCCOLORKEY);
       }
    }
}
//---------------------------------------------------------------------------
void __fastcall TFormTetris::VictorDDraw81DispFrame(TCustomDDraw8 *Sender)
{
  Sender->Display->Blt(0,0,BkSur);

  DrawTetris(Sender->Display, &TetrisLeft, 8,8, false);
  DrawTetris(Sender->Display, &TetrisRight, 296,8, true);

  DrawIncoming(Sender->Display, &TetrisLeft, 204,8);
  DrawIncoming(Sender->Display, &TetrisRight, 204,8+BlockSize*4+8);

  HDC hDC;
  Sender->BackBuffer->GetDC(&hDC);
    TCanvas *lpCanvas = new TCanvas;
      lpCanvas->Handle = hDC;

      lpCanvas->Brush->Style = bsClear;
      lpCanvas->Font->Color = clBlack;

      lpCanvas->TextOut(200,200,Str_L_Lines  );
      lpCanvas->TextOut(200,216,Str_L_Score  );
      lpCanvas->TextOut(200,240,Str_R_Lines  );
      lpCanvas->TextOut(200,256,Str_R_Score  );
      lpCanvas->TextOut(200,280,Str_Speed    );
      lpCanvas->TextOut(200,296,Str_HighScore);
      lpCanvas->TextOut(200,328,Str_Fps      );
      lpCanvas->TextOut(216,384,"C++爱好者"  );
      lpCanvas->TextOut(208,400,"cppfans.com");

    delete lpCanvas;
  Sender->BackBuffer->ReleaseDC(hDC);
  iFrmCnt++;
}
//---------------------------------------------------------------------------
void __fastcall TFormTetris::VictorDDraw81RestoreFrame(TCustomDDraw8 *Sender)
{
  LoadSurfaces();
}
//---------------------------------------------------------------------------
void __fastcall TFormTetris::EvTimerMainTimer(void)
{
  iFrames=iFrmCnt; iFrmCnt=0;
  sprintf(Str_Fps,"FPS.: %d", iFrames*1000/nTimerMainInterval);

  if((!TetrisLeft.GameOver)&&(TetrisLeft.Started)&&(!Paused))
    TetrisLeft.Move(TBaseTetris::btmDown);
  if((!TetrisRight.GameOver)&&(TetrisRight.Started)&&(!Paused))
    TetrisRight.Move(TBaseTetris::btmDown);
  CheckGameStatus();
}
//---------------------------------------------------------------------------
void __fastcall TFormTetris::EvTimerDownTimer(void)
{
  int KeyL=0, KeyR=0;

  if(TestKeyDown(_iLeftLeft ))KeyL=TBaseTetris::btmLeft;
  if(TestKeyDown(_iLeftRight))KeyL=TBaseTetris::btmRight;
  if(TestKeyDown(_iLeftDown ))KeyL=TBaseTetris::btmDown;

  if(TestKeyDown(_iRightLeft ))KeyR=TBaseTetris::btmLeft;
  if(TestKeyDown(_iRightRight))KeyR=TBaseTetris::btmRight;
  if(TestKeyDown(_iRightDown ))KeyR=TBaseTetris::btmDown;

  if(KeyL)
   if((!TetrisLeft.GameOver)&&(TetrisLeft.Started)&&(!Paused)&&(!TetrisLeft.Busy))
    TetrisLeft.Move(KeyL);
  if(KeyR)
   if((!TetrisRight.GameOver)&&(TetrisRight.Started)&&(!Paused)&&(!TetrisRight.Busy))
    TetrisRight.Move(KeyR);
  CheckGameStatus();
}
//---------------------------------------------------------------------------
bool __fastcall TFormTetris::TestKeyDown(int &iKey)
{
  if(iKey>_iKeyDelay)
    return true;
  if(iKey>0)
    iKey++;
  return false;
}
//---------------------------------------------------------------------------
void __fastcall TFormTetris::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
{
  if((!TetrisLeft.GameOver)&&(TetrisLeft.Started)&&(!Paused)&&(!TetrisLeft.Busy))
   {
     int btm = 0;
     switch(Key)
      {
        case 'A':
        case 'a': if(!_iLeftLeft)
                   {
                     btm=TBaseTetris::btmLeft;
                     _iLeftLeft=1;
                   }
                  break;
        case 'D':
        case 'd': if(!_iLeftRight)
                   {
                     btm=TBaseTetris::btmRight;
                     _iLeftRight=1;
                   }

⌨️ 快捷键说明

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