所用编译器: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;
}