📄 unittetris.cpp
字号:
//---------------------------------------------------------------------------
#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 + -