window编程 - 俄罗斯方块

这是一个使用Windows API编写的经典俄罗斯方块游戏程序。游戏包括多个功能模块,如游戏逻辑、图形界面绘制、用户交互等。玩家可以通过键盘控制方块的移动、旋转及下落速度。
#include <windows.h>
#include <time.h>
#include "resource.h"
#include "mmsystem.h"
#pragma comment(lib,"winmm.lib")

#define BOXSIZE      10             // 单个方块大小
#define WIN_WIDTH    645            // 窗口宽度
#define WIN_LENGTH   648            // 窗口长度
#define GAME_LEFT    10             // 游戏区域的左部
#define GAME_RIGHT   510            // 游戏区域的右部
#define GAME_TOP     0              // 游戏区域的顶部
#define GAME_BUT     600            // 游戏区域的底部
#define HINT_EDGE    150            // 提示区域边界
#define LINE_SCORE   100            // 每消一个加100分
// 全局变量
const POINT Tetris[7][4][4] = {
	{// |一
		{ { 250, 0 }, { 260, 0 }, { 270, 0 }, { 280, 0 } },
		{ { 250, 0 }, { 250, 10 }, { 250, 20 }, { 250, 30 } },
		{ { 250, 0 }, { 260, 0 }, { 270, 0 }, { 280, 0 } },
		{ { 250, 0 }, { 250, 10 }, { 250, 20 }, { 250, 30 } },
	},
	{// 田
		{ { 250, 0 }, { 260, 0 }, { 250, 10 }, { 260, 10 } },
		{ { 250, 0 }, { 260, 0 }, { 250, 10 }, { 260, 10 } },
		{ { 250, 0 }, { 260, 0 }, { 250, 10 }, { 260, 10 } },
		{ { 250, 0 }, { 260, 0 }, { 250, 10 }, { 260, 10 } },
	},
	{// L
		{ { 250, 0 }, { 250, 10 }, { 250, 20 }, { 260, 20 } },
		{ { 250, 0 }, { 250, 10 }, { 260, 0 }, { 270, 0 } },
		{ { 250, 0 }, { 260, 0 }, { 260, 10 }, { 260, 20 } },
		{ { 250, 10 }, { 260, 10 }, { 270, 10 }, { 270, 0 } },
	},
	{// ~L
		{ { 250, 20 }, { 260, 0 }, { 260, 10 }, { 260, 20 } },
		{ { 250, 0 }, { 250, 10 }, { 260, 10 }, { 270, 10 } },
		{ { 250, 0 }, { 250, 10 }, { 250, 20 }, { 260, 0 } },
		{ { 250, 0 }, { 260, 0 }, { 270, 0 }, { 270, 10 } },
	},
	{// Z N
		{ { 250, 0 }, { 260, 0 }, { 260, 10 }, { 270, 10 } },
		{ { 250, 10 }, { 250, 20 }, { 260, 0 }, { 260, 10 } },
		{ { 250, 0 }, { 260, 0 }, { 260, 10 }, { 270, 10 } },
		{ { 250, 10 }, { 250, 20 }, { 260, 0 }, { 260, 10 } },
	},
	{// ~Z
		{ { 250, 10 }, { 260, 0 }, { 260, 10 }, { 270, 0 } },
		{ { 250, 0 }, { 250, 10 }, { 260, 10 }, { 260, 20 } },
		{ { 250, 10 }, { 260, 0 }, { 260, 10 }, { 270, 0 } },
		{ { 250, 0 }, { 250, 10 }, { 260, 10 }, { 260, 20 } },
	},
	{ // 
		{ { 250, 10 }, { 260, 0 }, { 260, 10 }, { 270, 10 } },
		{ { 250, 0 }, { 250, 10 }, { 250, 20 }, { 260, 10 } },
		{ { 250, 0 }, { 260, 0 }, { 270, 0 }, { 260, 10 } },
		{ { 250, 10 }, { 260, 0 }, { 260, 10 }, { 260, 20 } },
	},
};
static int left_state = 0, right_state = 0, buttom_state = 0;
static int block_state_but = 0, block_state_right = 0, block_state_left = 0;
static int now_color = 0, now_shape = 0, now_dir = 0;                 // 当前方向
static int next_shape = 0, next_color = 0, next_dir = 0;                    // 下一次
static POINT now_block[4];                      // 当前方块
static HBRUSH gcolor[5];                        // 颜色
static int   game_zone[GAME_RIGHT][GAME_BUT];   // 游戏区
static int   over_state = 0, pause_state = 0;   // 结束、暂停标志
HWND hwndEdit1;             // 分数
HWND hwndEdit2;             // 等级
HWND hwndEdit3;             // 游戏时间
HWND hwndEdit4, hwndEdit5, hwndEdit6, hwndEdit7, hwndEdit8, hwndEdit9;             // 操作指南
HWND hwndBut1, hwndBut2, hwndBut3;
TCHAR buffer[100];
static int ghighest = 99999;
static int score = 0;                           // 分数
static int degree = 7;                           // 等级
static int game_time = 0;                           // 游戏时间
const int degree_score[7] = { 2000, 5000, 10000, 17000, 26000, 37000, 50000 }; // 晋级分数
int gspeed[8] = { 600, 500, 400, 300, 200, 100, 50, 20 };
int most_speed = 5;

// 函数声明
LRESULT CALLBACK WinProc(HWND, UINT, WPARAM, LPARAM);  // 回调函数
void DrawBackground(HDC hdc);                          // 画背景
void DrawBox(HDC hdc, int x, int y, int color);        // 画小方块
void DrawBlocks(HDC hdc, POINT bs[], int color);       // 画大方块
void Init(HWND, HINSTANCE);                            // 初始化
void SetColor();                                       // 设置颜色
void GetNext(HDC);                                     // 获取下一个
void IsBlocked(POINT now_block[4]);                    // 判断是否被挡住
void Save();                                           // 保存位置
void Rander(HDC hdc);                                  // 游戏区域测试
void Game_over(HDC, HWND);                             // 检测游戏是否结束
void Fall(HWND hwnd, HDC hdc);                         // 下落
void ShowGameZone(HDC);                                // 显示方块落下的区域
void ShowGameStatus(HWND);                             // 显示游戏进行的状态
void PlayMusic(HWND hwnd, LPCWSTR type, LPCWSTR name); // 实现不同格式音乐的播放
// 主函数
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
	PSTR szCmdLine, int iCmdShow)
{
	HWND hwnd;
	MSG  msg;
	WNDCLASS wndcls;
	TCHAR szAppName[] = L"Win32";

	wndcls.style = CS_HREDRAW | CS_VREDRAW | CS_NOCLOSE;
	wndcls.cbClsExtra = 0;
	wndcls.cbWndExtra = 0;
	wndcls.lpfnWndProc = WinProc;
	wndcls.hInstance = hInstance;
	wndcls.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
	wndcls.hCursor = LoadCursor(hInstance, MAKEINTRESOURCE(IDC_CURSOR1));
	wndcls.hbrBackground = static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
	wndcls.lpszClassName = szAppName;
	wndcls.lpszMenuName = NULL;

	if (!RegisterClass(&wndcls)){
		MessageBox(NULL, L"注册窗口失败,此程序必须在Windows环境下运行!", L"hint", MB_ICONHAND);
		return 0;
	}

	hwnd = CreateWindow(szAppName,
		TEXT("俄罗斯方块"),
		WS_OVERLAPPEDWINDOW&~WS_MAXIMIZEBOX^WS_THICKFRAME,
		10, 10, WIN_WIDTH, WIN_LENGTH, NULL,
		NULL,        // 菜单
		hInstance, NULL);

	ShowWindow(hwnd, iCmdShow);
	UpdateWindow(hwnd);

	while (GetMessage(&msg, NULL, 0, 0)){
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return static_cast<int>(msg.wParam);
}

// 回调函数
LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
	HDC hdc;
	PAINTSTRUCT ps;
	static HINSTANCE hInstance;
	RECT rect;
	static int music = 0;

	switch (message){
	case WM_CREATE:
		Init(hwnd, hInstance);                       // 初始化
		SetTimer(hwnd, 1, gspeed[degree], NULL);     // 设置时钟
		SetTimer(hwnd, 2, 1000, NULL);               // 游戏时间
		PlayMusic(hwnd, L"mpegvideo", L"music.mp3");
		//MessageBox(hwnd, L"窗口正在创建", L"Tips", MB_OK);
		return 0;
	case WM_PAINT:
		hdc = BeginPaint(hwnd, &ps);
		DrawBackground(hdc);          // 画背景
		Rander(hdc);
		EndPaint(hwnd, &ps);
		return 0;
	case MM_MCINOTIFY:
		if (music == 0){
			PlayMusic(hwnd, L"mpegvideo", L"snow_journey.mid");
			music = 1;
		}
		else if (music == 1){
			music = 0;
			PlayMusic(hwnd, L"mpegvideo", L"chocobo1.mid");
		}
		return 0;
	case WM_COMMAND:{
						hdc = GetDC(hwnd);
						switch (LOWORD(wParam)){
						case 4:{    // 新游戏
								   KillTimer(hwnd, 1);
								   int sel = MessageBox(hwnd, TEXT("是否开始新游戏?"), L"新游戏", MB_ICONQUESTION | MB_OKCANCEL);
								   if (sel == IDOK){
									   GetClientRect(hwnd, &rect);
									   Init(hwnd, hInstance);
									   SetTimer(hwnd, 1, gspeed[degree], NULL);
									   GetNext(hdc);
									   InvalidateRect(hwnd, &rect, TRUE);
								   }
								   else{
									   SetTimer(hwnd, 1, gspeed[degree], NULL);;
									   SetFocus(hwnd);
								   }
						}break;
						case 5:{    // 暂停
								   if (pause_state == 0){
									   pause_state = 1;
									   SetDlgItemText(hwnd, 5, L"继    续");
									   KillTimer(hwnd, 1);
								   }
								   else if (pause_state == 1){
									   pause_state = 0;
									   SetDlgItemText(hwnd, 5, L"暂    停");
									   SetTimer(hwnd, 1, gspeed[degree], NULL);
									   SetFocus(hwnd);
								   }
						}break;
						case 6:{    // 退出
								   KillTimer(hwnd, 1);
								   if (IDOK == MessageBox(hwnd, L"退出游戏?", L"退出",
									   MB_ICONINFORMATION | MB_OKCANCEL)){
									   PostQuitMessage(0);
								   }
								   else {
									   SetTimer(hwnd, 1, gspeed[degree], NULL);
									   // SetFocus(hwnd);
								   }
						}break;
						}
						ReleaseDC(hwnd, hdc);
	}return 0;
	case WM_KEYDOWN: // 按键处理
	{
						 hdc = GetDC(hwnd);
						 IsBlocked(now_block);
						 switch (wParam){
						 case VK_LEFT:// 左箭头
							 if (!left_state && !block_state_left && !buttom_state && !block_state_but){
								 DrawBlocks(hdc, now_block, 3);
								 for (int i = 0; i < 4; i++)
									 now_block[i].x -= BOXSIZE;
								 DrawBlocks(hdc, now_block, now_color);
							 } break;
						 case VK_RIGHT:// 右箭头
							 if (!right_state && !block_state_but && !buttom_state && !block_state_right){
								 DrawBlocks(hdc, now_block, 3);
								 for (int i = 0; i < 4; i++)
									 now_block[i].x += BOXSIZE;
								 DrawBlocks(hdc, now_block, now_color);
							 }break;
						 case VK_SPACE:{// 空格
										   POINT new_block[4];
										   int new_dir = (now_dir + 1) % 4;
										   int offset_y = now_block[0].y - Tetris[now_shape][now_dir][0].y;
										   int offset_x = now_block[0].x - Tetris[now_shape][now_dir][0].x;
										   for (int i = 0; i < 4; i++){
											   new_block[i].x = Tetris[now_shape][new_dir][i].x + offset_x;
											   new_block[i].y = Tetris[now_shape][new_dir][i].y + offset_y;
										   }
										   IsBlocked(new_block);
										   if (!buttom_state && !block_state_but && !block_state_right && !right_state){
											   DrawBlocks(hdc, now_block, 3);
											   for (int i = 0; i < 4; i++) now_block[i] = new_block[i];
											   now_dir = new_dir;
											   DrawBlocks(hdc, now_block, now_color);
										   }
						 }break;
						 case VK_DOWN:// 下箭头
							 SetTimer(hwnd, 1, 5, NULL);
							 break;
						 case VK_UP: // 上箭头
							 SetTimer(hwnd, 1, gspeed[degree], NULL);
							 break;
						 }
						 ReleaseDC(hwnd, hdc);
	}return 0;
	case WM_TIMER:// 计时器处理
		switch (wParam){
		case 1:{
				   ShowGameStatus(hwnd);
				   hdc = GetDC(hwnd);
				   IsBlocked(now_block);
				   if (!buttom_state && !block_state_but){   // 如果没有碰到窗口底部或块底部
					   DrawBlocks(hdc, now_block, 3);        // 覆盖先前的
					   for (int i = 0; i < 4; i++){
						   now_block[i].y += BOXSIZE;        // 画出移动后的
					   }
					   DrawBlocks(hdc, now_block, now_color);
				   }
				   else{
					   PlaySound(L"Falldown.wav", NULL, SND_FILENAME);
					   Save();
					   DrawBlocks(hdc, now_block, now_color);
					   Fall(hwnd, hdc);
					   Game_over(hdc, hwnd);
					   Rander(hdc);
					   GetNext(hdc);
					   SetTimer(hwnd, 1, gspeed[degree], NULL);
				   }
				   ReleaseDC(hwnd, hdc);
		}break;
		case 2:game_time++;
		break;
		}return 0;
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hwnd, message, wParam, lParam);
}

// 设置
void SetColor(){
	gcolor[0] = CreateSolidBrush(RGB(255, rand() % 127, rand() % 127));
	gcolor[1] = CreateSolidBrush(RGB(rand() % 127, 255, rand() % 127));
	gcolor[2] = CreateSolidBrush(RGB(rand() % 127, rand() % 127, 255));
	gcolor[4] = CreateSolidBrush(RGB(rand() % 127, rand() % 127, rand() % 127));
	if (now_color == 3) now_color = 0;
}

// 初始化
void Init(HWND hwnd, HINSTANCE hInstance){
	gcolor[3] = CreateSolidBrush(RGB(0, 0, 0));             // 黑色
	SetColor();                                             // 设置其它颜色
	srand((unsigned)time(0));
	score = 0;
	degree = 0;

	// 初始化方块状态
	next_shape = rand() % 7;
	next_dir = rand() % 4;
	next_color = rand() % 5;
	if (next_color == 3) next_color = 0;
	hwndEdit1 = CreateWindow(TEXT("EDIT"), L"分数:0", WS_CHILD | WS_VISIBLE | ES_READONLY,
		GAME_RIGHT + BOXSIZE + 2, HINT_EDGE + BOXSIZE + 2, 105, 20, hwnd, (HMENU)1, hInstance, NULL);
	hwndEdit2 = CreateWindow(TEXT("EDIT"), L"等级:0", WS_CHILD | WS_VISIBLE | ES_READONLY,
		GAME_RIGHT + BOXSIZE + 2, HINT_EDGE + BOXSIZE + 2 + 40 + 5, 105, 20, hwnd, (HMENU)2, hInstance, NULL);
	hwndEdit3 = CreateWindow(TEXT("EDIT"), L"游戏时间:0", WS_CHILD | WS_VISIBLE | ES_READONLY,
		GAME_RIGHT + BOXSIZE + 2, HINT_EDGE + BOXSIZE + 2 + 80 + 10, 105, 20, hwnd, (HMENU)3, hInstance, NULL);
	hwndBut1 = CreateWindow(TEXT("BUTTON"), L"新 游 戏", WS_CHILD | WS_VISIBLE,
		GAME_RIGHT + BOXSIZE + 2, HINT_EDGE + BOXSIZE + 2 + 120 + 20, 105, 30, hwnd, (HMENU)4, hInstance, NULL);
	hwndBut2 = CreateWindow(TEXT("BUTTON"), L"暂    停", WS_CHILD | WS_VISIBLE,
		GAME_RIGHT + BOXSIZE + 2, HINT_EDGE + BOXSIZE + 2 + 160 + 20, 105, 30, hwnd, (HMENU)5, hInstance, NULL);
	hwndBut2 = CreateWindow(TEXT("BUTTON"), L"退    出", WS_CHILD | WS_VISIBLE,
		GAME_RIGHT + BOXSIZE + 2, HINT_EDGE + BOXSIZE + 2 + 200 + 20, 105, 30, hwnd, (HMENU)6, hInstance, NULL);	
	hwndEdit4 = CreateWindow(TEXT("EDIT"), TEXT("← move left"), WS_CHILD | WS_VISIBLE | ES_READONLY,
		GAME_RIGHT + BOXSIZE + 2, HINT_EDGE + BOXSIZE + 2 + 280 + 20, 105, 20, hwnd, (HMENU)7, hInstance, NULL);
	hwndEdit5 = CreateWindow(TEXT("EDIT"), TEXT("→ move right"), WS_CHILD | WS_VISIBLE | ES_READONLY,
		GAME_RIGHT + BOXSIZE + 2, HINT_EDGE + BOXSIZE + 2 + 300 + 20, 105, 20, hwnd, (HMENU)8, hInstance, NULL);
	hwndEdit6 = CreateWindow(TEXT("EDIT"), TEXT("↑ speed down"), WS_CHILD | WS_VISIBLE | ES_READONLY,
		GAME_RIGHT + BOXSIZE + 2, HINT_EDGE + BOXSIZE + 2 + 320 + 20, 105, 20, hwnd, (HMENU)9, hInstance, NULL);
	hwndEdit7 = CreateWindow(TEXT("EDIT"), TEXT("↓ speed up"), WS_CHILD | WS_VISIBLE | ES_READONLY,
		GAME_RIGHT + BOXSIZE + 2, HINT_EDGE + BOXSIZE + 2 + 340 + 20, 105, 20, hwnd, (HMENU)10, hInstance, NULL);
	hwndEdit8 = CreateWindow(TEXT("EDIT"), TEXT("SPACE change"), WS_CHILD | WS_VISIBLE | ES_READONLY,
		GAME_RIGHT + BOXSIZE + 2, HINT_EDGE + BOXSIZE + 2 + 360 + 20, 105, 20, hwnd, (HMENU)11, hInstance, NULL);
	// 设置游戏区域
	for (int i = 0; i < GAME_RIGHT; i++){
		for (int j = 0; j < GAME_BUT; j++)
			game_zone[i][j] = 0;
	}

	for (int i = 0; i < BOXSIZE; i++){
		for (int j = 0; j < GAME_BUT; j++){
			game_zone[i][j] = 1;
		}
	}
	for (int i = GAME_BUT; i < GAME_BUT + BOXSIZE; i++){
		for (int j = 0; j < GAME_RIGHT; j++)
			game_zone[i][j] = 1;
	}
}

// 设置背景
void DrawBackground(HDC hdc){
	// 背景1
	SelectObject(hdc, gcolor[3]);
	Rectangle(hdc, GAME_LEFT, 0, GAME_RIGHT, GAME_BUT);
	Rectangle(hdc, GAME_RIGHT, 0, WIN_WIDTH, HINT_EDGE);
	SelectObject(hdc, gcolor[1]);
	Rectangle(hdc, GAME_RIGHT, HINT_EDGE, WIN_WIDTH, WIN_LENGTH);

	// 背景2 - 长条边界
	for (int i = 0; i <= GAME_BUT; i += 10){
		DrawBox(hdc, 0, i, 0);
		DrawBox(hdc, GAME_RIGHT, i, 0);
	}
	for (int i = 10; i < GAME_RIGHT; i += 10)
		DrawBox(hdc, i, GAME_BUT, 0);
	for (int i = GAME_RIGHT; i < WIN_WIDTH; i += 10)
		DrawBox(hdc, i, HINT_EDGE, 0);
}

// 画小方块
void  DrawBox(HDC hdc, int x, int y, int color){
	SelectObject(hdc, gcolor[color]);
	Rectangle(hdc, x, y, x + BOXSIZE, y + BOXSIZE);
}

// 画一个大方块
void DrawBlocks(HDC hdc, POINT bs[], int color){
	for (int i = 0; i < 4; i++){
		DrawBox(hdc, bs[i].x, bs[i].y, color);
	}
}

// 获取下一个形状
void GetNext(HDC hdc){
	RECT rect;
	SetRect(&rect, GAME_RIGHT + BOXSIZE, 0, WIN_WIDTH, HINT_EDGE);
	FillRect(hdc, &rect, gcolor[3]);

	// 设置新的颜色
	SetColor();

	// 更新现在的状态
	now_color = next_color;
	now_dir = next_dir;
	now_shape = next_shape;

	// 当前方块赋值
	for (int i = 0; i < 4; i++)
		now_block[i] = Tetris[now_shape][now_dir][i];

	// 获取下一状态
	next_color = rand() % 5;
	if (next_color == 3)
		next_color = 0;
	next_shape = rand() % 2;
	next_dir = rand() % 4;

	// 画出下一个
	for (int i = 0; i < 4; i++)
		DrawBox(hdc, Tetris[next_shape][next_dir][i].x + 320, Tetris[next_shape][next_dir][i].y + 60, next_color);
}

// 判断是否被挡住
void IsBlocked(POINT now_block[4]){
	left_state = 0, right_state = 0, buttom_state = 0;
	block_state_but = 0, block_state_right = 0, block_state_left = 0;
	int pos_x, pos_y;
	for (int i = 0; i < 4; i++){
		pos_x = now_block[i].x;
		pos_y = now_block[i].y;
		if (pos_y + BOXSIZE >= GAME_BUT)   buttom_state = 1;                   // 底边框 3
		if (pos_x + BOXSIZE >= GAME_RIGHT) right_state = 1;                     // 右边框 2
		if (pos_x <= GAME_LEFT)            left_state = 1;                       // 左边框 1
		if (game_zone[pos_x - BOXSIZE][pos_y] && game_zone[pos_x - BOXSIZE][pos_y + BOXSIZE])                          // 左块边界 11
			block_state_left = 1;
		if (game_zone[pos_x + BOXSIZE][pos_y] && game_zone[pos_x + BOXSIZE][pos_y + BOXSIZE])      // 右块边界 12
			block_state_right = 1;
		if (game_zone[pos_x][pos_y + BOXSIZE])                                                     // 下块边界 13
			block_state_but = 1;
	}
}

// 保存落下的方块的位置
void Save(){
	for (int i = 0; i < 4; i++){
		for (int k = now_block[i].x; k < now_block[i].x + BOXSIZE; k++){
			for (int j = now_block[i].y; j < now_block[i].y + BOXSIZE; j++)
				game_zone[k][j] = 1;
		}
	}
}

// 显示有方块的区域
void Rander(HDC hdc){
	for (int i = GAME_LEFT; i < GAME_RIGHT; i += BOXSIZE){
		for (int j = 0; j < GAME_BUT; j += BOXSIZE){
			if (game_zone[i][j])
				DrawBox(hdc, i, j, now_color);// SetPixel(hdc, i, j, RGB(0, 255, 0));
			else DrawBox(hdc, i, j, 3);
		}
	}
}

// 游戏结束
void Game_over(HDC hdc, HWND hwnd){
	for (int i = 0; i < 4; i++){
		int x = now_block[i].x, y = now_block[i].y;
		if (game_zone[x][y] && y == BOXSIZE){
			over_state = 1;
			break;
		}
	}
	if (over_state){
		KillTimer(hwnd, 1);
		for (int i = GAME_LEFT; i < GAME_RIGHT; i += BOXSIZE){
			for (int j = 0; j < GAME_BUT; j += BOXSIZE){
				DrawBox(hdc, i, j, 2);// SetPixel(hdc, i, j, RGB(0, 255, 0));
			}
			Sleep(1);
		}
		MessageBox(NULL, L"游戏结束!", L"Tips", MB_ICONINFORMATION);
		PostQuitMessage(0);
	}
}

// 当一行全满时,下落
void Fall(HWND hwnd, HDC hdc){
	int lowest = 0, highest = 9999;
	for (int i = 0; i < 4; i++){    // 找到落下的最低点位置和最高点位置
		if (now_block[i].y + BOXSIZE >= lowest)  lowest = now_block[i].y + BOXSIZE;
		if (now_block[i].y <= highest) highest = now_block[i].y;
	}
	if (highest < ghighest) ghighest = highest;
	int line = 0, begin = 0;
	for (int j = lowest; j >= highest; j -= BOXSIZE){
		int flag = 0;
		for (int i = GAME_LEFT; i < GAME_RIGHT; i += BOXSIZE){
			if (!game_zone[i][j]){
				flag = 1;
				break;
			}
		}
		if (!flag){
			PlaySound(L"Falling.wav", NULL, SND_FILENAME);
			line++;
			// 消去该行
			for (int k = GAME_LEFT; k < GAME_RIGHT; k++){
				game_zone[k][j] = 0;
			}
			Rander(hdc);
			for (int i = j; i > ghighest - BOXSIZE; i--){
				for (int k = GAME_LEFT; k < GAME_RIGHT; k++){
					game_zone[k][i] = game_zone[k][i - BOXSIZE];
				}
			}
			for (int i = ghighest; i<ghighest+BOXSIZE; i++){
				for (int k = GAME_LEFT; k < GAME_RIGHT; k++){
					game_zone[k][i] = 0;
				}
			}
			Rander(hdc);
		}
	}
	if (line > 0){
		if (line == 1) score += 100;
		else if (line == 2) score += 300;
		else if (line == 3) score += 600;
		else if (line == 4) score += 1000;
		if (degree == 0) degree = 1;
		wsprintf(buffer, L"分数:%d", score);
		SetWindowText(hwndEdit1, buffer);

		if (score >= degree_score[degree]){
			degree++;
			wsprintf(buffer, L"等级:%d", degree);
			SetWindowText(hwnd, buffer);
		}
		if (degree == 7){
			PlaySound(L"success.wav", NULL, SND_FILENAME);
			MessageBox(hwnd, L"恭喜你成功过关!", L"游戏结束", MB_ICONINFORMATION);
			over_state = 1;
		}
	}
}

// 显示游戏状态
void ShowGameStatus(HWND hwnd){
	TCHAR buffer[50];
	wsprintf(buffer, TEXT("分数:%d"), score);
	SetWindowText(hwndEdit1, buffer);
	wsprintf(buffer, L"等级:%d", degree);
	SetWindowText(hwndEdit2, buffer);
	wsprintf(buffer, TEXT("游戏时间:%ds"), game_time);
	SetWindowText(hwndEdit3, buffer);
}

// micSendCommond 来实现不同格式音乐的播放
void PlayMusic(HWND hwnd, LPCWSTR type, LPCWSTR name){
	// 播放音乐
	MCI_OPEN_PARMS m_mciOpen;
	MCI_OPEN_PARMS m_mciPlay;
	m_mciOpen.lpstrDeviceType = type;
	m_mciOpen.lpstrElementName = name;
	MCIERROR mcierror = mciSendCommand(0, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_ELEMENT, (DWORD)&m_mciOpen);
	if (mcierror){
		TCHAR buf[128] = { 0 };
		mciGetErrorString(mcierror, buf, 128);
		MessageBox(hwnd, buf, NULL, 0);
	}
	else{
		m_mciPlay.dwCallback = (DWORD)hwnd;
		mciSendCommand(m_mciOpen.wDeviceID, MCI_PLAY, MCI_NOTIFY, (DWORD)(LPVOID)&m_mciPlay);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值