/******************************************
* 俄罗斯方块V1.0 最后修改2012-2-14-0:13 *
******************************************/
#include "head.h"
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int iCmdShow)
{
const int CXFULLSCREEN = GetSystemMetrics(SM_CXFULLSCREEN);
const int CYFULLSCREEN = GetSystemMetrics(SM_CYFULLSCREEN);
static TCHAR szAppName[] = TEXT("Tetris");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if (!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("This program requires Windows NT!"),
szAppName, MB_ICONERROR);
return 0;
}
hwnd = CreateWindow(szAppName, TEXT("俄罗斯方块"),
WS_OVERLAPPED | WS_CAPTION
| WS_SYSMENU | WS_MINIMIZEBOX,
(CXFULLSCREEN - WIN_WIDTH) / 2,
(CYFULLSCREEN - WIN_HEIGHT) / 2,
WIN_WIDTH, WIN_HEIGHT,
NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
/* 游戏中沉底的方块 */
int Block_Interface[BLOCK_X_TOTAL + 1][BLOCK_Y_TOTAL + 2];
/* 沉底方块的基本坐标 */
POINT pt[] = {
12, 12,
30, 12,
30, 30,
12, 30
};
/* 初始画刷 */
const HBRUSH hFirstBrush = CreateSolidBrush(RGB(150, 150, 150));
int BlockStyle; /* 预览方块的种类 */
int ChangeBlockStyle; /* 变换方块的种类 */
int ChangeTime = 0; /* 方块变换次数 */
POINT ShowBlock[4][4]; /* 下落组合方块坐标 */
POINT PreviewShowBlock[4][4]; /* 预览组合方块坐标 */
LRESULT CALLBACK WndProc(HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
int x, y; /* 循环变量 */
static int Level_time; /* 定时器回调间隔时间 */
static int iScore; /* 玩家的所得的分数 */
static int iLevel; /* 当前游戏的难度 */
/* 玩家的分数字符串 */
static TCHAR szScore[100] = {'0', '\0'};
/* 当前的游戏等级字符串 */
static TCHAR szLevel[10] = {'0', '\0'};
HDC hdc;
PAINTSTRUCT ps;
POINT TmpPt[4];
switch (message)
{
case WM_CREATE:
{
/* 除了左右边界和最下边界不为0,其余都为0 */
for (x = 0; x < BLOCK_X_TOTAL; x++)
{
for (y = 1; y <= BLOCK_Y_TOTAL; y++)
{
Block_Interface[x][y] = 0;
}
}
/* 将最下边界置1 */
for (y = 0; y <= BLOCK_Y_TOTAL + 1; y++)
{
Block_Interface[BLOCK_X_TOTAL][y] = 1;
}
/* 将左右边界置1 */
for (x = 0; x < BLOCK_X_TOTAL; x++)
{
Block_Interface[x][0] = 1;
Block_Interface[x][BLOCK_Y_TOTAL + 1] = 1;
}
iScore = 0;
iLevel = 1;
itoa(iLevel, szLevel, 10);
itoa(iScore, szScore, 10);
srand((unsigned)time(NULL));
BlockStyle = rand() % 7;
Level_time = 800;
SetTimer(hwnd, TIMER_ID, Level_time, TimerProc);
return 0;
}
case WM_KEYDOWN:
{
int x, y;
ClearShowBlock(hwnd);
switch (wParam)
{
case VK_LEFT:
{
if (!IsLbarrier())
{
for (x = 0; x < 4; x++)
{
for (y = 0; y < 4; y++)
{
ShowBlock[x][y].x -= BLOCK_STEP;
}
}
}
break;
}
case VK_RIGHT:
{
if (!IsRbarrier())
{
for (x = 0; x < 4; x++)
{
for (y = 0; y < 4; y++)
{
ShowBlock[x][y].x += BLOCK_STEP;
}
}
}
break;
}
case VK_UP:
{
if (CanChangeStyle())
{
ClearShowBlock(hwnd);
ChangeStyle();
}
break;
}
case VK_DOWN:
{
if (!IsDbarrier())
{
for (x = 0; x < 4; x++)
{
for (y = 0; y < 4; y++)
{
ShowBlock[x][y].y += BLOCK_STEP;
}
}
}
break;
}
default:
break;
}
/* 发送重画组合方块消息 */
SendMessage(hwnd, WM_DRAWSHOWBLOCK, 0, 0);
return 0;
}
case WM_REMOVEBLOCK:
{
int RemoveTime = 0; /* 消行的次数 */
BOOL IsRemove;
BOOL NextDraw = true;
/* 遍历下沉方块数组查找满行 */
for (x = 0; x < BLOCK_X_TOTAL; x++)
{
IsRemove = true;
for (y = 1; y <= BLOCK_Y_TOTAL; y++)
{
if (Block_Interface[x][y] == 0)
{
IsRemove = false;
break;
}
}
/* 满行的话图形下移重画下沉方块 */
if (IsRemove)
{
for (int Rx = x; Rx > 0; Rx--)
{
for (y = 1; y <= BLOCK_Y_TOTAL; y++)
{
Block_Interface[Rx][y] = Block_Interface[Rx - 1][y];
}
}
iScore += ++RemoveTime * 100;
itoa(iScore, szScore, 10);
if (ChangeTimer(iScore, &Level_time, &iLevel))
{
KillTimer(hwnd, TIMER_ID);
SetTimer(hwnd, TIMER_ID, Level_time, TimerProc);
itoa(iLevel, szLevel, 10);
HDC hdc = GetDC(hwnd);
HPEN hPen = (HPEN)GetStockObject(WHITE_PEN);
HBRUSH hBrush = (HBRUSH)GetStockObject(WHITE_BRUSH);
HPEN hOldPen = (HPEN)SelectObject(hdc, hPen);
POINT PreviewPt[] = {
PREVIEW_A_X - 1, PREVIEW_B_Y + 180,
PREVIEW_B_X + 1, PREVIEW_B_Y + 180,
PREVIEW_B_X + 1, PREVIEW_B_Y + 220,
PREVIEW_B_X - 1, PREVIEW_B_Y + 220
};
SelectObject(hdc, hBrush);
Polygon(hdc, PreviewPt, 4);
SelectObject(hdc, hOldPen);
SelectObject(hdc, hFirstBrush);
DeleteObject(hPen);
DeleteObject(hBrush);
ReleaseDC(hwnd, hdc);
}
NextDraw = false;
InvalidateRect(hwnd, NULL, TRUE); /* 重画下沉方块 */
}
else
{
if (RemoveTime > 1)
{
RemoveTime = 0;
}
}
}
if (NextDraw)
{
hdc = GetDC(hwnd);
SelectObject(hdc, hFirstBrush);
CreateBlock(hdc);
PreviewBlock(hdc);
ReleaseDC(hwnd, hdc);
}
return 0;
}
case WM_PAINT:
{
hdc = BeginPaint(hwnd, &ps);
DrawFrame(hdc);
SelectObject(hdc, hFirstBrush);
/* 创建字体 */
SelectObject(hdc, CreateFont (0, 0, 0, 0, 0, 0, 0, 0,
DEFAULT_CHARSET, 0, 0, 0, FIXED_PITCH, NULL));
/* 绘制沉底方块 */
for (x = 0; x < BLOCK_X_TOTAL; x++)
{
for (y = 1; y <= BLOCK_Y_TOTAL; y++)
{
if (Block_Interface[x][y] == 1)
{
Coordinate(pt, TmpPt, x, y);
Polygon(hdc, TmpPt, 4);
}
}
}
CreateBlock(hdc);
PreviewBlock(hdc);
ShowScore(hdc, szScore);
ShowLevel(hdc, szLevel);
EndPaint(hwnd, &ps);
return 0;
}
case WM_DRAWSHOWBLOCK:
{
hdc = GetDC(hwnd);
SelectObject(hdc, hFirstBrush);
DrawBlock(hdc, ShowBlock);
ReleaseDC(hwnd, hdc);
return 0;
}
/* 移动窗口 */
case WM_NCHITTEST:
{
UINT nHitTest;
nHitTest = DefWindowProc(hwnd, message, wParam, lParam);
if (nHitTest == HTCLIENT && GetAsyncKeyState(MK_LBUTTON) < 0)
{
nHitTest=HTCAPTION;
}
return nHitTest;
}
case WM_DESTROY:
{
KillTimer(hwnd, TIMER_ID);
PostQuitMessage(0);
return 0;
}
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
}
/* 定�