//记得用多字符
#include<iostream>
#include<conio.h>
#include<time.h>
#include<string>
#include<windows.h>
#include<mmreg.h>
#include<mmsystem.h>
#include<stdlib.h>
using namespace std;
#define IDB_ONE
#define Width 20
#define High 26
#define YIGE 20
#define E_NEWBLOCK WM_USER+1
#define E_DRAW WM_USER+2
#define E_NEXTBLOCK WM_USER+3
#pragma comment(lib,"winmm.lib")
static int Top, sel, Fg, sel1;
static int state = 0, b = 1;
//static int b = 1;
HWND hwnd;
HDC mdc, hdc;
int score; int len; int n = 1;
char ch[256];
static int ShowKUAI[4][2], KUAI[4][2], SNextKUAI[4][2], NextKUAI[4][2];
static bool pauseFlag = false;
static int key = 1;
void HiGame(HWND);
void StopGame(HWND);
void StartP(HDC);
void Sweep(HWND);
HDC m_hdc;
HFONT hfont;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int iCmdShow)
{
static char AppName[] = "Tetris俄罗斯方块";
MSG msg;
msg.message = 0;
WNDCLASSEX wndclass;
int iScreenWide;
wndclass.cbSize = sizeof(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(BLACK_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = AppName;
wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (!RegisterClassEx(&wndclass))
{
MessageBeep(0);
return FALSE;
}
iScreenWide = GetSystemMetrics(SM_CXFULLSCREEN);
hwnd = CreateWindow(
AppName,
"俄罗斯方块",
WS_MINIMIZEBOX | WS_SYSMENU,
0,
0,
600,
520,
NULL,
NULL,
hInstance,
NULL
);
if (!hwnd)
return FALSE;
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
SendMessage(hwnd, E_NEWBLOCK, 0, 0);
SetTimer(hwnd, 1, 300, NULL);
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
if (!state)
{
hdc = GetDC(hwnd);
m_hdc = CreateCompatibleDC(hdc);
state = 1;
Sleep(200);
}
else if (state == 1)
{
if (b)
{
Sweep(hwnd);
InvalidateRect(hwnd, NULL, TRUE);
KillTimer(hwnd, 1);
b = 0;
}
}
}
}
return msg.wParam;
}
void DrawRect(HDC hdc, int l, int t, int r, int b)
{
MoveToEx(hdc, l, t, NULL);
LineTo(hdc, r, t);
LineTo(hdc, r, b);
LineTo(hdc, l, b);
LineTo(hdc, l, t);
}
class Colour
{
public:
Colour(int, int, int);
HBRUSH hhBru;
HBRUSH visithhBru()
{
return hhBru;
};
private:
int a1, b1, c1;
};
Colour::Colour(int a, int b, int c)
{
a1 = a; b1 = b; c1 = c;
hhBru = CreateSolidBrush(RGB(a1, b1, c1));
}
void DrawCell(HDC hdc, int l, int t, int r, int b)
{
Colour B1(255, 2, 255), B2(8, 92, 255), B3(96, 113, 223), B4(34, 126, 255), B5(172, 108, 2);
HBRUSH hBru, hBru1, hBru2, hBru3, hBru4;
hBru = B1.visithhBru();
hBru1 = B2.visithhBru();
hBru2 = B3.visithhBru();
hBru3 = B4.visithhBru();
hBru4 = B5.visithhBru();
//hBru = CreateSolidBrush(RGB(255, 2, 255)); //紫色
//hBru1 = CreateSolidBrush(RGB(8, 92, 255));
//hBru2 = CreateSolidBrush(RGB(96, 113, 223));
//hBru3 = CreateSolidBrush(RGB(34, 126, 255));
//hBru4 = CreateSolidBrush(RGB(172, 108, 2)); //zongse
switch (sel1)
{
case 0:
SelectObject(hdc, hBru);
Rectangle(hdc, l, t, r, b);
break;
case 1:
SelectObject(hdc, hBru1);
Rectangle(hdc, l, t, r, b);
break;
case 2:
SelectObject(hdc, hBru2);
Rectangle(hdc, l, t, r, b);
break;
case 3:
SelectObject(hdc, hBru2);
Rectangle(hdc, l, t, r, b);
break;
case 4:
SelectObject(hdc, hBru3);
Rectangle(hdc, l, t, r, b);
break;
case 5:
SelectObject(hdc, hBru3);
Rectangle(hdc, l, t, r, b);
break;
case 6:
SelectObject(hdc, hBru4);
Rectangle(hdc, l, t, r, b);
break;
}
DeleteObject(hBru);
DeleteObject(hBru1);
DeleteObject(hBru2);
DeleteObject(hBru3);
DeleteObject(hBru4);
}
void DrawGamePlace(HDC hdc)
{
if (key)
{
StartP(hdc);
}
else {
int i, j;
HPEN hpen1;
hpen1 = CreatePen(PS_SOLID, 1, RGB(0, 255, 0));
MoveToEx(hdc, (Width - 8) * YIGE, 0, NULL);
LineTo(hdc, (Width - 8) * YIGE, (High - 2) * YIGE);
SelectObject(hdc, hpen1);
for (i = 1; i < High - 1; i++)
for (j = 1; j <= Width - 8; j++)
DrawRect(hdc, (j - 1) * YIGE, (i - 1) * YIGE, j * YIGE, i * YIGE);
for (i = 5; i < 9; i++)
for (j = Width - 5; j < Width - 1; j++)
DrawRect(hdc, (j - 1) * YIGE, (i - 1) * YIGE, j * YIGE, i * YIGE);
DeleteObject(hpen1);
}
}
void DrawBlock(HDC hdc, int block[4][2])
{
int i;
for (i = 0; i < 4; i++)
DrawCell(hdc, (block[i][0] - 1) * YIGE, (block[i][1] - 1) * YIGE, block[i][0] * YIGE, block[i][1] * YIGE);
}
void Cover(HDC hdc, int Zhanshi[4][2])
{
int i;
HBRUSH hBru;
DrawGamePlace(hdc);
hBru = (HBRUSH)GetStockObject(BLACK_BRUSH);
SelectObject(hdc, hBru);
for (i = 0; i < 4; i++)
Rectangle(hdc, (Zhanshi[i][0] - 1) * YIGE, (Zhanshi[i][1] - 1) * YIGE, Zhanshi[i][0] * YIGE, Zhanshi[i][1] * YIGE);
DeleteObject(hBru);
}
void StopGame(HWND hwnd)
{
KillTimer(hwnd, 1);
MessageBox(hwnd, " 游戏暂停\n\n 再次按下空格开始", "提示", MB_OK);
}
void HiGame(HWND hwnd)
{
if (score <= 500)
SetTimer(hwnd, 1, 300, NULL);
else if (score <= 1000)
SetTimer(hwnd, 1, 200, NULL);
else
SetTimer(hwnd, 1, 50, NULL);
}
void Sweep(HWND hwnd)
{
ReleaseDC(hwnd, hdc);
DeleteObject(hfont);
DeleteObject(m_hdc);
}
void StartP(HDC hdc)
{
TextOut(hdc, 240, 200, "俄罗斯方块", lstrlen("俄罗斯方块"));
TextOut(hdc, 230, 230, "按下Enter进入游戏", lstrlen("按下Enter进入游戏"));
}
LRESULT CALLBACK WndProc(HWND hwnd,
UINT iMsg,
WPARAM wParam,
LPARAM lParam)
{
int i, j, k, lines, r;
static int CLS[Width - 7][High];
HPEN hpen;
PAINTSTRUCT ps;
switch (iMsg)
{
case WM_CREATE:
Top = High - 1;
for (i = 0; i < High; i++)
{
CLS[0][i] = 1;
CLS[Width - 7][i] = 1;
}
for (i = 0; i < Width - 7; i++)
{
CLS[i][High - 1] = 1;
}
for (i = 1; i <= Width - 8; i++)
{
for (j = 0; j < High - 1; j++)
CLS[i][j] = 0;
}
return 0;
case E_NEWBLOCK:
Fg = 0;
if (score >= 500)
{
KillTimer(hwnd, 1);
SetTimer(hwnd, 1, 200, NULL);
}
if (score >= 1000)
{
KillTimer(hwnd, 1);
SetTimer(hwnd, 1, 100, NULL);
}
for (i = Top; i < High - 1; i++)
{
lines = 1;
for (j = 1; j <= Width - 7; j++)
if (!CLS[j][i])
{
lines = 0;
break;
}
if (lines)
{
score += 100;
for (j = 1; j < Width - 7; j++)
for (k = i; k > 0; k--)
{
CLS[j][k] = CLS[j][k - 1];
}
Top++;
InvalidateRect(hwnd, NULL, TRUE);
}
}
if (n)
{
sel1 = 0;
n = 0;
ShowKUAI[0][0] = KUAI[0][0] = 5; ShowKUAI[0][1] = KUAI[0][1] = 0;
ShowKUAI[1][0] = KUAI[1][0] = 6; ShowKUAI[1][1] = KUAI[1][1] = 0;
ShowKUAI[2][0] = KUAI[2][0] = 5; ShowKUAI[2][1] = KUAI[2][1] = 1;
ShowKUAI[3][0] = KUAI[3][0] = 6; ShowKUAI[3][1] = KUAI[3][1] = 1;
}
else
{
sel1 = sel;
ShowKUAI[0][0] = KUAI[0][0] = NextKUAI[0][0]; ShowKUAI[0][1] = KUAI[0][1] = NextKUAI[0][1];
ShowKUAI[1][0] = KUAI[1][0] = NextKUAI[1][0]; ShowKUAI[1][1] = KUAI[1][1] = NextKUAI[1][1];
ShowKUAI[2][0] = KUAI[2][0] = NextKUAI[2][0]; ShowKUAI[2][1] = KUAI[2][1] = NextKUAI[2][1];
ShowKUAI[3][0] = KUAI[3][0] = NextKUAI[3][0]; ShowKUAI[3][1] = KUAI[3][1] = NextKUAI[3][1];
}
srand((unsigned)time(NULL));
sel = rand() % 7;
switch (sel)
{
case 0:
// 田字
NextKUAI[0][0] = 5; NextKUAI[0][1] = 0;
NextKUAI[1][0] = 6; NextKUAI[1][1] = 0;
NextKUAI[2][0] = 5; NextKUAI[2][1] = 1;
NextKUAI[3][0] = 6; NextKUAI[3][1] = 1;
for (i = 0; i < 4; i++)
{
SNextKUAI[i][0] = NextKUAI[i][0] + 11;
SNextKUAI[i][1] = NextKUAI[i][1] + 5;
}
break;
case 1:
//横杆
NextKUAI[0][0] = 4; NextKUAI[0][1] = 0;
NextKUAI[1][0] = 5; NextKUAI[1][1] = 0;
NextKUAI[2][0] = 6; NextKUAI[2][1] = 0;
NextKUAI[3][0] = 7; NextKUAI[3][1] = 0;
for (i = 0; i < 4; i++)
{
SNextKUAI[i][0] = NextKUAI[i][0] + 11;
SNextKUAI[i][1] = NextKUAI[i][1] + 5;
}
break;
case 2:
//左上右下
NextKUAI[0][0] = 5; NextKUAI[0][1] = 0;
NextKUAI[1][0] = 5; NextKUAI[1][1] = 1;
NextKUAI[2][0] = 6; NextKUAI[2][1] = 1;
NextKUAI[3][0] = 6; NextKUAI[3][1] = 2;
for (i = 0; i < 4; i++)
{
SNextKUAI[i][0] = NextKUAI[i][0] + 11;
SNextKUAI[i][1] = NextKUAI[i][1] + 5;
}
break;
case 3:
// 右上左下
NextKUAI[0][0] = 6; NextKUAI[0][1] = 0;
NextKUAI[1][0] = 6; NextKUAI[1][1] = 1;
NextKUAI[2][0] = 5; NextKUAI[2][1] = 1;
NextKUAI[3][0] = 5; NextKUAI[3][1] = 2;
for (i = 0; i < 4; i++)
{
SNextKUAI[i][0] = NextKUAI[i][0] + 11;
SNextKUAI[i][1] = NextKUAI[i][1] + 5;
}
break;
case 4:
//向右朝向的L
NextKUAI[0][0] = 5; NextKUAI[0][1] = 0;
NextKUAI[1][0] = 5; NextKUAI[1][1] = 1;
NextKUAI[2][0] = 5; NextKUAI[2][1] = 2;
NextKUAI[3][0] = 6; NextKUAI[3][1] = 2;
for (i = 0; i < 4; i++)
{
SNextKUAI[i][0] = NextKUAI[i][0] + 11;
SNextKUAI[i][1] = NextKUAI[i][1] + 5;
}
break;
case 5:
// 向左朝向的L
NextKUAI[0][0] = 5; NextKUAI[0][1] = 0;
NextKUAI[1][0] = 5; NextKUAI[1][1] = 1;
NextKUAI[2][0] = 5; NextKUAI[2][1] = 2;
NextKUAI[3][0] = 4; NextKUAI[3][1] = 2;
for (i = 0; i < 4; i++)
{
SNextKUAI[i][0] = NextKUAI[i][0] + 11;
SNextKUAI[i][1] = NextKUAI[i][1] + 5;
}
break;
case 6:
// 土字
NextKUAI[0][0] = 5; NextKUAI[0][1] = 0;
NextKUAI[1][0] = 4; NextKUAI[1][1] = 1;
NextKUAI[2][0] = 5; NextKUAI[2][1] = 1;
NextKUAI[3][0] = 6; NextKUAI[3][1] = 1;
for (i = 0; i < 4; i++)
{
SNextKUAI[i][0] = NextKUAI[i][0] + 11;
SNextKUAI[i][1] = NextKUAI[i][1] + 5;
}
SendMessage(hwnd, E_NEXTBLOCK, 0, 0);
break;
default:
SendMessage(hwnd, E_NEWBLOCK, 0, 0);
SendMessage(hwnd, E_NEXTBLOCK, 0, 0);
break;
}
return 0;
case WM_TIMER:
if (!state)
break;
for (i = 0; i < 4; i++)
KUAI[i][1]++;
for (i = 0; i < 4; i++)
if (CLS[KUAI[i][0]][KUAI[i][1]])
{
SendMessage(hwnd, E_NEXTBLOCK, 0, 0);
for (i = 0; i < 4; i++)
CLS[ShowKUAI[i][0]][ShowKUAI[i][1]] = 1;
if (Top > ShowKUAI[0][1] - 2)
Top = ShowKUAI[0][1] - 2;
if (Top < 0)
{
PlaySound(NULL, NULL, SND_ASYNC | SND_FILENAME);
KillTimer(hwnd, 1);
MessageBox(hwnd, "游戏结束", "退出", MB_OK);
PostQuitMessage(0);
}
SendMessage(hwnd, E_NEWBLOCK, 0, 0);
return 0;
}
SendMessage(hwnd, E_DRAW, 0, 0);
return 0;
case WM_KEYDOWN:
r = 0;
switch ((int)wParam)
{
case VK_LEFT:
if (pauseFlag)
break;
for (i = 0; i < 4; i++)
KUAI[i][0]--;
break;
case VK_RIGHT:
if (pauseFlag)
break;
for (i = 0; i < 4; i++)
KUAI[i][0]++;
break;
case VK_DOWN:
if (pauseFlag)
break;
for (i = 0; i < 4; i++)
KUAI[i][1]++;
break;
case VK_SPACE:
pauseFlag = !pauseFlag;
if (pauseFlag == true)
{
StopGame(hwnd);
break;
}
else {
HiGame(hwnd);
break;
}
case VK_ESCAPE:
{
PlaySound(NULL, NULL, SND_ASYNC | SND_FILENAME);
KillTimer(hwnd, 1);
MessageBox(hwnd, "游戏结束", "退出", MB_OK);
PostQuitMessage(0);
}
case VK_RETURN:
key = 0;
InvalidateRect(hwnd, NULL, TRUE);
SetTimer(hwnd, 1, 300, NULL);
case VK_UP:
if (pauseFlag)
break;
r = 1;
Fg++;
switch (sel1)
{
case 0:
break;
//横变成竖
case 1:
Fg = Fg % 2;
for (i = 0; i < 4; i++)
{
KUAI[i][(Fg + 1) % 2] = ShowKUAI[2][(Fg + 1) % 2];
KUAI[i][Fg] = ShowKUAI[2][Fg] - 2 + i;
}
break;
//左上右下顺时针90°
case 2:
Fg = Fg % 2;
if (Fg)
{
KUAI[0][1] += 2; KUAI[3][0] -= 2;
}
else
{
KUAI[0][1] -= 2; KUAI[3][0] += 2;
}
break;
// 左下右上顺时针90°
case 3:
Fg = Fg % 2;
if (Fg)
{
KUAI[0][1] += 2; KUAI[3][0] += 2;
}
else
{
KUAI[0][1] -= 2; KUAI[3][0] -= 2;
}
break;
// L顺时针旋转
case 4:
Fg = Fg % 4;
switch (Fg)
{
case 0:
KUAI[2][0] += 2; KUAI[3][0] += 2;
KUAI[2][1] += 1; KUAI[3][1] += 1;
break;
case 1:
KUAI[2][0] += 1; KUAI[3][0] += 1;
KUAI[2][1] -= 2; KUAI[3][1] -= 2;
break;
case 2:
KUAI[2][0] -= 2; KUAI[3][0] -= 2;
KUAI[2][1] -= 1; KUAI[3][1] -= 1;
break;
case 3:
KUAI[2][0] -= 1; KUAI[3][0] -= 1;
KUAI[2][1] += 2; KUAI[3][1] += 2;
break;
}
break;
// 左L顺时针旋转
case 5:
Fg = Fg % 4;
switch (Fg)
{
case 0:
KUAI[2][0] += 1; KUAI[3][0] += 1;
KUAI[2][1] += 2; KUAI[3][1] += 2;
break;
case 1:
KUAI[2][0] += 2; KUAI[3][0] += 2;
KUAI[2][1] -= 1; KUAI[3][1] -= 1;
break;
case 2:
KUAI[2][0] -= 1; KUAI[3][0] -= 1;
KUAI[2][1] -= 2; KUAI[3][1] -= 2;
break;
case 3:
KUAI[2][0] -= 2; KUAI[3][0] -= 2;
KUAI[2][1] += 1; KUAI[3][1] += 1;
break;
}
break;
case 6:
// 土顺时针旋转90°
Fg = Fg % 4;
switch (Fg)
{
case 0:
KUAI[0][0]++; KUAI[0][1]--;
KUAI[1][0]--; KUAI[1][1]--;
KUAI[3][0]++; KUAI[3][1]++;
break;
case 1:
KUAI[1][0]++; KUAI[1][1]++; break;
case 2:
KUAI[0][0]--; KUAI[0][1]++; break;
case 3:
KUAI[3][0]--; KUAI[3][1]--; break;
}
break;
}
break;
}
for (i = 0; i < 4; i++)
if (CLS[KUAI[i][0]][KUAI[i][1]])
{
if (r) Fg += 3;
{
for (i = 0; i < 4; i++)
{
for (j = 0; j < 2; j++)
KUAI[i][j] = ShowKUAI[i][j];
}
}
return 0;
}
SendMessage(hwnd, E_DRAW, 0, 0);;
return 0;
case E_NEXTBLOCK:
hdc = GetDC(hwnd);
Cover(hdc, SNextKUAI);
return 0;
case E_DRAW:
hdc = GetDC(hwnd);
Cover(hdc, ShowKUAI);
DrawBlock(hdc, SNextKUAI);
for (i = 0; i < 4; i++)
{
for (j = 0; j < 2; j++)
{
ShowKUAI[i][j] = KUAI[i][j];
}
}
DrawBlock(hdc, ShowKUAI);
ReleaseDC(hwnd, hdc);
return 0;
case WM_PAINT:
len = wsprintf(ch, "Score:%d", score);
hdc = BeginPaint(hwnd, &ps);
DrawGamePlace(hdc);
if (key != 1)
{
//TextOut(hdc, 15 * YIGE, 12 * YIGE, "Score", lstrlen("Score"));
TextOut(hdc, 15 * YIGE, 13 * YIGE, ch, len);
TextOut(hdc, 15 * YIGE, 15 * YIGE, "Level: ", lstrlen("Level: "));
if (score <= 500)
TextOut(hdc, 18 * YIGE, 15 * YIGE, "简单", lstrlen("简单"));
else if (score <= 1000)
TextOut(hdc, 18 * YIGE, 15 * YIGE, "中等", lstrlen("中等"));
else
TextOut(hdc, 18 * YIGE, 15 * YIGE, "困难", lstrlen("困难"));
}
hpen = CreatePen(PS_SOLID, 1, RGB(0, 255, 0));
SelectObject(hdc, hpen);
for (i = 0; i < High - 1; i++)
{
for (j = 1; j <= Width - 8; j++)
{
if (CLS[j][i])
DrawCell(hdc, (j - 1) * YIGE, (i - 1) * YIGE, j * YIGE, i * YIGE);
}
}
DeleteObject(hpen);
EndPaint(hwnd, &ps);
return 0;
case WM_DESTROY:
Sweep(hwnd);
KillTimer(hwnd, 1);
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, iMsg, wParam, lParam);
}