因为把目标定在了游戏上,最近在学习win32编程
经过一段时间的学习,开始进行编程实现俄罗斯方块,记录一下其中遇到的一些问题
一开始是看网上的教程学习的,但是做完一部分之后发现 会有闪屏的情况 所以又去网上搜索了一下发现要用到双缓冲。
注意:这段开始正确性有待考证!
我一开始的时候是把
drawTeris();
drawBackGround();
drawBlocked();
都放在了WM_PAINT事件里
而且里面都用了双缓冲来绘制,结果导致后面闪屏更加频繁,后来把所有的绘制动作都交由一个缓冲区来处理,然后删掉其他函数中的双缓冲相关代码并加入drawBackGround中,这样在WM_PAINT事件中只需要调用一次drawBackground就行了 而且也没发现有闪屏了。
另外还发现一个比较奇葩的问题:
一个用了BOOL类型的变量后面把他当作bool类型进行memcpy的时候会出问题
贴上在网上找到的资料:
windows为了兼容问题定义的基础变量。
typedef unsigned long DWORD;
typedef int BOOL;
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef float FLOAT;
typedef FLOAT *PFLOAT;
typedef BOOL near *PBOOL;
typedef BOOL far *LPBOOL;
typedef BYTE near *PBYTE;
typedef BYTE far *LPBYTE;
typedef int near *PINT;
typedef int far *LPINT;
typedef int BOOL;
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef float FLOAT;
typedef FLOAT *PFLOAT;
typedef BOOL near *PBOOL;
typedef BOOL far *LPBOOL;
typedef BYTE near *PBYTE;
typedef BYTE far *LPBYTE;
typedef int near *PINT;
typedef int far *LPINT;
根据上面这段可以发现其实BOOL是个int类型的
附上 代码
tetris.h
#pragma once
#include "resource.h"
//函数声明
void checkComplite(); //查看一行是否能消去 采用从上往下的消法,消去一行后把上面的每行都往下移,但是我感觉效率有点低,以后看能不能有点改进
void drawBlocked(HDC hdc); //绘制当前已经存在砖块的区域
void DrawBackGround(HDC hdc); //绘制背景
void outPutBoxInt(int num); //自定义的弹窗函数 用于调试
void outPutBoxString(TCHAR str[1024]);
void setRandomT(); //随机生成一个方块用作下一次掉落
void init_game(); //初始化
void fillBlock(); //到达底部后填充矩阵
void RotateTeris(BOOL bTeris[4][4]); //旋转矩阵
void DrawTeris(HDC mdc); //绘制正在下落的方块
void drawNext(HDC hdc); //绘制下一个将要掉落的方块
void drawScore(HDC hdc); //绘制分数
void drawCompleteParticle(int line);
int RandomInt(int _min,int _max); //获取一个随机int
int CheckValide(int curPosX,int curPosY,BOOL bCurTeris[4][4]); //给定一个矩阵,查看是否合法
int selectDiffculty(HWND hWnd,int dif);
int selectLayOut(HWND hWnd,int layout);
//常量声明
const int BORDER_X = 10;
const int BORDER_Y = 10;
const int SCREEN_LEFT_X = 300 + BORDER_X;
const int SCREEN_Y = 600 + BORDER_Y;
const int SCREEN_RIGHT_X = 180+BORDER_X*2;
const int SCREEN_X = SCREEN_LEFT_X+SCREEN_RIGHT_X;
const BOOL state_teris[][4][4]=
{
{{1,1,1,1},{0,0,0,0},{0,0,0,0},{0,0,0,0}},
{{0,1,1,0},{0,1,1,0},{0,0,0,0},{0,0,0,0}},
{{0,1,1,1},{0,0,0,1},{0,0,0,0},{0,0,0,0}},
{{0,1,1,0},{0,0,1,1},{0,0,0,0},{0,0,0,0}},
{{0,1,0,0},{1,1,1,0},{0,0,0,0},{0,0,0,0}},
{{0,1,1,1},{0,1,0,0},{0,0,0,0},{0,0,0,0}},
{{0,1,1,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}}
};
//全局变量声明
bool g_hasBlocked[50][50];
RECT rc_left,rc_right,rc_right_top,rc_right_bottom,rc_main;
int g_speed = 300;
int t_speed = 300;
BOOL bCurTeris[4][4];
BOOL bNextCurTeris[4][4];
int curPosX,curPosY;
int rd_seed = 1995421;
int tPre=0,tCur;
int GAME_STATE = 0;
int GAME_SCORE=0;
int GAME_DIFF = 1;
int NUM_X = 10;
int NUM_Y = 20;
int BLOCK_SIZE = 30;
tetris.cpp:
// Tetris.cpp : 定义应用程序的入口点。
//
/*
记录于2016-5-29 星期日 由于闪屏过于显眼,采用双缓冲
*/
#include "stdafx.h"
#include "Tetris.h"
#include "windows.h"
#include <mmsystem.h>
#pragma comment(lib, "WINMM.LIB")
#define MAX_LOADSTRING 100
// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
// 全局变量:
HINSTANCE hInst; // 当前实例
TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
init_game();
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: 在此放置代码。
MSG msg;
HACCEL hAccelTable;
// 初始化全局字符串
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_TETRIS, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// 执行应用程序初始化:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TETRIS));
// 主消息循环:
while (1)
{
if (PeekMessage(&msg,0,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
if (msg.message==WM_QUIT)
{
break;
}
}
else
{
if ((GAME_STATE&2)!=0)
{
tCur = GetTickCount();
if (tCur-tPre>g_speed)
{
int flag = CheckValide(curPosX,curPosY+1,bCurTeris);
if (flag==1)
{
curPosY++;
tPre = tCur;
HWND hWnd = GetActiveWindow();
InvalidateRect(hWnd,&rc_left,FALSE);
InvalidateRect(hWnd,&rc_right_top,FALSE);
}
else if (flag==-2)
{
g_speed = t_speed;
fillBlock();
checkComplite();
setRandomT();
curPosX = (NUM_X-4)>>1;
curPosY = 0;
HWND hWnd = GetActiveWindow();
InvalidateRect(hWnd,&rc_main,FALSE);
}
else if(flag==-3)
{
HWND hWnd = GetActiveWindow();
if (MessageBox(hWnd,L"胜败乃兵家常事,菜鸡请重新来过",L":时光机",MB_YESNO)==IDYES)
{
init_game();
}
else
{
break;
}
}
}
}
}
}
return (int) msg.wParam;
}
//
// 函数: MyRegisterClass()
//
// 目的: 注册窗口类。
//
// 注释:
//
// 仅当希望
// 此代码与添加到 Windows 95 中的“RegisterClassEx”
// 函数之前的 Win32 系统兼容时,才需要此函数及其用法。调用此函数十分重要,
// 这样应用程序就可以获得关联的
// “格式正确的”小图标。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TETRIS));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_TETRIS);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
//
// 函数: InitInstance(HINSTANCE, int)
//
// 目的: 保存实例句柄并创建主窗口
//
// 注释:
//
// 在此函数中,我们在全局变量中保存实例句柄并
// 创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // 将实例句柄存储在全局变量中
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// 函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// 目的: 处理主窗口的消息。
//
// WM_COMMAND - 处理应用程序菜单
// WM_PAINT - 绘制主窗口
// WM_DESTROY - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
int nWinx,nWiny,nClientX,nClientY;
int posX,posY;
RECT rect;
HMENU hSysmenu;
switch (message)
{
case WM_CREATE:
GetWindowRect(hWnd,&rect);
nWinx = 530;
nWiny = 680;
posX = GetSystemMetrics(SM_CXSCREEN);
posY = GetSystemMetrics(SM_CYSCREEN);
posX = (posX - nWinx)>>1;
posY = (posY - nWiny)>>1;
GetClientRect(hWnd,&rect);
nClientX = rect.right - rect.left;
nClientY = rect.bottom - rect.top;
MoveWindow(hWnd,posX,posY,530,680,TRUE);
hSysmenu = GetSystemMenu(hWnd,false);
AppendMenu(hSysmenu,MF_SEPARATOR,0,NULL);
AppendMenu(hSysmenu,0,IDM_DIFF,L"难度选择");
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 分析菜单选择:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
case ID_dif1:
selectDiffculty(hWnd,1);
break;
case ID_dif2:
selectDiffculty(hWnd,2);
break;
case ID_dif3:
selectDiffculty(hWnd,3);
break;
case ID_LAYOUT1:
selectLayOut(hWnd,1);
break;
case ID_LAYOUT2:
selectLayOut(hWnd,2);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_KEYDOWN:
hdc = GetDC(hWnd);
InvalidateRect(hWnd,NULL,false);
switch(wParam)
{
case VK_LEFT:
curPosX--;
if(CheckValide(curPosX,curPosY,bCurTeris)!=1)
{
curPosX++;
}
break;
case VK_RIGHT:
curPosX++;
if(CheckValide(curPosX,curPosY,bCurTeris)!=1)
{
curPosX--;
}
break;
case VK_UP:
RotateTeris(bCurTeris);
break;
case VK_DOWN:
if (g_speed==t_speed)
g_speed =10 ;
else
g_speed = t_speed;
//outPutBoxInt(g_speed);
break;
case 'W':
RotateTeris(bCurTeris);
break;
case 'A':
curPosX--;
if(CheckValide(curPosX,curPosY,bCurTeris)!=1)
{
curPosX++;
}
break;
case 'D':
curPosX++;
if(CheckValide(curPosX,curPosY,bCurTeris)!=1)
{
curPosX--;
}
break;
case 'S':
if (g_speed==t_speed)
g_speed =10 ;
else
g_speed = t_speed;
//outPutBoxInt(g_speed);
break;
default:
break;
}
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: 在此添加任意绘图代码...
DrawBackGround(hdc);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// “关于”框的消息处理程序。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
void drawBlocked(HDC mdc)
{
int i,j;
HBRUSH hBrush = (HBRUSH)CreateSolidBrush(RGB(255,255,0));
SelectObject(mdc,hBrush);
for (i=0;i<NUM_Y;i++)
{
for (j=0;j<NUM_X;j++)
{
if (g_hasBlocked[i][j])
{
Rectangle(mdc,BORDER_X+j*BLOCK_SIZE,BORDER_Y+i*BLOCK_SIZE,
BORDER_X+(j+1)*BLOCK_SIZE,BORDER_Y+(i+1)*BLOCK_SIZE
);
}
}
}
DeleteObject(hBrush);
}
int CheckValide(int startX,int startY,BOOL bTemp[4][4])
{
int i,j;
for (i=3;i>=0;i--)
{
for (j=3;j>=0;j--)
{
if(bTemp[i][j])
{
if (j+startX<0||j+startX>=NUM_X)
{
return -1;
}
if (i+startY>=NUM_Y)
{
return -2;
}
if (g_hasBlocked[i+startY][j+startX])
{
//outPutBoxInt(j+startY);
if (curPosY==0)
{
return -3;
}
return -2;
}
}
}
}
//MessageBox(NULL,L"这里",L"as",MB_OK);
//outPutBoxInt(curPosY);
return 1;
}
void checkComplite()
{
int i,j,k,count=0;
for (i=0;i<NUM_Y;i++)
{
bool flag = true;
for (j=0;j<NUM_X;j++)
{
if(!g_hasBlocked[i][j])
{
flag = false;
}
}
if (flag)
{
count++;
for (j=i;j>=1;j--)
{
for (k=0;k<NUM_X;k++)
{
g_hasBlocked[j][k] = g_hasBlocked[j-1][k];
}
}
drawCompleteParticle(i);
Sleep(300);
PlaySound(_T("coin.wav"),NULL,SND_FILENAME|SND_ASYNC);
}
}
GAME_SCORE += int(count*1.5);
}
VOID outPutBoxInt(int num)
{
TCHAR szBuf[1024];
LPCTSTR str = TEXT("%d");
wsprintf(szBuf,str,num);
MessageBox(NULL,szBuf,L"aasa",MB_OK);
}
VOID outPutBoxString(TCHAR str[1024])
{
TCHAR szBuf[1024];
LPCTSTR cstr = TEXT("%s");
wsprintf(szBuf,cstr,str);
MessageBox(NULL,szBuf,L"aasa",MB_OK);
}
void setRandomT()
{
int rd_start = RandomInt(0,sizeof(state_teris)/sizeof(state_teris[0]));
int rd_next = RandomInt(0,sizeof(state_teris)/sizeof(state_teris[0]));
//outPutBoxInt(rd_start);
//outPutBoxInt(rd_next);
//outPutBoxInt(rd_start);
if (GAME_STATE==0)
{
GAME_STATE = GAME_STATE | 0x0001;
//outPutBoxInt(GAME_STATE);
memcpy(bCurTeris,state_teris[rd_start],sizeof(state_teris[rd_start]));
memcpy(bNextCurTeris,state_teris[rd_next],sizeof(state_teris[rd_next]));
}
else
{
memcpy(bCurTeris,bNextCurTeris,sizeof(bNextCurTeris));
memcpy(bNextCurTeris,state_teris[rd_next],sizeof(state_teris[rd_next]));
}
}
void init_game()
{
GAME_SCORE = 0;
setRandomT();
curPosX = (NUM_X-4)>>1;
curPosY = 0;
memset(g_hasBlocked,0,sizeof(g_hasBlocked));
rc_left.left = 0;
rc_left.right = SCREEN_LEFT_X;
rc_left.top = 0;
rc_left.bottom = SCREEN_Y;
rc_right.left = rc_left.right+BORDER_X;
rc_right.right = 180+rc_right.left;
rc_right.top = 0;
rc_right.bottom = SCREEN_Y;
rc_main.left = 0;
rc_main.right = SCREEN_X;
rc_main.top = 0;
rc_main.bottom = SCREEN_Y;
rc_right_top.left = rc_right.left;
rc_right_top.top = rc_right.top;
rc_right_top.right = rc_right.right;
rc_right_top.bottom = (rc_right.bottom) / 2;
rc_right_bottom.left = rc_right.left;
rc_right_bottom.top = rc_right_top.bottom+BORDER_Y;
rc_right_bottom.right = rc_right.right;
rc_right_bottom.bottom = rc_right.bottom;
g_speed = t_speed = 1000-GAME_DIFF*280;
}
void fillBlock()
{
int i,j;
for (i=0;i<4;i++)
{
for (j=0;j<4;j++)
{
if(bCurTeris[i][j])
{
g_hasBlocked[curPosY+i][curPosX+j] = 1;
}
}
}
}
void RotateTeris(BOOL bTeris[4][4])
{
BOOL bNewTeris[4][4];
int x,y;
for (x=0;x<4;x++)
{
for(y=0;y<4;y++)
{
bNewTeris[x][y] = bTeris[3-y][x];
//逆时针:
//bNewTeris[x][y] = bTeris[y][3-x];
}
}
if (CheckValide(curPosX,curPosY,bNewTeris)==1)
{
memcpy(bTeris,bNewTeris,sizeof(bNewTeris));
}
}
int RandomInt(int _min,int _max)
{
srand((rd_seed++)%65532+GetTickCount());
return _min+rand()%(_max-_min);
}
VOID DrawTeris(HDC mdc)
{
int i,j;
HPEN hPen = (HPEN)GetStockObject(BLACK_PEN);
HBRUSH hBrush = (HBRUSH)GetStockObject(WHITE_BRUSH);
SelectObject(mdc,hPen);
SelectObject(mdc,hBrush);
for (i=0;i<4;i++)
{
for (j=0;j<4;j++)
{
if(bCurTeris[i][j])
{
Rectangle(mdc,(j+curPosX)*BLOCK_SIZE+BORDER_X,(i+curPosY)*BLOCK_SIZE+BORDER_Y,(j+1+curPosX)*BLOCK_SIZE+BORDER_X,(i+1+curPosY)*BLOCK_SIZE+BORDER_Y);
}
}
}
drawBlocked(mdc);
DeleteObject(hPen);
DeleteObject(hBrush);
}
VOID DrawBackGround(HDC hdc)
{
HBRUSH hBrush = (HBRUSH)GetStockObject(GRAY_BRUSH);
HDC mdc = CreateCompatibleDC(hdc);
HBITMAP hBitmap = CreateCompatibleBitmap(hdc,SCREEN_X,SCREEN_Y);
SelectObject(mdc,hBrush);
SelectObject(mdc,hBitmap);
HBRUSH hBrush2 = (HBRUSH)GetStockObject(WHITE_BRUSH);
FillRect(mdc,&rc_main,hBrush2);
Rectangle(mdc,rc_left.left+BORDER_X,rc_left.top+BORDER_Y,rc_left.right,rc_left.bottom);
Rectangle(mdc,rc_right.left+BORDER_X,rc_right.top+BORDER_Y,rc_right.right,rc_right.bottom);
DrawTeris(mdc);
drawNext(mdc);
drawScore(mdc);
::BitBlt(hdc,0,0,SCREEN_X,SCREEN_Y,mdc,0,0,SRCCOPY);
DeleteObject(hBrush);
DeleteDC(mdc);
DeleteObject(hBitmap);
DeleteObject(hBrush2);
// int x,y;
// HPEN hPen = (HPEN)GetStockObject(NULL_PEN);
// HBRUSH hBrush = (HBRUSH)GetStockObject(GRAY_BRUSH);
// SelectObject(hdc,hPen);
// SelectObject(hdc,hBrush);
// for (x = 0;x<NUM_X;x++)
// {
// for(y=0;y<NUM_Y;y++)
// {
// Rectangle(hdc,BORDER_X+x*BLOCK_SIZE,BORDER_Y+y*BLOCK_SIZE,
// BORDER_X+(x+1)*BLOCK_SIZE,
// BORDER_Y+(y+1)*BLOCK_SIZE);
// }
// }
}
void drawNext(HDC hdc)
{
int i,j;
HBRUSH hBrush = (HBRUSH)CreateSolidBrush(RGB(0,188,0));
SelectObject(hdc,hBrush);
for (i=0;i<4;i++)
{
for (j=0;j<4;j++)
{
if(bNextCurTeris[i][j])
{
Rectangle(hdc,rc_right_top.left+BLOCK_SIZE*(j+1),rc_right_top.top+BLOCK_SIZE*(i+1),rc_right_top.left+BLOCK_SIZE*(j+2),rc_right_top.top+BLOCK_SIZE*(i+2));
}
}
}
HFONT hFont = CreateFont(30,0,0,0,FW_THIN,0,0,0,UNICODE,0,0,0,0,L"微软雅黑");
SelectObject(hdc,hFont);
SetBkMode(hdc,TRANSPARENT);
SetBkColor(hdc,RGB(255,255,0));
RECT rect;
rect.left = rc_right_top.left+40;
rect.top = rc_right_top.bottom -150;
rect.right = rc_right_top.right;
rect.bottom = rc_right_top.bottom;
DrawTextW(hdc,TEXT("下一个"),_tcslen(TEXT("下一个")),&rect,0);
DeleteObject(hFont);
DeleteObject(hBrush);
}
void drawScore(HDC hdc)
{
HFONT hFont = CreateFont(30,0,0,0,FW_THIN,0,0,0,UNICODE,0,0,0,0,L"微软雅黑");
SelectObject(hdc,hFont);
SetBkMode(hdc,TRANSPARENT);
SetBkColor(hdc,RGB(255,255,0));
RECT rect;
rect.left = rc_right_bottom.left;
rect.top = rc_right_bottom.top;
rect.right = rc_right_bottom.right;
rect.bottom = rc_right_bottom.bottom;
TCHAR szBuf[30];
LPCTSTR cstr = TEXT("当前难度:%d");
wsprintf(szBuf,cstr,GAME_DIFF);
DrawTextW(hdc,szBuf,_tcslen(szBuf),&rect,DT_CENTER | DT_VCENTER);
RECT rect2;
rect2.left = rc_right_bottom.left;
rect2.top = rc_right_bottom.bottom/2+100;
rect2.right = rc_right_bottom.right;
rect2.bottom = rc_right_bottom.bottom;
TCHAR szBuf2[30];
LPCTSTR cstr2 = TEXT("得分:%d");
wsprintf(szBuf2,cstr2,GAME_SCORE);
//outPutBoxInt(sizeof(szBuf));
DrawTextW(hdc,szBuf2,_tcslen(szBuf2),&rect2,DT_CENTER | DT_VCENTER);
DeleteObject(hFont);
}
int selectDiffculty(HWND hWnd,int diff)
{
TCHAR szBuf2[30];
LPCTSTR cstr2 = TEXT("确认选择难度 %d 吗?");
wsprintf(szBuf2,cstr2,diff);
if (MessageBox(hWnd,szBuf2,L"难度选择",MB_YESNO)==IDYES)
{
GAME_DIFF = diff;
InvalidateRect(hWnd,&rc_right_bottom,false);
GAME_STATE |=2;
init_game();
return GAME_DIFF;
}
return -1;
}
int selectLayOut(HWND hWnd,int layout)
{
NUM_X = 10*layout;
NUM_Y = 20*layout;
BLOCK_SIZE = 30/layout;
GAME_STATE|=2;
InvalidateRect(hWnd,&rc_right_bottom,false);
init_game();
return layout;
}
void drawCompleteParticle(int line)
{
HWND hWnd = GetActiveWindow();
HDC hdc = GetDC(hWnd);
HBRUSH hBrush = (HBRUSH)GetStockObject(GRAY_BRUSH);
HPEN hPen = (HPEN)CreatePen(PS_DOT,1,RGB(255,255,0));
SelectObject(hdc,hBrush);
SelectObject(hdc,hPen);
Rectangle(hdc,BORDER_X,
BORDER_Y+line*BLOCK_SIZE,
BORDER_X+NUM_X*BLOCK_SIZE,
BORDER_Y+BLOCK_SIZE*(1+line));
DeleteObject(hBrush);
DeleteObject(hPen);
}
于2016-5-29