俄罗斯方块代码(自写)

所用编译器:Visual Studio 2013

所用语言:C

所写代码简单易学耐心看完全可看懂

#include <Windows.h>
#include <time.h>
#include <stdio.h>
#include <mmsystem.h>
#include <wingdi.h>
#include "resource.h"
#pragma comment(lib, "winmm.lib")
#define TIMER1 1
#define TIMER2 2
#define TIMER3 3
#define TIMER4 4
#define TIMER5 5
#define TIMER6 6
#define TIMER7 7
#define TIMER8 8
#define TIMER9 9
#define TIMER10 10
//俄罗斯方块Tetris
//数组 定义图形
//俄罗斯方块随机图形
int graphTetris[2][4] = { 0 };
int graphBackGround[24][30] = { 0 };
int flag;
int SqareID;
int Line = 0;
int List = 0;
int FLAG = 1;
int Number = 0;
int Grade = 1;
int SU;
int item = 1;
int kill;





//随机创造一种俄罗斯方块
void CreateTetris()
{
	int nIndex;
	if (item == 1)
	{
		srand((UINT)time(NULL));
		nIndex = rand() % 7;
		item = 0;
	}
	else
	{
		nIndex = SU; 
	}
	//总共七种图形
	switch (nIndex)
	{
		SqareID = nIndex;
	case 0:
		graphTetris[0][0] = 1; graphTetris[0][1] = 1; graphTetris[0][2] = 1; graphTetris[0][3] = 1;
		graphTetris[1][0] = 0; graphTetris[1][1] = 0; graphTetris[1][2] = 0; graphTetris[1][3] = 0;
		Line = 0;
		List = 8;
		flag = 0;
		break;
	case 1:
		graphTetris[0][0] = 1; graphTetris[0][1] = 0; graphTetris[0][2] = 0; graphTetris[0][3] = 0;
		graphTetris[1][0] = 1; graphTetris[1][1] = 1; graphTetris[1][2] = 1; graphTetris[1][3] = 0;
		Line = 0;
		List = 7;
		flag = 1;
		break;
	case 2:
		graphTetris[0][0] = 0; graphTetris[0][1] = 0; graphTetris[0][2] = 1; graphTetris[0][3] = 0;
		graphTetris[1][0] = 1; graphTetris[1][1] = 1; graphTetris[1][2] = 1; graphTetris[1][3] = 0;
		Line = 0;
		List = 7;
		flag = 2;
		break;
	case 3:
		graphTetris[0][0] = 0; graphTetris[0][1] = 1; graphTetris[0][2] = 1; graphTetris[0][3] = 0;
		graphTetris[1][0] = 1; graphTetris[1][1] = 1; graphTetris[1][2] = 0; graphTetris[1][3] = 0;
		Line = 0;
		List = 7;
		flag = 3;
		break;
	case 4:
		graphTetris[0][0] = 1; graphTetris[0][1] = 1; graphTetris[0][2] = 0; graphTetris[0][3] = 0;
		graphTetris[1][0] = 0; graphTetris[1][1] = 1; graphTetris[1][2] = 1; graphTetris[1][3] = 0;
		Line = 0;
		List = 7;
		flag = 4;
		break;
	case 5:
		graphTetris[0][0] = 0; graphTetris[0][1] = 1; graphTetris[0][2] = 1; graphTetris[0][3] = 0;
		graphTetris[1][0] = 0; graphTetris[1][1] = 1; graphTetris[1][2] = 1; graphTetris[1][3] = 0;
		Line = 0;
		List = 8;
		flag = 5;
		break;
	case 6:
		graphTetris[0][0] = 0; graphTetris[0][1] = 1; graphTetris[0][2] = 0; graphTetris[0][3] = 0;
		graphTetris[1][0] = 1; graphTetris[1][1] = 1; graphTetris[1][2] = 1; graphTetris[1][3] = 0;
		Line = 0;
		List = 7;
		flag = 6;
		break;
	}
	SqareID = nIndex;
}
//将随机产生的俄罗斯复制到背景块中
void CopyTetrisCreate_Ground()
{
	for (int i = 0; i < 2; i++)
	for (int j = 0; j < 4; j++)
	{
		graphBackGround[i][j + 7] = graphTetris[i][j];
	}
};




//总绘图函数 初始化 打开窗口然后在第一行就显示随机块
void Oncreate()
{
	srand((UINT)time(NULL));  //UINT 强制转型 
	CreateTetris();				//随机创造俄罗斯方块
	CopyTetrisCreate_Ground();	//赋值随机创造的俄罗斯到背景里面去
}




//随机创造一种俄罗斯方块并且将随机产生的俄罗斯复制到背景块中
void CreateRightTetris()
{
	srand((UINT)time(NULL));
	int nInt = rand() % 7; //总共七种图形
	SU = nInt;
	switch (nInt)
	{
	case 0:
		graphTetris[0][0] = 1; graphTetris[0][1] = 1; graphTetris[0][2] = 1; graphTetris[0][3] = 1;
		graphTetris[1][0] = 0; graphTetris[1][1] = 0; graphTetris[1][2] = 0; graphTetris[1][3] = 0;
		break;
	case 1:
		graphTetris[0][0] = 1; graphTetris[0][1] = 0; graphTetris[0][2] = 0; graphTetris[0][3] = 0;
		graphTetris[1][0] = 1; graphTetris[1][1] = 1; graphTetris[1][2] = 1; graphTetris[1][3] = 0;
		break;
	case 2:
		graphTetris[0][0] = 0; graphTetris[0][1] = 0; graphTetris[0][2] = 1; graphTetris[0][3] = 0;
		graphTetris[1][0] = 1; graphTetris[1][1] = 1; graphTetris[1][2] = 1; graphTetris[1][3] = 0;
		break;
	case 3:
		graphTetris[0][0] = 0; graphTetris[0][1] = 1; graphTetris[0][2] = 1; graphTetris[0][3] = 0;
		graphTetris[1][0] = 1; graphTetris[1][1] = 1; graphTetris[1][2] = 0; graphTetris[1][3] = 0;
		break;
	case 4:
		graphTetris[0][0] = 1; graphTetris[0][1] = 1; graphTetris[0][2] = 0; graphTetris[0][3] = 0;
		graphTetris[1][0] = 0; graphTetris[1][1] = 1; graphTetris[1][2] = 1; graphTetris[1][3] = 0;
		break;
	case 5:
		graphTetris[0][0] = 0; graphTetris[0][1] = 1; graphTetris[0][2] = 1; graphTetris[0][3] = 0;
		graphTetris[1][0] = 0; graphTetris[1][1] = 1; graphTetris[1][2] = 1; graphTetris[1][3] = 0;
		break;
	case 6:
		graphTetris[0][0] = 0; graphTetris[0][1] = 1; graphTetris[0][2] = 0; graphTetris[0][3] = 0;
		graphTetris[1][0] = 1; graphTetris[1][1] = 1; graphTetris[1][2] = 1; graphTetris[1][3] = 0;
		break;
	}
};
//把产生的随机块复制到背景中去
void AppearnextTetris()
{
	for (int a = 0; a < 2; a++)
	for (int b = 0; b < 4; b++)
		graphBackGround[a + 2][b + 22] = graphTetris[a][b];
};
//在右上角显示下一个随机产生的俄罗斯方块
void DrawRightSqare(HDC hDC)
{
	HBRUSH hNewBrush;
	HBRUSH hOldBrush;
	//第一种 长条  红色
	if (flag == 0)
	{
		hNewBrush = CreateSolidBrush(RGB(255, 0, 0));
		hOldBrush = (HBRUSH)SelectObject(hDC, hNewBrush);			//选中它
	}
	//第二种 左上一下三 橙色
	else if (flag == 1)
	{
		hNewBrush = CreateSolidBrush(RGB(255, 69, 0));
		hOldBrush = (HBRUSH)SelectObject(hDC, hNewBrush);			//选中它
	}
	//第三种 右上一下三 黄色
	else if (flag == 2)
	{
		hNewBrush = CreateSolidBrush(RGB(255, 255, 0));
		hOldBrush = (HBRUSH)SelectObject(hDC, hNewBrush);			//选中它
	}
	//第四种 右上二下二 绿色
	else if (flag == 3)
	{
		hNewBrush = CreateSolidBrush(RGB(0, 255, 0));
		hOldBrush = (HBRUSH)SelectObject(hDC, hNewBrush);			//选中它
	}
	//第五种 左上二下二 雪白色
	else if (flag == 4)
	{
		hNewBrush = CreateSolidBrush(RGB(255, 250, 250));
		hOldBrush = (HBRUSH)SelectObject(hDC, hNewBrush);			//选中它
	}
	//第六种 田字 粉红色
	else if (flag == 5)
	{
		hNewBrush = CreateSolidBrush(RGB(255, 130, 171));
		hOldBrush = (HBRUSH)SelectObject(hDC, hNewBrush);;			//选中它
	}
	//第七种 上中一下三 紫色
	else if (flag == 6)
	{
		hNewBrush = CreateSolidBrush(RGB(155, 48, 255));
		hOldBrush = (HBRUSH)SelectObject(hDC, hNewBrush);			//选中它
	}
	for (int i = 0; i < 8; i++)
	{
		for (int j = 19; j < 27; j++)
		{
			if (graphBackGround[i][j] == 1)
				Rectangle(hDC, j * 20, i * 20, (j + 1) * 20, (i + 1) * 20);
		}
	}
	hNewBrush = (HBRUSH)SelectObject(hDC, hOldBrush);
	DeleteObject(hNewBrush);
};




//绘制右边框的信息
void Drawresult(HDC hDC)
{
	TCHAR buffer[1000];
	int size = 0;
	size = wsprintf(buffer, TEXT("等级:"));
	TextOut(hDC, 20 * 21, 20 * 10, TEXT("等级:"), size);
	size = wsprintf(buffer, TEXT("分数:"));
	TextOut(hDC, 20 * 21, 20 * 12, TEXT("分数:"), size);
	size = wsprintf(buffer, TEXT("游戏说明:"));
	TextOut(hDC, 20 * 20, 20 * 14, TEXT("游戏说明:"), size);
	size = wsprintf(buffer, TEXT("变换图形:↑"));
	TextOut(hDC, 20 * 22, 20 * 16, TEXT("变换图形:↑"), size);
	size = wsprintf(buffer, TEXT("加速下降:↓"));
	TextOut(hDC, 20 * 22, 20 * 18, TEXT("加速下降:↓"), size);
	size = wsprintf(buffer, TEXT("左移:←"));
	TextOut(hDC, 20 * 22, 20 * 20, TEXT("左移:←"), size);
	size = wsprintf(buffer, TEXT("右移:→"));
	TextOut(hDC, 20 * 22, 20 * 22, TEXT("右移:→"), size);
};
//绘制边框
void DrawFrame(HDC hDC)
{
	HBRUSH hOldBrush;
	HBRUSH hNewBrush;
	hNewBrush = CreateSolidBrush(RGB(0, 0, 255));				//纯蓝色
	hOldBrush = (HBRUSH)SelectObject(hDC, hNewBrush);			//选中它
	//画边框
	for (int i = 1; i <= 24; i++)
		Rectangle(hDC, 0, (i - 1) * 20, 20, i * 20);	//利用for循环画图
	for (int i = 2; i <= 19; i++)
		Rectangle(hDC, 20 * (i - 1), 23 * 20, 20 * i, 24 * 20);
	for (int i = 1; i <= 23; i++)
		Rectangle(hDC, 20 * 18, 20 * (i - 1), 19 * 20, 20 * i);
	hNewBrush = (HBRUSH)SelectObject(hDC, hOldBrush);
	DeleteObject(hNewBrush);


	HBRUSH hOldBrush2;
	HBRUSH hNewBrush2;
	hNewBrush2 = CreateSolidBrush(RGB(255, 250, 250));			//雪白色
	hOldBrush2 = (HBRUSH)SelectObject(hDC, hNewBrush2);			//选中它
	Rectangle(hDC, 20 * 19 , 0, 20 * 28, 20 * 7);
	hNewBrush2 = (HBRUSH)(hDC, hOldBrush2);
	DeleteObject(hNewBrush2);


	HBRUSH hOldBrush3;
	HBRUSH hNewBrush3;
	hNewBrush3 = CreateSolidBrush(RGB(255, 250, 250));			//雪白色
	hOldBrush3 = (HBRUSH)SelectObject(hDC, hNewBrush3);			//选中它
	Rectangle(hDC, 20 * 19, 20*8, 20 * 28, 20 * 24);
	hNewBrush3 = (HBRUSH)(hDC, hOldBrush3);
	DeleteObject(hNewBrush3);

	HBRUSH hOldBrush4;
	HBRUSH hNewBrush4;
	hNewBrush4 = CreateSolidBrush(RGB(255, 250, 250));			//雪白色
	hOldBrush4 = (HBRUSH)SelectObject(hDC, hNewBrush4);			//选中它
	Rectangle(hDC, 20 , 0, 20 * 18, 20 * 23);
	hNewBrush4 = (HBRUSH)(hDC, hOldBrush4);
	DeleteObject(hNewBrush4);

	HBRUSH hOldBrush1;
	HBRUSH hNewBrush1;
	hNewBrush1 = CreateSolidBrush(RGB(255, 99, 71));			//番茄色
	hOldBrush1 = (HBRUSH)SelectObject(hDC, hNewBrush1);			//选中它
	for (int i = 0; i <= 8; i++)
		Rectangle(hDC, 20 * (19 + i), 20 * 7, 20 * (20 + i), 20 * 8);
	hNewBrush1 = (HBRUSH)(hDC, hOldBrush1);
	DeleteObject(hNewBrush1);



	Drawresult(hDC);
}
//绘制俄罗斯方块
void DrawTetris1(HDC hDC)
{
	HBRUSH hNewBrush;
	HBRUSH hOldBrush;
	//第一种 长条  红色
	if (flag == 0)
	{
		hNewBrush = CreateSolidBrush(RGB(255, 0, 0));
		hOldBrush = (HBRUSH)SelectObject(hDC, hNewBrush);			//选中它
	}
	//第二种 左上一下三 橙色
	else if (flag == 1)
	{
		hNewBrush = CreateSolidBrush(RGB(255, 69, 0));
		hOldBrush = (HBRUSH)SelectObject(hDC, hNewBrush);			//选中它
	}
	//第三种 右上一下三 黄色
	else if (flag == 2)
	{
		hNewBrush = CreateSolidBrush(RGB(255, 255, 0));
		hOldBrush = (HBRUSH)SelectObject(hDC, hNewBrush);			//选中它
	}
	//第四种 右上二下二 绿色
	else if (flag == 3)
	{
		hNewBrush = CreateSolidBrush(RGB(0, 205, 0));
		hOldBrush = (HBRUSH)SelectObject(hDC, hNewBrush);			//选中它
	}
	//第五种 左上二下二 雪白色
	else if (flag == 4)
	{
		hNewBrush = CreateSolidBrush(RGB(255, 250, 250));
		hOldBrush = (HBRUSH)SelectObject(hDC, hNewBrush);			//选中它
	}
	//第六种 田字 粉红色
	else if (flag == 5)
	{
		hNewBrush = CreateSolidBrush(RGB(255, 130, 171));
		hOldBrush = (HBRUSH)SelectObject(hDC, hNewBrush);;			//选中它
	}
	//第七种 上中一下三 紫色
	else if (flag == 6)
	{
		hNewBrush = CreateSolidBrush(RGB(155, 48, 255));
		hOldBrush = (HBRUSH)SelectObject(hDC, hNewBrush);			//选中它
	}
	for (int i = 0; i < 24; i++)
	{
		for (int j = 0; j < 19; j++)
		{
			if (graphBackGround[i][j] == 1)
				Rectangle(hDC, j * 20, i * 20, (j + 1) * 20, (i + 1) * 20);
		}
	}
	hNewBrush = (HBRUSH)SelectObject(hDC, hOldBrush);
	DeleteObject(hNewBrush);
	TCHAR buffer[1000];
	int size = 0;
	size = wsprintf(buffer, TEXT("%d"), Number);
	TextOut(hDC, 20 * 23, 20 * 12, buffer, size);
	size = wsprintf(buffer, TEXT("%d"), Grade);
	TextOut(hDC, 20 * 23, 20 * 10, buffer, size);
}
void DrawTetris2(HDC hMemDC)
{
	for (int i = 0; i < 24; i++)
	{
		for (int j = 0; j < 19; j++)
		{
			if (graphBackGround[i][j] == 2)
				Rectangle(hMemDC, j * 20, i * 20, (j + 1) * 20, (i + 1) * 20);
		}
	}
};




//绘图 内存机制
void OnPaint(HDC hDC)
{
	//双缓冲机制
	//创建一个内存DC(一起刷新的话就会闪烁,所以一次性把图都画好,然后复制到窗口,就解决了这个问题)
	//随后建立与屏幕显示兼容的内存显示设备
	HDC hMemDC = CreateCompatibleDC(hDC);
	//创建一张兼容位图(窗口大小)
	HBITMAP hbackbmp = CreateCompatibleBitmap(hDC, 567, 515);
	SelectObject(hMemDC, hbackbmp);
	//
	DrawFrame(hMemDC);
	DrawRightSqare(hMemDC);
	DrawTetris1(hMemDC);
	DrawTetris2(hMemDC);
	//思考:如何让方块掉下来??
	//复制==贴图 从内存复制在窗口上显示出来
	BitBlt(hDC, 0, 0, 576, 515, hMemDC, 0, 0, SRCCOPY);
	DeleteObject(hbackbmp);
	DeleteDC(hMemDC);
}
//开启定时器
void OnReturn(HWND hWnd)
{
	//开启定时器
	SetTimer(hWnd, TIMER1, 500, NULL); //ID等级为1的时候 下降时间为700ms
	kill=TIMER1;
	//如果返回一个非零值,那么就会返回一个消息,在回调函数中处理
	//UINT_ptr SetTimer(HWND hWnd(窗口句柄hWnd),UINT_PTR nIDEvent(ID可以用来设置等级为多少的时候设置下降速度),UINT uElapse,TIMERPROC lpTimerFuc)
	//可以按需要关闭定时器
};
//方块下落 记录下落的方块格子 然后要显示
void SqareDown()
{
	int a, b = 0;
	for (a = 23; a >= 0; a--)
	{
		for (b = 1; b < 18; b++)
		{
			if (graphBackGround[a][b] == 1)
			{
				graphBackGround[a + 1][b] = 1;
				graphBackGround[a][b] = 0;
			}
		}
	}
};
//判断俄罗斯方块能否继续下落的条件(不能够下降到边框以外)
int Stop()
{
	int i = 0;
	for (i = 0; i < 19; i++)
	{
		if (i == 0 || i == 18)
			continue;
		if (graphBackGround[22][i] == 1)
			return 0;
	}
	return 1;
};
//判断俄罗斯方块能否继续下落的第二个条件(下边有其它俄罗斯方块则不能继续下降)
int Stop2()
{
	int a, b = 0;
	for (a = 23; a >= 0; a--)
	{
		for (b = 0; b < 19; b++)
		{
			if (graphBackGround[a][b] == 1)
			{
				if (graphBackGround[a + 1][b] == 2)
					return 0;
			}
		}
	}
	return 1;
};
//将不能再下落的俄罗斯方块的赋值由1变为2
void change1to2()
{
	for (int i = 0; i < 24; i++)
	for (int j = 0; j < 19; j++)
	if (graphBackGround[i][j] == 1)
		graphBackGround[i][j] = 2;
};
//消除行(当这一行满格以后就消除 并且得十分)
void OnDelectSqare()
{
	int sum = 0;
	for (int i = 22; i >= 0; i--)
	{
		for (int j = 1; j <= 17; j++)
			sum += graphBackGround[i][j];
		if (sum == 34)
		{
			Number += 10;
			Grade = (Number / 100) + 1;
			//消除行
			for (int n = i; n >= 1; n--)
			{
				for (int m = 1; m <= 17; m++)
					graphBackGround[n][m] = graphBackGround[n - 1][m];
			}
			//如果没有i=23,那么赋值完以后i--,那么就会直接跳过了,从而不能解决消除多行的问题
			//所以,从头开始,是一个很好的选择
			i = 23;

		}
		//清零
		sum = 0;
	}
};
//如果俄罗斯到达顶层那么就结束掉游戏,并且弹出提示窗口
int OnGameOver()
{
	for (int i = 1; i <= 17; i++)
	{
		if (graphBackGround[0][i] == 2)
		{
			//结束游戏
			MessageBox(NULL, L"游戏结束啦!\n\n不要气馁,再来一盘吧!!!", L"wu~~!!!", MB_ICONEXCLAMATION);
			return 0;
		}
	}
	return 1;
};
//定时器响应函数
void OnTimer(HWND hWnd)
{
	HDC hDC = GetDC(hWnd);			//内核对象使用完一定要释放掉
	//如果Stop()返回的函数等于1那么就继续下落,返回0就停住
	if (Stop() == 1 && Stop2() == 1)
	{
		SqareDown();
		if (Grade == 2)
		{
			KillTimer(hWnd, TIMER1);
			SetTimer(hWnd, TIMER2, 400, NULL);
			kill = TIMER2;
		}
		else if (Grade ==3)
		{
			KillTimer(hWnd, TIMER2);
			SetTimer(hWnd, TIMER3, 450, NULL);
			kill = TIMER3;
		}
		else if (Grade == 4)
		{
			KillTimer(hWnd, TIMER3);
			SetTimer(hWnd, TIMER4, 400, NULL);
			kill = TIMER4;
		}
		else if (Grade == 5)
		{
			KillTimer(hWnd, TIMER4);
			SetTimer(hWnd, TIMER5, 350, NULL);
			kill = TIMER5;
		}
		else if (Grade == 6)
		{
			KillTimer(hWnd, TIMER5);
			SetTimer(hWnd, TIMER6, 300, NULL);
			kill = TIMER6;
		}
		else if (Grade == 7)
		{
			KillTimer(hWnd, TIMER5);
			SetTimer(hWnd, TIMER7, 250, NULL);
			kill = TIMER7;
		}
		else if (Grade == 8)
		{
			KillTimer(hWnd, TIMER7);
			SetTimer(hWnd, TIMER8, 200, NULL);
			kill = TIMER8;
		}
		else if (Grade == 9)
		{
			KillTimer(hWnd, TIMER8);
			SetTimer(hWnd, TIMER9, 100, NULL);
			kill = TIMER9;
		}
		else if (Grade == 10)
		{
			KillTimer(hWnd, TIMER9);
			SetTimer(hWnd, TIMER10, 50, NULL);
			kill = TIMER10;
		}
		Line++;
		if (Line == 1)
		{
			CreateRightTetris();
			AppearnextTetris();
		}
	}
	//生成新的俄罗斯方块
	//复制到背景上
	else
	{
		change1to2();
		OnDelectSqare();
		if (OnGameOver() == 0)
		{
			KillTimer(hWnd, TIMER1);
			KillTimer(hWnd, TIMER2);
			KillTimer(hWnd, TIMER3);
			KillTimer(hWnd, TIMER4);
			KillTimer(hWnd, TIMER5);
			KillTimer(hWnd, TIMER6);
			KillTimer(hWnd, TIMER7);
			KillTimer(hWnd, TIMER8);
			KillTimer(hWnd, TIMER9);
			KillTimer(hWnd, TIMER10);
		}
		//随机产生方块
		CreateTetris();
		//复制到背景上
		CopyTetrisCreate_Ground();
	}
	OnPaint(hDC);
	ReleaseDC(hWnd, hDC);
};
//方块加速运动
void OnDown(HWND hWnd)
{
	OnTimer(hWnd);
};
//方块左移赋值函数
void SqareLeft()
{
	for (int i = 0; i < 24; i++)
	{
		for (int j = 0; j < 19; j++)
		{
			if (graphBackGround[i][j] == 1)
			{
				graphBackGround[i][j - 1] = 1;
				graphBackGround[i][j] = 0;
			}
		}
	}
};
//方块能否左移的条件
int CanSqareLeft()
{
	for (int i = 0; i < 24; i++)
	{
		if (graphBackGround[i][1] == 1)
			return 0;
	}
	return 1;
};
int CanSqareLeft2()
{
	for (int i = 0; i < 24; i++)
	{
		for (int j = 0; j < 19; j++)
		{
			if (graphBackGround[i][j] == 1)
			{
				if (graphBackGround[i][j - 1] == 2)
					return 0;
			}
		}
	}
	return 1;
};
//开始画图 把方块左移的图形画出来
void OnLeft(HWND hWnd)
{

	//方块向左移
	if (CanSqareLeft() == 1 && CanSqareLeft2() == 1)
	{
		//获取DC
		HDC hDC = GetDC(hWnd);
		SqareLeft();
		List--;
		//显示方块(还要判断能否左移)
		OnPaint(hDC);
		//释放DC
		ReleaseDC(hWnd, hDC);
	}
};
//方块右移赋值函数
void SqareRight()
{
	for (int i = 0; i < 24; i++)
	{
		for (int j = 18; j >= 0; j--)
		{
			if (graphBackGround[i][j] == 1)
			{
				graphBackGround[i][j + 1] = 1;
				graphBackGround[i][j] = 0;
			}
		}
	}
};
//方块能否右移的条件
int CanSqareRight()
{
	for (int i = 0; i < 24; i++)
	{
		if (graphBackGround[i][17] == 1)
			return 0;
	}
	return 1;
};
int CanSqareRight2()
{
	for (int i = 0; i < 24; i++)
	{
		for (int j = 0; j < 19; j++)
		{
			if (graphBackGround[i][j] == 1)
			{
				if (graphBackGround[i][j + 1] == 2)
					return 0;
			}
		}
	}
	return 1;
};
//开始画图 把方块右移的图形画出来
void OnRight(HWND hWnd)
{
	//方块向右移
	if (CanSqareRight() == 1 && CanSqareRight2() == 1)
	{
		//获取DC
		HDC hDC = GetDC(hWnd);
		SqareRight();
		List++;
		//显示方块
		OnPaint(hDC);
		//释放DC
		ReleaseDC(hWnd, hDC);
	}
};
//改变方块形状
void ChangeSqare()
{
	char Graph[3][3];
	int item = 2;
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			Graph[i][j] = graphBackGround[Line + i][List + j];
		}
	}
	//变形后复制回去
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			graphBackGround[Line + i][List + j] = Graph[item][i];
			item--;
		}
		item = 2;
	}
};
//判断能否改变改变形状的条件
int CanChangeSqare()
{
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			if (graphBackGround[Line + i][List + j] == 2)
				return 0;
		}
	}
	return 1;
};
int CanChangeSqare1()
{
	if (List < 1)
	{
		List = 1;
	}
	else if (List>15)
	{
		List = 15;
	}
	return 1;
};
//改变长条方块的函数
void ChangeLongSqare()
{
	//想从第零行变
	if (Line == 0)
	{
		graphBackGround[Line][List - 1] = 0;
		graphBackGround[Line][List + 1] = 0;
		graphBackGround[Line][List + 2] = 0;
		graphBackGround[Line + 1][List] = 1;
		graphBackGround[Line + 2][List] = 1;
		graphBackGround[Line + 3][List] = 1;
		Line++;
	}
	//横条变竖条
	//清零
	else if (Line != 0 && graphBackGround[Line][List - 1] == 1)
	{
		graphBackGround[Line][List - 1] = 0;
		graphBackGround[Line][List + 1] = 0;
		graphBackGround[Line][List + 2] = 0;
		//赋值
		if (graphBackGround[Line + 1][List] == 2 || Line == 22)
		{
			graphBackGround[Line - 1][List] = 1;
			graphBackGround[Line - 2][List] = 1;
			graphBackGround[Line - 3][List] = 1;
			Line = Line - 2;
		}
		else if (graphBackGround[Line + 2][List] == 2 || Line == 21)
		{
			graphBackGround[Line + 1][List] = 1;
			graphBackGround[Line - 1][List] = 1;
			graphBackGround[Line - 2][List] = 1;
			Line--;
		}
		else
		{
			graphBackGround[Line - 1][List] = 1;
			graphBackGround[Line + 1][List] = 1;
			graphBackGround[Line + 2][List] = 1;
		}
	}
	//竖条变横条
	else if (graphBackGround[Line - 1][List] == 1)
	{
		//清零
		graphBackGround[Line - 1][List] = 0;
		graphBackGround[Line + 1][List] = 0;
		graphBackGround[Line + 2][List] = 0;
		//赋值
		if (graphBackGround[Line][List + 1] == 2 || List == 17)
		{
			graphBackGround[Line][List - 1] = 1;
			graphBackGround[Line][List - 2] = 1;
			graphBackGround[Line][List - 3] = 1;
			List = List - 2;
		}
		else if (graphBackGround[Line][List + 2] == 2 || List == 16)
		{
			graphBackGround[Line][List - 1] = 1;
			graphBackGround[Line][List - 2] = 1;
			graphBackGround[Line][List + 1] = 1;
			List--;
		}
		else if (graphBackGround[Line][List - 1] == 2 || List == 1)
		{
			graphBackGround[Line][List + 1] = 1;
			graphBackGround[Line][List + 2] = 1;
			graphBackGround[Line][List + 3] = 1;
			List = List++;
		}
		else if (graphBackGround[Line][List - 2] == 2 || List == 2)
		{
			graphBackGround[Line][List - 1] = 1;
			graphBackGround[Line][List + 1] = 1;
			graphBackGround[Line][List + 2] = 1;
		}
		else
		{
			graphBackGround[Line][List - 1] = 1;
			graphBackGround[Line][List + 1] = 1;
			graphBackGround[Line][List + 2] = 1;
		}
	}
};
//判断能否改变长条方块的函数
int CanChangeLongSqare()
{
	//有墙
	//左边墙
	if ((List == 1 && graphBackGround[Line][List + 1] == 2) || (List == 1 && graphBackGround[Line][List + 2] == 2) || (List == 1 && graphBackGround[Line][List + 3] == 2))
		return 0;
	else if (List == 2 && graphBackGround[Line][List + 1] == 2 || List == 2 && graphBackGround[Line][List + 2] == 2)
		return 0;
	else if (List == 3 && graphBackGround[Line][List + 1] == 2)
		return 0;
	//右边墙
	else if ((List == 17 && graphBackGround[Line][List - 1] == 2) || (List == 17 && graphBackGround[Line][List - 2] == 2) || (List == 17 && graphBackGround[Line][List - 3] == 2))
		return 0;
	else if (List == 16 && graphBackGround[Line][List - 1] == 2 || List == 16 && graphBackGround[Line][List - 2] == 2)
		return 0;
	else if (List == 15 && graphBackGround[Line][List - 1] == 2)
		return 0;
	//没墙
	else if (graphBackGround[Line][List - 1] == 2 && graphBackGround[Line][List + 1] == 2) return 0;
	else if (graphBackGround[Line][List - 1] == 2 && graphBackGround[Line][List + 2] == 2) return 0;
	else if (graphBackGround[Line][List - 2] == 2 && graphBackGround[Line][List + 1] == 2) return 0;
	else if (graphBackGround[Line][List - 1] == 2 && graphBackGround[Line][List + 3] == 2) return 0;
	else if (graphBackGround[Line][List - 2] == 2 && graphBackGround[Line][List + 2] == 2) return 0;
	else if (graphBackGround[Line][List - 3] == 2 && graphBackGround[Line][List + 1] == 2) return 0;
	else if (Line == 0 && graphBackGround[Line + 1][List] == 2) return 0;
	else if (Line == 0 && graphBackGround[Line + 2][List] == 2) return 0;
	else if (Line == 0 && graphBackGround[Line + 3][List] == 2) return 0;
	else return 1;
};
//按键以后判断应该是那种类型的switch语句
void OnSqareChange(HWND hWnd)
{
	HDC hDC = GetDC(hWnd);
	switch (SqareID)
	{
	case 1:
	case 2:
	case 3:
	case 4:
	case 6:
		if (CanChangeSqare() == 1 && CanChangeSqare1() == 1)
			ChangeSqare();
		else
			return;
		break;
	case 0:
		if (CanChangeLongSqare() == 1)
			ChangeLongSqare();
		break;
	case 5:
		return;
	}
	OnPaint(hDC);
	ReleaseDC(hWnd, hDC);
};
//方块停住 停在最底处
//返回零停住
LRESULT CALLBACK WindowProc(
	HWND hWnd,	//窗口句柄
	UINT uMsg,		//消息编号
	WPARAM wParam,	//附加参数
	LPARAM lParam  //附加参数  点了什么键要给计算机处理,鼠标点一下也是一个消息,数据就存在这两个参数里面
	)
{
	PAINTSTRUCT ps;				//画图的数据--保存在这里
	HDC	hDC;							//绘图句柄
	//如何实现往下掉?是因为数值改变了(数组)
	switch (uMsg)
	{
	case WM_CREATE:
		Oncreate();				//窗口创建处理函数 需要声明,把随机创造的俄罗斯方块,复制到背景图形中去,2行4列
		//SUM(hDC);
		break;
	case WM_TIMER:
		OnTimer(hWnd);
		break;
	case WM_PAINT:					//绘图消息
		//开始画图
		hDC = BeginPaint(hWnd, &ps);
		//显示文字
		//画边框(调用Draw函数画)
		OnPaint(hDC);
		//结束画图
		EndPaint(hWnd, &ps);
		break;
	case WM_KEYDOWN:				//按下键盘的消息
		switch (wParam)
		{
		case VK_RETURN:
			PlaySound(L"C:\\Users\\Administrator\\Documents\\Visual Studio 2013\\Projects\\Win32Project1\\Win32Project1\\小霸王游戏机卡的背景音乐.wav", NULL, SND_LOOP | SND_ASYNC);
			//MessageBox(hWnd,L"按下回车键开始游戏\n再按一下可以暂停游戏哦",L"提示",MB_OK);
			//写一个专门响应回车键的函数
			OnReturn(hWnd);
			break;
			//左移
		case VK_LEFT:
			OnLeft(hWnd);
			break;
			//右移
		case VK_RIGHT:
			OnRight(hWnd);
			break;
			//按上变换图形
		case VK_UP:
			OnSqareChange(hWnd);
			break;
		case VK_DOWN:
			OnDown(hWnd);
			break;
		}
		break;
	case WM_CLOSE:					//窗口关闭消息
		DestroyWindow(hWnd);
		break;
	case WM_ERASEBKGND:
		//禁止系统刷新背景
		break;
	case WM_DESTROY:				//窗口摧毁消息
		KillTimer(hWnd, TIMER1);
		KillTimer(hWnd, kill);
		PostQuitMessage(0);			//发送退出进程消息
		break;
	}
	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
//主函数 main-->黑窗口
int WINAPI WinMain(
	HINSTANCE hInstance,			//应用程序实例句柄
	//打开任务管理器 我们可以看到很多个进程 这些进程 就是一个个实例 实例句柄就是用来标识它们的 (识别)
	HINSTANCE hPrevInstance,		//应用程序前一个实例句柄
	LPSTR lpCmdLine,				//表示Char *(指针)的一个字符  命令行参数
	int nShowCmd					//窗口的显示方式 (比如:最大化 最小化 还原 关闭)
	)
{
	//1、设计窗口
	//每个窗口都有属于它自己的类型 是自己编写的
	//窗口类型名
	TCHAR szAppClassName[] = TEXT("Tetris");

	//定义一个结构体
	WNDCLASS wndClass;
	wndClass.cbClsExtra = 0;									//窗口类额外扩展空间大小
	wndClass.cbWndExtra = 0;									//窗口额外扩展空间大小
	wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);//背景颜色  强制转型 HBRUSH表示刷子
	wndClass.hCursor = LoadCursor(hInstance,MAKEINTRESOURCE( IDC_CURSOR1));				//加载系统里面的一个光标 实例句柄为NULL
	wndClass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));										//图标 不要图标就带NULL 
	wndClass.hInstance = hInstance;								//实例句柄
	wndClass.lpfnWndProc = WindowProc;							//窗口处理函数
	wndClass.lpszClassName = szAppClassName;					//窗口类型名
	wndClass.lpszMenuName = NULL;								//菜单名
	wndClass.style = CS_HREDRAW | CS_VREDRAW;					//窗口类的风格

	//2、注册窗口
	RegisterClass(&wndClass);

	//3、创建窗口
	HWND hWnd;
	hWnd = CreateWindow(
		//WS_EX_TOPMOST,
		szAppClassName,							//窗口类型名
		TEXT("凯铭俄罗斯方块"),					//窗口标题名
		WS_MINIMIZEBOX | WS_SYSMENU,			//窗口的风格
		200,									//窗口左上角横坐标
		100,									//窗口左上角纵坐标
		576,									//窗口的宽度
		515,									//窗口的高度
		NULL,									//父窗口句柄
		NULL,									//菜单句柄
		hInstance,								//实例句柄
		NULL									//参数
		);
	//4、显示窗口
	ShowWindow(
		hWnd,											//创建的窗口句柄
		nShowCmd											//窗口的显示方式
		);
	//更新窗口
	UpdateWindow(hWnd);
	//提示
	//开始游戏提示
	MessageBox(NULL, L"操作方法:上下左右键\n\n满级10级你能玩到多少级???\n随着等级的升高速度会越来越快哦!!!\n\n快按下Enter键来玩耍吧!", L"提示", MB_OK);
	//消息循环
	MSG msg;								 					//定义一个结构体--消息
	while (GetMessage(&msg, NULL, 0, 0))
	{
		//将虚拟键消息转换为字符消息
		TranslateMessage(&msg);
		//将消息分发给回调函数
		DispatchMessage(&msg);
	}

	return 0;
}

 

  • 25
    点赞
  • 104
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值