?? terris.cpp
字號:
#include <windows.h>
#include <time.h>
#include "terris.h"
const char MenuName[]=TEXT("TerrisMenu");
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInst,
LPSTR CommandLine,int CommandShow)
{
MSG msg;
if(!InitClass(hInstance))
return (0);
if(!InitWindow(hInstance))
return (0);
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (msg.wParam);
}
BOOL InitClass(HINSTANCE hInstMain)
{
WNDCLASSEX wc;
wc.cbSize=sizeof(WNDCLASSEX);
wc.style=CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc=(WNDPROC)(WndProc);
wc.cbClsExtra=0;
wc.cbWndExtra=0;
wc.hInstance=hInstMain;
wc.hIcon=LoadIcon(hInstMain,"TerrisBig");
wc.hIconSm=LoadIcon(hInstMain,"TerrisSmall");
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground=(HBRUSH)(COLOR_BTNFACE+1);
wc.lpszMenuName=MenuName;
wc.lpszClassName="Terris";
if (RegisterClassEx(&wc))
return (TRUE);
else
return (FALSE);
}
BOOL InitWindow(HINSTANCE hInstMain)
{
HWND hwnd=CreateWindowEx(WS_EX_CLIENTEDGE,
"Terris",
"Terris",
WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX | WS_VISIBLE,
CW_USEDEFAULT,CW_USEDEFAULT,300,460,
NULL,NULL,hInstMain,NULL);
if(hwnd)
return (TRUE);
else
return (FALSE);
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
static HINSTANCE hInst;
static BLOCK BlockArray[ROWS][COLS];
static TimerInterval;
static bool FlagGameJustStart = TRUE;
switch(uMsg)
{
case WM_CREATE:
hInst=((LPCREATESTRUCT)lParam)->hInstance;
TimerInterval = EasyInterval;
CheckMenuRadioItem( GetMenu(hWnd), IDM_EASY,IDM_DIFFICULT,IDM_EASY,MF_BYCOMMAND);
break;
case WM_TIMER:
if(NeedGenerateNewBlock(BlockArray))
{
KillFullLine(hWnd,BlockArray);
if(GameOver(BlockArray))
{
KillTimer(hWnd,TIMERID);
EnableMenuItem( GetMenu(hWnd ),IDM_START,MF_ENABLED);
EnableMenuItem( GetMenu(hWnd ),IDM_PAUSE,MF_GRAYED);
FlagGameJustStart = TRUE;
ChangeBlockStyleToGray(BlockArray);
RefreshWindow(hWnd,BlockArray);
MessageBox(hWnd,"對不起,請再來一盤","注意",MB_OK | MB_ICONEXCLAMATION);
}
else
{
MoveBlockFromPreviewToGameArea(hWnd,BlockArray);
GenerateNewBlock(hWnd,BlockArray);
}
}
else
{
if (CanBlockMoveDown(BlockArray))
MoveBlockDown(hWnd,BlockArray);
else
{
Moveable2Stable(BlockArray);
}
}
break;
case WM_KEYDOWN:
if ( GetMenuState(GetMenu(hWnd), IDM_START, MF_BYCOMMAND) != MF_GRAYED )
break;
switch(wParam)
{
case VK_RIGHT:
if(CanBlockMoveRight(BlockArray))
{
MoveBlockRight(hWnd,BlockArray);
}
break;
case VK_LEFT:
if(CanBlockMoveLeft(BlockArray))
{
MoveBlockLeft(hWnd,BlockArray);
}
break;
case VK_DOWN:
if(CanBlockMoveDown(BlockArray))
{
MoveBlockDown(hWnd,BlockArray);
}
break;
case VK_UP:
switch(JudgeBlockStyle(BlockArray))
{
case 0:
RotateStyleZero(hWnd,BlockArray);
break;
case 1:
RotateStyleOne(hWnd,BlockArray);
break;
case 2:
RotateStyleTwo(hWnd,BlockArray);
break;
case 3:
RotateStyleThree(hWnd,BlockArray);
break;
case 4:
RotateStyleFour(hWnd,BlockArray);
break;
case 5:
break;
case 6:
RotateStyleSix(hWnd,BlockArray);
break;
}
break;
}
break;
case WM_COMMAND:
switch (LOWORD (wParam))
{
case IDM_START:
if ( FlagGameJustStart == TRUE)
{
InitializeBlock( BlockArray );
RefreshWindow(hWnd, BlockArray );
FlagGameJustStart = FALSE;
}
SetTimer(hWnd,TIMERID,TimerInterval,NULL);
EnableMenuItem( GetMenu(hWnd), IDM_START, MF_GRAYED);
EnableMenuItem( GetMenu(hWnd), IDM_PAUSE, MF_ENABLED);
break;
case IDM_PAUSE:
KillTimer(hWnd,TIMERID);
EnableMenuItem( GetMenu(hWnd), IDM_START,MF_ENABLED);
EnableMenuItem( GetMenu(hWnd), IDM_PAUSE,MF_GRAYED);
break;
case IDM_EXIT:
if ( GetMenuState(GetMenu(hWnd), IDM_START, MF_BYCOMMAND) == MF_GRAYED)
KillTimer( hWnd,TIMERID);
DestroyWindow(hWnd);
break;
case IDM_EASY:
TimerInterval = EasyInterval;
CheckMenuRadioItem( GetMenu(hWnd),IDM_EASY,IDM_DIFFICULT,IDM_EASY,MF_BYCOMMAND);
if(GetMenuState(GetMenu(hWnd),IDM_START,MF_BYCOMMAND) == MF_GRAYED)
{
KillTimer(hWnd,TIMERID);
SetTimer(hWnd,TIMERID,TimerInterval,NULL);
}
break;
case IDM_MEDIUM:
TimerInterval = MediumInterval;
CheckMenuRadioItem( GetMenu(hWnd),IDM_EASY,IDM_DIFFICULT,IDM_MEDIUM,MF_BYCOMMAND);
if(GetMenuState(GetMenu(hWnd),IDM_START,MF_BYCOMMAND) == MF_GRAYED)
{
KillTimer(hWnd,TIMERID);
SetTimer(hWnd,TIMERID,TimerInterval,NULL);
}
break;
case IDM_DIFFICULT:
TimerInterval = DifficultInterval;
CheckMenuRadioItem( GetMenu(hWnd),IDM_EASY,IDM_DIFFICULT,IDM_DIFFICULT,MF_BYCOMMAND);
if(GetMenuState(GetMenu(hWnd),IDM_START,MF_BYCOMMAND) == MF_GRAYED)
{
KillTimer(hWnd,TIMERID);
SetTimer(hWnd,TIMERID,TimerInterval,NULL);
}
break;
case IDM_ABOUT:
DialogBoxParam(hInst,"DLG_ABOUT",hWnd,\
(DLGPROC)AboutDialogProc,(LPARAM)0);
break;
}
break;
case WM_PAINT:
hdc=BeginPaint(hWnd,&ps);
DrawBackground(hdc);
RefreshWindow(hWnd,BlockArray);
EndPaint(hWnd,&ps);
break;
case WM_DESTROY:
KillTimer(hWnd,TIMERID);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
return (0);
}
void DrawBackground(HDC hdc)
{
HBRUSH hBrush;
POINT pt[8];
pt[0].x = OriginXPos;
pt[0].y = OriginYPos + 4 * BLOCKSIZE;
pt[1].x = OriginXPos;
pt[1].y = OriginYPos + ROWS * BLOCKSIZE;
pt[2].x = pt[1].x + COLS * BLOCKSIZE;
pt[2].y = pt[1].y;
pt[3].x = pt[2].x;
pt[3].y = pt[0].y;
pt[4].x = pt[3].x + 5;
pt[4].y = pt[3].y;
pt[5].x = pt[4].x;
pt[5].y = pt[2].y + 5;
pt[6].x = pt[0].x - 5;
pt[6].y = pt[1].y + 5;
pt[7].x = pt[6].x;
pt[7].y = pt[0].y;
SelectObject(hdc,GetStockObject(NULL_PEN));
SelectObject(hdc,GetStockObject(WHITE_BRUSH));
Polygon(hdc,pt,8);
SelectObject(hdc,GetStockObject(BLACK_BRUSH));
Polygon(hdc,pt,4);
pt[0].x=OriginXPos;
pt[0].y=OriginYPos;
pt[1].x=pt[0].x + BLOCKSIZE * COLS;
pt[1].y=pt[0].y;
pt[2].x=pt[1].x;
pt[2].y=pt[1].y + BLOCKSIZE * 4;
pt[3].x=pt[0].x;
pt[3].y=pt[2].y;
hBrush=CreateSolidBrush(GetPixel(hdc,0,0));
SelectObject(hdc,hBrush);
Polygon(hdc,pt,4);
SelectObject(hdc,GetStockObject(BLACK_PEN));
SelectObject(hdc,GetStockObject(NULL_BRUSH));
DeleteObject(hBrush);
}
void DrawBlock(HDC hdc,int row,int column,int BlockStyle)
{
POINT pt[4];
COLORREF BrightBrushColor[8]={RGB(255,0,0),RGB(0,255,0),RGB(0,0,255),\
RGB(0,255,255),RGB(255,0,255),RGB(255,255,0),\
RGB(200,200,200),RGB(200,200,200)};
COLORREF MediumBrushColor[8]={RGB(180,0,0),RGB(0,180,0),RGB(0,0,180),\
RGB(0,200,200),RGB(200,0,200),RGB(200,200,0),\
RGB(90,90,90),RGB(140,140,140)};
COLORREF DarkBrushColor[8]={RGB(90,0,0),RGB(0,90,0),RGB(0,0,90),\
RGB(0,90,90),RGB(90,0,90),RGB(90,90,0),\
RGB(40,40,40),RGB(100,100,100)};
HBRUSH hBrushBright,hBrushMedium,hBrushDark;
hBrushBright=CreateSolidBrush(BrightBrushColor[BlockStyle]);
hBrushMedium=CreateSolidBrush(MediumBrushColor[BlockStyle]);
hBrushDark=CreateSolidBrush(DarkBrushColor[BlockStyle]);
SelectObject(hdc,GetStockObject(NULL_PEN));
SelectObject(hdc,hBrushBright);
pt[0].x=column* BLOCKSIZE + OriginXPos;
pt[0].y=row* BLOCKSIZE + OriginYPos;
pt[1].x=pt[0].x+BLOCKSIZE;
pt[1].y=pt[0].y;
pt[2].x=pt[1].x-3;
pt[2].y=pt[1].y+3;
pt[3].x=pt[0].x+3;
pt[3].y=pt[0].y+3;
Polygon(hdc,pt,4);
pt[0].x=column* BLOCKSIZE + OriginXPos;
pt[0].y=row* BLOCKSIZE + OriginYPos;
pt[1].x=pt[0].x+3;
pt[1].y=pt[0].y+3;
pt[3].x=pt[0].x;
pt[3].y=pt[0].y+BLOCKSIZE;
pt[2].x=pt[3].x+3;
pt[2].y=pt[3].y-3;
Polygon(hdc,pt,4);
SelectObject(hdc,hBrushMedium);
pt[0].x=column* BLOCKSIZE + OriginXPos+3;
pt[0].y=row* BLOCKSIZE + OriginYPos+3;
pt[1].x=column* BLOCKSIZE + OriginXPos+BLOCKSIZE-3;
pt[1].y=row* BLOCKSIZE + OriginYPos + 3;
pt[2].x=column* BLOCKSIZE + OriginXPos+BLOCKSIZE-3;
pt[2].y=row* BLOCKSIZE + OriginYPos+BLOCKSIZE - 3;
pt[3].x=column* BLOCKSIZE + OriginXPos +3;
pt[3].y=row* BLOCKSIZE + OriginYPos+BLOCKSIZE - 3;
Polygon(hdc,pt,4);
SelectObject(hdc,hBrushDark);
pt[0].x=column* BLOCKSIZE + OriginXPos+BLOCKSIZE;
pt[0].y=row* BLOCKSIZE + OriginYPos;
pt[1].x=pt[0].x;
pt[1].y=pt[0].y+BLOCKSIZE;
pt[2].x=pt[1].x - 3;
pt[2].y=pt[1].y - 3;
pt[3].x=pt[0].x - 3;
pt[3].y=pt[0].y + 3;
Polygon(hdc,pt,4);
pt[0].x=column* BLOCKSIZE + OriginXPos + BLOCKSIZE;
pt[0].y=row* BLOCKSIZE + OriginYPos + BLOCKSIZE;
pt[1].x=pt[0].x-BLOCKSIZE;
pt[1].y=pt[0].y;
pt[2].x=pt[1].x + 3;
pt[2].y=pt[1].y - 3;
pt[3].x=pt[0].x - 3;
pt[3].y=pt[0].y - 3;
Polygon(hdc,pt,4);
SelectObject(hdc,GetStockObject(NULL_BRUSH));
SelectObject(hdc,GetStockObject(BLACK_PEN));
DeleteObject(hBrushBright);
DeleteObject(hBrushMedium);
DeleteObject(hBrushDark);
}
void InitializeBlock(BLOCK BlockArray[ROWS][COLS])
{
int i, j;
for (i = 0; i < ROWS; i ++)
for (j = 0; j < COLS; j ++)
{
BlockArray[i][j].Flag_Is_Filled = FALSE;
BlockArray[i][j].Flag_Is_Moveable = FALSE;
BlockArray[i][j].BlockStyle = 0;
}
}
void EraseBlock(HDC hdc,int row,int column)
{
POINT pt[4];
HBRUSH hBrush;
pt[0].x=BLOCKSIZE * column + OriginXPos;
pt[0].y=BLOCKSIZE * row +OriginYPos;
pt[1].x=pt[0].x+BLOCKSIZE;
pt[1].y=pt[0].y;
pt[2].x=pt[1].x;
pt[2].y=pt[1].y+BLOCKSIZE;
pt[3].x=pt[0].x;
pt[3].y=pt[0].y+BLOCKSIZE;
if ((row >= 0) && ( row <= 3))
{
hBrush=CreateSolidBrush(GetPixel(hdc,0,0));
SelectObject(hdc,GetStockObject(NULL_PEN));
SelectObject(hdc,hBrush);
Polygon(hdc,pt,4);
SelectObject(hdc,GetStockObject(BLACK_PEN));
SelectObject(hdc,GetStockObject(NULL_BRUSH));
DeleteObject(hBrush);
}
else
{
SelectObject(hdc,GetStockObject(NULL_PEN));
SelectObject(hdc,GetStockObject(BLACK_BRUSH));
Polygon(hdc,pt,4);
SelectObject(hdc,GetStockObject(BLACK_PEN));
SelectObject(hdc,GetStockObject(NULL_BRUSH));
}
}
void MoveBlockFromSrcToDes (BLOCK BlockArray[ROWS][COLS],int SrcRow, int SrcCol, int DesRow, int DesCol)
/* 將某一個方塊從源地址移到目的地址 */
{
BlockArray[DesRow][DesCol].Flag_Is_Filled = BlockArray[SrcRow][SrcCol].Flag_Is_Filled;
BlockArray[DesRow][DesCol].Flag_Is_Moveable = BlockArray[SrcRow][SrcCol].Flag_Is_Moveable;
BlockArray[DesRow][DesCol].BlockStyle = BlockArray[SrcRow][SrcCol].BlockStyle;
BlockArray[SrcRow][SrcCol].Flag_Is_Filled = FALSE;
BlockArray[SrcRow][SrcCol].Flag_Is_Moveable = FALSE;
BlockArray[SrcRow][SrcCol].BlockStyle = 0;
}
void MoveBlockFromPreviewToGameArea(HWND hwnd, BLOCK BlockArray[ROWS][COLS])
{
int i,j;
HDC hdc;
hdc = GetDC(hwnd);
for (i = 0; i < 2; i ++)
for (j = 0 ;j < COLS; j ++)
{
if (BlockArray[ i ][ j ].Flag_Is_Filled == TRUE)
{
MoveBlockFromSrcToDes(BlockArray,i, j, i + 2, j + 3 );
DrawBlock(hdc, i + 2,j + 3, BlockArray[i + 2][j + 3 ].BlockStyle);
EraseBlock(hdc,i, j);
}
}
ReleaseDC(hwnd,hdc);
}
void GenerateNewBlock(HWND hwnd,BLOCK BlockArray[ROWS][COLS])
{
int i,j;
HDC hdc;
srand( (unsigned)time( NULL ) );
switch ( rand()%7 )
{
case 0:
BlockArray[0][0].BlockStyle=0;BlockArray[0][0].Flag_Is_Filled=TRUE;BlockArray[0][0].Flag_Is_Moveable=TRUE;
BlockArray[0][1].BlockStyle=0;BlockArray[0][1].Flag_Is_Filled=TRUE;BlockArray[0][1].Flag_Is_Moveable=TRUE;
BlockArray[0][2].BlockStyle=0;BlockArray[0][2].Flag_Is_Filled=TRUE;BlockArray[0][2].Flag_Is_Moveable=TRUE;
BlockArray[0][3].BlockStyle=0;BlockArray[0][3].Flag_Is_Filled=TRUE;BlockArray[0][3].Flag_Is_Moveable=TRUE;
break;
case 1:
BlockArray[0][1].BlockStyle=1;BlockArray[0][1].Flag_Is_Filled=TRUE;BlockArray[0][1].Flag_Is_Moveable=TRUE;
BlockArray[0][2].BlockStyle=1;BlockArray[0][2].Flag_Is_Filled=TRUE;BlockArray[0][2].Flag_Is_Moveable=TRUE;
BlockArray[1][0].BlockStyle=1;BlockArray[1][0].Flag_Is_Filled=TRUE;BlockArray[1][0].Flag_Is_Moveable=TRUE;
BlockArray[1][1].BlockStyle=1;BlockArray[1][1].Flag_Is_Filled=TRUE;BlockArray[1][1].Flag_Is_Moveable=TRUE;
break;
case 2:
BlockArray[0][0].BlockStyle=2;BlockArray[0][0].Flag_Is_Filled=TRUE;BlockArray[0][0].Flag_Is_Moveable=TRUE;
BlockArray[0][1].BlockStyle=2;BlockArray[0][1].Flag_Is_Filled=TRUE;BlockArray[0][1].Flag_Is_Moveable=TRUE;
BlockArray[0][2].BlockStyle=2;BlockArray[0][2].Flag_Is_Filled=TRUE;BlockArray[0][2].Flag_Is_Moveable=TRUE;
BlockArray[1][0].BlockStyle=2;BlockArray[1][0].Flag_Is_Filled=TRUE;BlockArray[1][0].Flag_Is_Moveable=TRUE;
break;
case 3:
BlockArray[0][0].BlockStyle=3;BlockArray[0][0].Flag_Is_Filled=TRUE;BlockArray[0][0].Flag_Is_Moveable=TRUE;
BlockArray[0][1].BlockStyle=3;BlockArray[0][1].Flag_Is_Filled=TRUE;BlockArray[0][1].Flag_Is_Moveable=TRUE;
BlockArray[0][2].BlockStyle=3;BlockArray[0][2].Flag_Is_Filled=TRUE;BlockArray[0][2].Flag_Is_Moveable=TRUE;
BlockArray[1][1].BlockStyle=3;BlockArray[1][1].Flag_Is_Filled=TRUE;BlockArray[1][1].Flag_Is_Moveable=TRUE;
break;
case 4:
BlockArray[0][0].BlockStyle=4;BlockArray[0][0].Flag_Is_Filled=TRUE;BlockArray[0][0].Flag_Is_Moveable=TRUE;
BlockArray[0][1].BlockStyle=4;BlockArray[0][1].Flag_Is_Filled=TRUE;BlockArray[0][1].Flag_Is_Moveable=TRUE;
BlockArray[1][1].BlockStyle=4;BlockArray[1][1].Flag_Is_Filled=TRUE;BlockArray[1][1].Flag_Is_Moveable=TRUE;
BlockArray[1][2].BlockStyle=4;BlockArray[1][2].Flag_Is_Filled=TRUE;BlockArray[1][2].Flag_Is_Moveable=TRUE;
break;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -