📄 tetris.cpp
字号:
int iX, iY;
//预览区填充黑色
rc.left = 240; rc.top = 40;
rc.right = 340; rc.bottom = 140;
FillRect(hdc,&rc,CreateSolidBrush(RGB(0,0,0)));
//绘制预览方块
SelectObject(hDcBitmap,LoadBitmap(hInst,MAKEINTRESOURCE(120+cc)));
iX = 1 + Tetris[ii][jj].a.x; iY = 1 + Tetris[ii][jj].a.y;
BitBlt(hdc,240+iX*20,40+iY*20,20,20,hDcBitmap,0,0,SRCCOPY);
iX = 1 + Tetris[ii][jj].b.x; iY = 1 + Tetris[ii][jj].b.y;
BitBlt(hdc,240+iX*20,40+iY*20,20,20,hDcBitmap,0,0,SRCCOPY);
iX = 1 + Tetris[ii][jj].c.x; iY = 1 + Tetris[ii][jj].c.y;
BitBlt(hdc,240+iX*20,40+iY*20,20,20,hDcBitmap,0,0,SRCCOPY);
iX = 1 + Tetris[ii][jj].d.x; iY = 1 + Tetris[ii][jj].d.y;
BitBlt(hdc,240+iX*20,40+iY*20,20,20,hDcBitmap,0,0,SRCCOPY);
return;
}
//随机产生新的方块数据
void RandomBlock(int * l, int * m, int * n)
{
srand((unsigned)time(NULL));
* l = rand() % 7;
* m = rand() % 4;
* n = rand() % 7;
return;
}
//方块越界检测
BOOL CheckBlock(int x, int y)
{
int m, n;
//初始位置不允许左右移动
if( y == -1 ) return false;
//游戏区越界检测
if ( Tetris[i][j].a.x+x<0 || Tetris[i][j].a.x+x>9 || Tetris[i][j].a.y+y>18 ) return FALSE;
if ( Tetris[i][j].b.x+x<0 || Tetris[i][j].b.x+x>9 || Tetris[i][j].b.y+y>18 ) return FALSE;
if ( Tetris[i][j].c.x+x<0 || Tetris[i][j].c.x+x>9 || Tetris[i][j].c.y+y>18 ) return FALSE;
if ( Tetris[i][j].d.x+x<0 || Tetris[i][j].d.x+x>9 || Tetris[i][j].d.y+y>18 ) return FALSE;
//方块相遇检测
for ( m=0; m<=18; m++ )
{
for ( n=0; n<=9; n++ )
{
if ( m==Tetris[i][j].a.y+y && n==Tetris[i][j].a.x+x && Matrix[m][n]!=-1 ) return FALSE;
if ( m==Tetris[i][j].b.y+y && n==Tetris[i][j].b.x+x && Matrix[m][n]!=-1 ) return FALSE;
if ( m==Tetris[i][j].c.y+y && n==Tetris[i][j].c.x+x && Matrix[m][n]!=-1 ) return FALSE;
if ( m==Tetris[i][j].d.y+y && n==Tetris[i][j].d.x+x && Matrix[m][n]!=-1 ) return FALSE;
}
}
return TRUE;
}
//方块下落
void DropTetris(HWND hwnd)
{
BOOL bReDraw;
int l, m, n;
HDC hdc;
//检测下一个方块位
if ( CheckBlock(x,y+1) )
{ //可以下落
hdc = GetDC(hwnd);
if ( y == -1 )
{
//传递方块并重绘预览区
i = ii; j = jj; c = cc;
RandomBlock(&ii,&jj,&cc);
DrawNext(hdc);
//绘制新方块
y ++;
DrawTetris(hdc,0,0,0);
}
else
{
//绘制新方块
y ++;
DrawTetris(hdc,0,1,0);
}
ReleaseDC(hwnd,hdc);
}
else
{ //不能下落
//在初始位置越界则结束游戏
if ( y == -1 )
{
GameOver(hwnd);
return;
}
//保存当前方块
Matrix[ Tetris[i][j].a.y+y ][ Tetris[i][j].a.x+x ] = c;
Matrix[ Tetris[i][j].b.y+y ][ Tetris[i][j].b.x+x ] = c;
Matrix[ Tetris[i][j].c.y+y ][ Tetris[i][j].c.x+x ] = c;
Matrix[ Tetris[i][j].d.y+y ][ Tetris[i][j].d.x+x ] = c;
//逐行扫描 检测满行
for ( l=18; l>=0; l-- )
{
bReDraw = TRUE;
for ( m=0; m<=9; m++ )
{
if ( Matrix[l][m] == -1 )
{
bReDraw = FALSE;
//break;
}
}
if ( bReDraw )//检测到第l行为满行
{
//更新计分器
iLayer += 1;
wsprintf(szBuffer,TEXT("%i"),iLayer);
SetWindowText(hLayer,szBuffer); //满行
iSorce += 10;
wsprintf(szBuffer,TEXT("%i"),iSorce);
SetWindowText(hSorce,szBuffer); //得分
if ( iSorce >= (iLevel*50+50)*iLevel/2 ) //升级
{
iLevel ++;
wsprintf(szBuffer,TEXT("%i"),iLevel);
SetWindowText(hLevel,szBuffer);
SendMessage(hStatus,SB_SETTEXT,1,(LPARAM)TEXT("恭喜升级!"));
}
else
{
wsprintf(szBuffer,TEXT("恭喜加分!距离下次升级还需 %i 分!"),(iLevel*50+50)*iLevel/2-iSorce);
SendMessage(hStatus,SB_SETTEXT,1,(LPARAM)szBuffer);
}
//删除满行数据
for ( m=0; m<=9; m++ ) Matrix[l][m] = -1;
//数据整体下移
for ( n=l; n>0; n-- )
{
for ( m=0; m<=9; m++ )
{
Matrix[n][m] = Matrix[n-1][m];
Matrix[n-1][m] = -1;
}
}
//重绘游戏区
hdc = GetDC(hwnd);
DrawMatrix(hdc);
ReleaseDC(hwnd,hdc);
l ++; //重新检查当前行
}
}
//重置方块位置
x = 4; y = -1;
}
}
//方块旋转
void RankTetris(HWND hwnd)
{
HDC hdc;
if ( j == 3 )
{
j = 0;
if ( CheckBlock(x,y) )
{
hdc = GetDC(hwnd);
DrawTetris(hdc,0,0,1);
ReleaseDC(hwnd,hdc);
}
else
{
j = 3;
}
}
else
{
j++;
if ( CheckBlock(x,y) )
{
hdc = GetDC(hwnd);
DrawTetris(hdc,0,0,1);
ReleaseDC(hwnd,hdc);
}
else
{
j --;
}
}
}
//在控件中显示默认设备字体
void SetNormalText(HWND hwnd,BOOL redraw)
{
static HFONT hFont;
LOGFONT lfBuffer;
GetObject(GetStockObject(DEFAULT_GUI_FONT),sizeof(lfBuffer),&lfBuffer);
hFont = CreateFontIndirect(&lfBuffer);
SendMessage(hwnd,WM_SETFONT,(WPARAM)hFont,(LPARAM)redraw);
return;
}
//处理自绘消息
void DrawButton(LPARAM lParam)
{
HDC hdc;
LPDRAWITEMSTRUCT pdis;
HPEN hpen;
pdis = (LPDRAWITEMSTRUCT)lParam; //包含自绘信息的结构体
hdc = pdis->hDC;
hpen = CreatePen(PS_SOLID,1,RGB(0,0,128));
SelectObject(hdc,hpen);
switch ( pdis->CtlID )
{
case IDM_UP:
//FillRect(pdis->hDC,&pdis->rcItem,(HBRUSH)(COLOR_BTNFACE+1));
SendMessage(pdis->hwndItem,WM_ERASEBKGND,(WPARAM)pdis->hDC,NULL);
if ( pdis->itemState & ODS_SELECTED )
{
MoveToEx(hdc,13,1,NULL);
LineTo(hdc,1,25);
LineTo(hdc,25,25);
LineTo(hdc,13,1);
MoveToEx(hdc,12,3,NULL);
LineTo(hdc,2,24);
}
else
{
MoveToEx(hdc,12,1,NULL);
LineTo(hdc,1,24);
LineTo(hdc,24,24);
LineTo(hdc,12,1);
MoveToEx(hdc,13,2,NULL);
LineTo(hdc,25,25);
LineTo(hdc,2,25);
}
break;
case IDM_DOWN:
//FillRect(pdis->hDC,&pdis->rcItem,(HBRUSH)(COLOR_BTNFACE+1));
SendMessage(pdis->hwndItem,WM_ERASEBKGND,(WPARAM)pdis->hDC,NULL);
if ( pdis->itemState & ODS_SELECTED )
{
MoveToEx(hdc,1,1,NULL);
LineTo(hdc,13,25);
LineTo(hdc,25,1);
LineTo(hdc,1,1);
MoveToEx(hdc,1,2,NULL);
LineTo(hdc,24,2);
}
else
{
MoveToEx(hdc,1,1,NULL);
LineTo(hdc,13,24);
LineTo(hdc,24,1);
LineTo(hdc,1,1);
MoveToEx(hdc,25,2,NULL);
LineTo(hdc,13,25);
LineTo(hdc,1,2);
}
break;
case IDM_LEFT:
//FillRect(pdis->hDC,&pdis->rcItem,(HBRUSH)(COLOR_BTNFACE+1));
SendMessage(pdis->hwndItem,WM_ERASEBKGND,(WPARAM)pdis->hDC,NULL);
if ( pdis->itemState & ODS_SELECTED )
{
MoveToEx(hdc,1,13,NULL);
LineTo(hdc,25,25);
LineTo(hdc,25,1);
LineTo(hdc,1,13);
MoveToEx(hdc,2,13,NULL);
LineTo(hdc,24,2);
}
else
{
MoveToEx(hdc,1,12,NULL);
LineTo(hdc,24,23);
LineTo(hdc,24,1);
LineTo(hdc,1,12);
MoveToEx(hdc,1,13,NULL);
LineTo(hdc,25,25);
LineTo(hdc,25,1);
}
break;
case IDM_RIGHT:
//FillRect(pdis->hDC,&pdis->rcItem,(HBRUSH)(COLOR_BTNFACE+1));
SendMessage(pdis->hwndItem,WM_ERASEBKGND,(WPARAM)pdis->hDC,NULL);
if ( pdis->itemState & ODS_SELECTED )
{
MoveToEx(hdc,1,1,NULL);
LineTo(hdc,1,25);
LineTo(hdc,25,12);
LineTo(hdc,1,1);
MoveToEx(hdc,2,24,NULL);
LineTo(hdc,2,2);
LineTo(hdc,24,13);
}
else
{
MoveToEx(hdc,1,1,NULL);
LineTo(hdc,1,24);
LineTo(hdc,24,12);
LineTo(hdc,1,1);
MoveToEx(hdc,1,25,NULL);
LineTo(hdc,25,13);
}
break;
}
DeleteObject(hpen);
return;
}
//游戏界面控件
void GameUI(HWND hwnd)
{
int stWidth[] = {100,-1};
HWND hTemp;
//工具栏
CreateToolbarEx(
hwnd, //hwnd 父窗口句柄
WS_VISIBLE|WS_CHILD|TBSTYLE_FLAT|TBSTYLE_TOOLTIPS|CCS_NODIVIDER, //ws 工具栏风格
IDR_TOOLBAR1, //wID 工具栏的子窗口ID
6, //nBitmaps 位图中包含多少个按钮小图标
hInst, //hBMInst 包含位图资源的模块句柄
IDB_BITMAP1, //wBMID 位图资源ID
tbButtons, //lpButtons
8, //iNumButtons 按钮总数
16, //dxButton 单个按钮宽度
16, //dyButton 单个按钮高度
16, //dxBitmap 单个按钮小图标的宽度
16, //dyBitmap 单个按钮小图标的高度
sizeof(TBBUTTON)); //uStructSize
//状态栏
hStatus = CreateStatusWindow(
WS_CHILD|WS_VISIBLE,
NULL,
hwnd,
IDS_STATUSBAR);
SendMessage(hStatus,SB_SETPARTS,2,(LPARAM)(stWidth));
//工具栏下的黑线
CreateWindow(
TEXT("static"), //lpClassName 类名
NULL, //lpWindowName 标题
WS_CHILD|WS_VISIBLE|SS_BLACKFRAME,
1,24,
358,1,
hwnd, //hWndParent
NULL, //hMenu
hInst,
NULL); //lpParam 额外的参数
//游戏区的外框
CreateWindow(
TEXT("static"),
NULL,
WS_CHILD|WS_VISIBLE|SS_GRAYFRAME,
17,37,
206,386,
hwnd,
NULL,
hInst,
NULL);
//预览区的外框
CreateWindow(
TEXT("static"),
NULL,
WS_CHILD|WS_VISIBLE|SS_GRAYFRAME,
237,37,
106,106,
hwnd,
NULL,
hInst,
NULL);
//级别
hTemp = CreateWindow(
TEXT("static"),
TEXT("级别 :"),
WS_CHILD|WS_VISIBLE|SS_LEFT,
240,190,
48,12,
hwnd,
NULL,
hInst,
NULL);
SetNormalText(hTemp,FALSE);
hLevel = CreateWindowEx(
WS_EX_STATICEDGE,
TEXT("static"),
NULL,
WS_CHILD|WS_VISIBLE|WS_GROUP|SS_RIGHT|SS_CENTERIMAGE,
280,186,
60,18,
hwnd,
NULL,
hInst,
NULL);
SetNormalText(hLevel,FALSE);
//满行
hTemp = CreateWindow(
TEXT("static"),
TEXT("满行 :"),
WS_CHILD|WS_VISIBLE|SS_LEFT,
240,220,
36,12,
hwnd,
NULL,
hInst,
NULL);
SetNormalText(hTemp,FALSE);
hLayer = CreateWindowEx(
WS_EX_STATICEDGE,
TEXT("static"),
NULL,
WS_CHILD|WS_VISIBLE|WS_GROUP|SS_RIGHT|SS_CENTERIMAGE,
280,216,
60,18,
hwnd,
NULL,
hInst,
NULL);
SetNormalText(hLayer,FALSE);
//得分
hTemp = CreateWindow(
TEXT("static"),
TEXT("得分 :"),
WS_CHILD|WS_VISIBLE|SS_LEFT,
240,250,
36,12,
hwnd,
NULL,
hInst,
NULL);
SetNormalText(hTemp,FALSE);
hSorce = CreateWindowEx(
WS_EX_STATICEDGE,
TEXT("static"),
NULL,
WS_CHILD|WS_VISIBLE|WS_GROUP|SS_RIGHT|SS_CENTERIMAGE,
280,246,
60,18,
hwnd,
NULL,
hInst,
NULL);
SetNormalText(hSorce,FALSE);
//最高分
hTemp = CreateWindow(
TEXT("static"),
TEXT("最高分"),
WS_CHILD|WS_VISIBLE|SS_LEFT,
240,280,
36,12,
hwnd,
NULL,
hInst,
NULL);
SetNormalText(hTemp,FALSE);
hSorceMax = CreateWindowEx(
WS_EX_STATICEDGE,
TEXT("static"),
NULL,
WS_CHILD|WS_VISIBLE|WS_GROUP|SS_RIGHT|SS_CENTERIMAGE,
280,276,
60,18,
hwnd,
NULL,
hInst,
NULL);
SetNormalText(hSorceMax,FALSE);
//方向键 上
CreateWindow(
TEXT("button"),
NULL,
WS_CHILD|WS_VISIBLE|BS_OWNERDRAW,
280,340,
26,26,
hwnd,
(HMENU)IDM_UP,
hInst,
NULL);
//方向键 下
CreateWindow(
TEXT("button"),
NULL,
WS_CHILD|WS_VISIBLE|BS_OWNERDRAW,
280,370,
26,26,
hwnd,
(HMENU)IDM_DOWN,
hInst,
NULL);
//方向键 左
CreateWindow(
TEXT("button"),
NULL,
WS_CHILD|WS_VISIBLE|BS_OWNERDRAW,
253,355,
26,26,
hwnd,
(HMENU)IDM_LEFT,
hInst,
NULL);
//方向键 右
CreateWindow(
TEXT("button"),
NULL,
WS_CHILD|WS_VISIBLE|BS_OWNERDRAW,
307,355,
26,26,
hwnd,
(HMENU)IDM_RIGHT,
hInst,
NULL);
hTemp = CreateWindow(
TEXT("static"),
TEXT("下载本程序源代码请访问作者主页:http://www.EasyIDE.cn"),
WS_CHILD|WS_VISIBLE|SS_LEFT|WS_DISABLED,
18,433,
500,12,
hwnd,
NULL,
hInst,
NULL);
SetNormalText(hTemp,FALSE);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -