先打開VS,創建解決方案
選擇windows應用程序
在源文件文件夾下新建tetris.cpp文件,用來寫我們實現俄羅斯方塊的代碼
代碼及其註釋如下所示:
/*
創建窗口
win32窗口的創建過程主要有6部分
1.頭文件與主函數、2.創建窗口結構體、3.註冊窗口、4.創建窗口、5.顯示窗口、6.消息循環、7.回調函數
頭文件:windows.h
主函數:int WINAPI WinMain( HINSTANCE hlnstance, //句柄:一個數,窗口唯一標識
HINSTANCE hPrevlnstance, //前一個句柄
LPTSTR lpCmdLine,//傳遞給應用程序的命令行參數
int nCmdShow)//指定窗口的顯示方式 隱藏 最大最小顯示
返回值:int
WINAPI:調用約定, 主要是參數的入棧順序,這個棧空間的清理者,__stdcall,APIENTRY,本質都是一樣的
WinMain:主函數的寫法,注意不是main
*/
#include<time.h>
#include<stdlib.h>
#include<windows.h>
//定時器ID
#define DEF_TIMER1 1234
//創建兼容性DC
void OnPaint(HDC hDc);
//顯示方塊
void PaintSpare(HDC hMemDC);
//隨機小方塊
int CreateRandmSqare();
//隨機小方塊貼進背景
void CopySqareToBack();
//初始化
void OnCreate();
//回車鍵函數
void OnReturn(HWND hWnd);
//方塊下落
void SqareDwon();
//定時器相應函數
void OnTimer(HWND hWnd);
//方塊停在最底下 0 不可以下落 1可以下落
int CanSgareDown();
//下落
int CanSgareDown2();
//將1變成2
void Change1To2();
//顯示2
void ShowSqare2(HDC hMemDC);
//左鍵
void OnLeft(HWND hWnd);
//左移
void SqareLeft();
//方塊在最左面 0 不可以左移 1可以左移
int CanSgareLeft();
//左移限制
int CanSgareLeft2();
//右鍵
void OnRight(HWND hWnd);
//右移
void SqareRight();
//方塊在最右面 0 不可以右移 1可以右移
int CanSgareRight();
//右移限制
int CanSgareRight2();
//加速向下
void OnDown(HWND hWnd);
//變形 上鍵
void OnUp(HWND hWnd);
//3 * 3變形
void ChangeSqare();
//3 * 3變形限制
int CanSqareChangeSape();
//長條變形
void ChangeLineSqare();
//長條變形限制
int CanLineSqareChange();
//消除已滿的行數
void DestroyOneLineSqare();
//顯示分數
void ShowScore(HDC hMemDC);
//遊戲結束
int CanGomeOver();
//7.回調函數
// 回調函數 一個窗口對應一個窗口句柄
//long類型 調用約定 函數名字(窗口句柄,無符號整形消息的ID, 參數 3無符號整形 4long 傳遞信息自己定可以)
LRESULT CALLBACK PELouSi(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParan)
{
PAINTSTRUCT pt;
HDC hDC;//可以畫的範圍 也就是用戶窗口可操作的範圍(標識)
switch (nMsg)
{
case WM_CREATE://窗口消息處理程序接收的第一個消息-也是回掉函數的第一個消息-是WM_CREATE 這個消息只產生一次,一般用於初始化一些數據
OnCreate();
break;
//回掉函數的第二個消息
//當窗口顯示區域的一部分顯示內容或者全部變爲“無效”,以至於必須“更新畫面”時,將由這個消息通知程序
//窗口結構體的最後那個成員CS_HREDRAW | CS_VREDRAW,目的就是窗口大小發生變化的時候,產生WM_PAINT消息
//窗口重疊時,重疊部分漸漸出現時
case WM_TIMER://定時器消息
OnTimer(hWnd);
break;
case WM_PAINT:
hDC = BeginPaint(hWnd, &pt);//畫窗口內容開始 有用getDC的
OnPaint(hDC);//畫圖的函數
EndPaint(hWnd, &pt);//畫窗口內容結束
break;
case WM_KEYDOWN://WM_KEYDOWN鍵盤安下
switch (wParam)//wParam回掉函數第三個參數 區分是按得那個鍵
{
case VK_RETURN://回車鍵
OnReturn(hWnd);//開始
break;
case VK_LEFT://左鍵
OnLeft(hWnd);//左移
break;
case VK_RIGHT://右鍵
OnRight(hWnd);//右移
break;
case VK_UP://上鍵
OnUp(hWnd);//變形
break;
case VK_DOWN://下鍵
OnDown(hWnd);//加速
break;
}
break;
case WM_DESTROY://點×三種消息依次產生: WM_CLOSE -> WM_DESTROY銷燬窗口 -> WM_QUIT退出消息 W:windows M:消息
KillTimer(hWnd, DEF_TIMER1);
PostQuitMessage(0);//傳遞退出消息
break;
}
return DefWindowProc(hWnd, nMsg, wParam, lParan);//功能 沒有處理的消息系統自動處理 保證系統的連貫性 什麼都不做 每次在窗口有點擊、輸入都會有消息
}
//1.頭文件與主函數
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
//2.創建窗口結構體
//初始化窗口類
WNDCLASSEX wc;
HWND hWnd;
MSG mSg; //MSG 消息的結構體
//12個成員不能多不能少 要不 失敗
wc.cbClsExtra = 0;//緊跟在窗口類尾部的一塊額外的空間,不用設爲0。
wc.cbSize = sizeof(WNDCLASSEX);//類的大小
wc.cbWndExtra = 0;//拓展窗口對話框
wc.hbrBackground = (HBRUSH)COLOR_SCROLLBAR;//背景顏色COLOR_BACKGROUND
wc.hCursor = NULL;//光標樣式 LoadCursor(句柄系統定義填NULL 加載自定義填hInstance,樣式 自定義添加資源文件)
wc.hIcon = NULL;//任務欄顯示的圖標 LoadIcon(句柄系統定義填NULL 加載自定義填hInstance,樣式 自定義添加資源文件)
wc.hIconSm = NULL;//窗口左上角的圖標 如果爲空則默認爲任務欄的圖標
wc.hInstance = hInstance;//當前窗口的句柄 //句柄又系統傳遞
wc.lpfnWndProc = PELouSi;//回掉函數函數地址
wc.lpszClassName = L"elsfk";//窗口類的名字 名字不要重複 給系統看的 不是最上面那個名字
wc.lpszMenuName = NULL; //菜單
wc.style = CS_HREDRAW | CS_VREDRAW;///窗口顯示風格 垂直刷新 水平刷新 最大化等
//3.註冊窗口對象
if (0 == RegisterClassEx(&wc))//如果註冊失敗
{
//出錯 不知道什麼原因
int a = GetLastError();//用這個函數 返回一個值
return 0;
}
//4.創建窗口
hWnd = CreateWindowEx(WS_EX_TOPMOST, L"elsfk", L"俄羅斯方塊", WS_OVERLAPPEDWINDOW, 100, 100, 500, 646, NULL, NULL, hInstance, NULL);
//(附加屬性 (WS_EX_TOPMOST總是在最前端),
//窗口類的名字 名字不要重複 給系統看的 不是最上面那個名字 與上面的一樣,
//窗口的名字 左上角的 人你看的... ,
//指定窗口的風格,
//int x;相對於桌面 座標 是像素 左,
//int y;相對於桌面 座標 是像素 上,
//寬度,
//高度,
//子句柄 子窗口,
//菜單的句柄 沒有菜單NULL,
//當前實例句柄,
//(win下lp是指針類型)指向一個值得指針,多文檔 多個編輯框);
if (NULL == hWnd) //窗口句柄 窗口的唯一標識
{
return 0;
}
//5.顯示窗口
ShowWindow(hWnd, SW_SHOWNORMAL);//句柄,顯示風格(最大化 最小化 默認nCmdShow等)
//隱藏顯示返回0 正常顯示返回非0
//6.消息循環
while (GetMessage(&mSg, NULL, 0, 0))//(指向MSG消息結構體的指針,窗口句柄(NULL與非NULL的區別NULL接收所以窗口消息非NULL接所填句柄的消息,3 4參數處理消息範圍(0, 0是取所以範圍))
//GetMessage取到消息返回非零值
{
//消息翻譯 將輸入設備的電信號轉換成字符消息
TranslateMessage(&mSg);//參是一個指針指向結構體
//分發消息 分類 :標準消息 命令消息 通知消息 自定義消息
DispatchMessage(&mSg);//參是一個指針指向結構體
}
return 0;
}
/*
兼容性DC(就是在後臺畫好當前頁面再給當前)
創建兼容性DC
HDC CreateCompatibleDC(HDC hdc);
創建兼容性位圖
HBITMAP CreateCompatibleBitmap(HDC hdc, int nWidth, int nHeight);
將DC與位圖綁定在一起
HGDIOBJ SelectObject(HDC hdc, HGDIOBJ hgdiobj);
釋放DC
BOOL DeleteDC(HDC hdc);
將內存DC傳遞到窗口DC
BOOL BitBlt(HDC hdcDest, int nXDest, int nYDest, nt nWidth, int nHeight, HDC hdcSrc, int nXSrc, int nYSrc, DWORD dwRop);
(目標DC 窗口DC, 2 3參數 目標的起始位置 注意是基於我們的窗口, 4 5區域的大小, 源DC 也是我們的內存DC, 7 8內存圖片的起始位置, 傳遞的方式)
返回值:失敗返回0,成功返回非0
*/
/*
定時器:
啓動定時器
UINT_PTR SetTimer(HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc);
(窗口句柄hWnd NULL, 定時器ID 不理會, 間隔時間 毫秒 1000ms = 1s, 設置爲NULL 處理函數的地址);
返回值:成功返回非零
關閉定時器
BOOL KillTimer(HWND hWnd, UINT_PTR uIDEvent);
*/
/*
給方塊圖色
HBRUSH oldBrush;
創建一個顏色的畫刷
HBRUSH newBrush = CreateSolidBrush(RGB(67, 132, 19));
綁定當前DC與畫刷,返回系統默認畫刷
oldBrush = SelectObject(hdc, newBrush);
使用完新畫刷,把系統默認畫刷選回來,返回創建的畫刷
newBrush = SelectObject(hdc,oldBrush);
釋放畫刷句柄
DeleteObject(newBrush);
*/
//背景數組(二維數組)
char g_arrBackGroud[20][10] = { 0 };
//小方塊數組
char g_arrSqare[2][4] = { 0 };
//標記小方塊的形狀
int g_nSqareID = -1;
// 記錄位置
int g_nLine = -1;//行
int g_nList = -1;//列
//記分
int g_nScore = 0;
//函數實現
void OnPaint(HDC hDc)
{
//創建兼容性DC(dc編號)可以創建多個
HDC hMemDC = CreateCompatibleDC(hDc);
//位圖(創建一張紙)
HBITMAP hBitmapBack = CreateCompatibleBitmap(hDc, 500, 646);//(,紙的大小)
//關聯起來
SelectObject(hMemDC, hBitmapBack);
//顯示方塊
PaintSpare(hMemDC);
ShowSqare2(hMemDC);
//顯示右面 顯示分數
ShowScore(hMemDC);
//傳遞//源
BitBlt(hDc, 0, 0, 500, 600, hMemDC, 0, 0, SRCCOPY);
//釋放DC
DeleteObject(hBitmapBack);//位圖
DeleteDC(hMemDC);//編號
}
//顯示分數
void ShowScore(HDC hMemDC)
{
char strScore[10] = { 0 };
Rectangle(hMemDC, 300, 0, 500, 646);//右邊顯示
itoa(g_nScore, strScore, 10);//轉換成字符串
TextOut(hMemDC, 340, 100, L"得分:", strlen("得分:"));
TextOut(hMemDC, 400, 100, (LPCWSTR)strScore, strlen(strScore));//(句柄,x,y,一個字符串,字節數 有效的)
TextOut(hMemDC, 340, 180, L"回車開始", strlen("回車開始"));
TextOut(hMemDC, 340, 210, L"上鍵變形", strlen("上鍵變形"));
TextOut(hMemDC, 340, 240, L"下鍵加速", strlen("下鍵加速"));
TextOut(hMemDC, 340, 270, L"左鍵左移", strlen("左鍵左移"));
TextOut(hMemDC, 340, 300, L"右鍵右移", strlen("右鍵右移"));
TextOut(hMemDC, 350, 150, L"按鍵:", strlen("按鍵:"));
}
//初始化
void OnCreate()
{
srand((unsigned)time(NULL));
CreateRandmSqare();
CopySqareToBack();
}
//顯示方塊
void PaintSpare(HDC hMemDC)
{
int i = 0;
int j = 0;//i j 循環遍歷用
//舊的畫刷
HBRUSH hOldBrush;
//畫刷 塗顏色
HBRUSH hNewBrush;
//畫刷 塗顏色背景
hNewBrush = CreateSolidBrush(RGB(255, 255, 128));
//選入當前DC
hOldBrush = (HBRUSH)SelectObject(hMemDC, hNewBrush);
//畫大方塊
Rectangle(hMemDC, 0, 0, 300, 600);//(畫板, 畫窗口起始位置, 畫結束位置 先橫向 後豎向)
hNewBrush = (HBRUSH)SelectObject(hMemDC, hOldBrush);
DeleteObject(hNewBrush);
hNewBrush = CreateSolidBrush(RGB(0, 255, 0));
//選入當前DC
hOldBrush = (HBRUSH)SelectObject(hMemDC, hNewBrush);
//遍歷
for (i = 0; i < 20; i++)//行
{
for (j = 0; j < 10; j++)//列
{
if (1 == g_arrBackGroud[i][j])
{
//畫方塊
Rectangle(hMemDC, j * 30, i * 30, j * 30 + 30, i * 30 + 30);
}
}
}
hNewBrush = (HBRUSH)SelectObject(hMemDC, hOldBrush);
DeleteObject(hNewBrush);
}
//隨機小方塊
int CreateRandmSqare()
{
int n = rand() % 7;
switch (n)//n
{
case 1:
g_arrSqare[0][0] = 1,g_arrSqare[0][1] = 1, g_arrSqare[0][2] = 0, g_arrSqare[0][3] = 0;
g_arrSqare[1][0] = 0, g_arrSqare[1][1] = 1, g_arrSqare[1][2] = 1, g_arrSqare[1][3] = 0;
g_nLine = 0;
g_nList = 3;
break;
case 2:
g_arrSqare[0][0] = 0,g_arrSqare[0][1] = 1, g_arrSqare[0][2] = 1, g_arrSqare[0][3] = 0;
g_arrSqare[1][0] = 1, g_arrSqare[1][1] = 1, g_arrSqare[1][2] = 0, g_arrSqare[1][3] = 0;
g_nLine = 0;
g_nList = 3;
break;
case 3:
g_arrSqare[0][0] = 1,g_arrSqare[0][1] = 1, g_arrSqare[0][2] = 1, g_arrSqare[0][3] = 0;
g_arrSqare[1][0] = 1, g_arrSqare[1][1] = 0, g_arrSqare[1][2] = 0, g_arrSqare[1][3] = 0;
g_nLine = 0;
g_nList = 3;
break;
case 4:
g_arrSqare[0][0] = 1, g_arrSqare[0][1] = 0, g_arrSqare[0][2] = 0, g_arrSqare[0][3] = 0;
g_arrSqare[1][0] = 1, g_arrSqare[1][1] = 1, g_arrSqare[1][2] = 1, g_arrSqare[1][3] = 0;
g_nLine = 0;
g_nList = 3;
break;
case 5:
g_arrSqare[0][0] = 0, g_arrSqare[0][1] = 1, g_arrSqare[0][2] = 1, g_arrSqare[0][3] = 0;
g_arrSqare[1][0] = 0, g_arrSqare[1][1] = 1, g_arrSqare[1][2] = 1, g_arrSqare[1][3] = 0;
break;
case 6:
g_arrSqare[0][0] = 1, g_arrSqare[0][1] = 1, g_arrSqare[0][2] = 1, g_arrSqare[0][3] = 1;
g_arrSqare[1][0] = 0, g_arrSqare[1][1] = 0, g_arrSqare[1][2] = 0, g_arrSqare[1][3] = 0;
g_nLine = 0;
g_nList = 4;
break;
case 0:
g_arrSqare[0][0] = 0, g_arrSqare[0][1] = 1, g_arrSqare[0][2] = 0, g_arrSqare[0][3] = 0;
g_arrSqare[1][0] = 1, g_arrSqare[1][1] = 1, g_arrSqare[1][2] = 1, g_arrSqare[1][3] = 0;
g_nLine = 0;
g_nList = 3;
break;
}
//小方塊的ID
g_nSqareID = n;
return n;
}
//隨機小方塊貼進背景
void CopySqareToBack()
{
int i = 0;
int j = 0;
for (i = 0; i < 2; i++)
{
for (j = 0; j < 4; j++)
{
g_arrBackGroud[i][j + 3] = g_arrSqare[i][j];
}
}
}
//回車鍵函數
void OnReturn(HWND hWnd)
{
//打開定時器
SetTimer(hWnd, DEF_TIMER1, 600, NULL);
}
//方塊下落
void SqareDwon()
{
int i = 0;
int j = 0;
for (i = 19; i >= 0; i--)
{
for (j = 0; j < 10; j++)
{
if (1 == g_arrBackGroud[i][j])
{
g_arrBackGroud[i + 1][j] = g_arrBackGroud[i][j];
g_arrBackGroud[i][j] = 0;
}
}
}
}
//定時器相應函數
void OnTimer(HWND hWnd)
{
//得到DC的函數
HDC hDc = GetDC(hWnd);
//判斷是否能下落
if (1 == CanSgareDown() && 1 == CanSgareDown2())
{
//方塊下落
SqareDwon();
g_nLine++;
}
else
{
//1變成2
Change1To2();
//消除已滿的行數
DestroyOneLineSqare();
//遊戲結束
if (0 == CanGomeOver())
{
//結束
KillTimer(hWnd, DEF_TIMER1);
return ;
}
//產生隨機塊
CreateRandmSqare();
//複製到背景上
CopySqareToBack();
}
//顯示方塊
//PaintSpare(hDc);
OnPaint(hDc);
//釋放DC
ReleaseDC(hWnd, hDc);//內核對象 要程序員釋放
}
//方塊停在最底下 0 不可以下落 1可以下落
int CanSgareDown()
{
for (int i = 0; i < 10; i++)
{
if (1 == g_arrBackGroud[19][i])
{
return 0;
}
}
return 1;
}
//將1變成2
void Change1To2()
{
for (int i = 0; i < 20; i++)
{
for (int j = 0; j < 10; j++)
{
if (1 == g_arrBackGroud[i][j])
{
g_arrBackGroud[i][j] = 2;
}
}
}
}
//顯示2
void ShowSqare2(HDC hMemDC)
{
//舊的畫刷
HBRUSH hOldBrush;
//畫刷 塗顏色
HBRUSH hNewBrush = CreateSolidBrush(RGB(109, 249, 252));
//選入當前DC
hOldBrush = (HBRUSH)SelectObject(hMemDC, hNewBrush);
for (int i = 0; i < 20; i++)
{
for (int j = 0; j < 10; j++)
{
if (2 == g_arrBackGroud[i][j])
{
Rectangle(hMemDC, j * 30, i * 30, j * 30 + 30, i * 30 + 30);
}
}
}
hNewBrush = (HBRUSH)SelectObject(hMemDC, hOldBrush);
DeleteObject(hNewBrush);
}
//下落
int CanSgareDown2()
{
for (int i = 19; i >= 0; i--)
{
for (int j = 0; j < 10; j++)
{
if (1 == g_arrBackGroud[i][j] && 2 == g_arrBackGroud[i + 1][j])
{
return 0;
}
}
}
return 1;
}
//左鍵
void OnLeft(HWND hWnd)
{
//方塊向左移
if (1 == CanSgareLeft() && 1 == CanSgareLeft2())
{
//得到DC的函數
HDC hDc = GetDC(hWnd);
g_nList--;
SqareLeft();
//顯示方塊
OnPaint(hDc);
//釋放DC
ReleaseDC(hWnd, hDc);
}
}
//左移
void SqareLeft()
{
for (int i = 0; i < 20; i++)
{
for (int j = 0; j < 10; j++)
{
if (1 == g_arrBackGroud[i][j])
{
g_arrBackGroud[i][j - 1] = g_arrBackGroud[i][j];
g_arrBackGroud[i][j] = 0;
}
}
}
}
//方塊在最左面 0 不可以左移 1可以左移
int CanSgareLeft()
{
for (int i = 0; i < 20; i++)
{
if (1 == g_arrBackGroud[i][0])
{
return 0;
}
}
return 1;
}
//左移限制
int CanSgareLeft2()
{
for (int i = 0; i < 20; i++)
{
for (int j = 0; j < 10; j++)
{
if (1 == g_arrBackGroud[i][j] && 2 == g_arrBackGroud[i][j - 1])
{
return 0;
}
}
}
return 1;
}
//右鍵
void OnRight(HWND hWnd)
{
//右移
if (1 == CanSgareRight() && 1 == CanSgareRight2())
{
//得到一個DC函數
HDC hDc = GetDC(hWnd);
g_nList++;
SqareRight();
//顯示方塊
OnPaint(hDc);
//釋放DC
ReleaseDC(hWnd, hDc);
}
}
//右移
void SqareRight()
{
for (int i = 0; i < 20; i++)
{
for (int j = 9; j >= 0; j--)
{
if (1 == g_arrBackGroud[i][j])
{
g_arrBackGroud[i][j + 1] = g_arrBackGroud[i][j];
g_arrBackGroud[i][j] = 0;
}
}
}
}
//方塊在最右面 0 不可以右移 1可以右移
int CanSgareRight()
{
for (int i = 0; i < 20; i++)
{
if (1 == g_arrBackGroud[i][19])
{
return 0;
}
}
return 1;
}
//右移限制
int CanSgareRight2()
{
for (int i = 0; i < 20; i++)
{
for (int j = 0; j < 10; j++)
{
if (1 == g_arrBackGroud[i][j] && 2 == g_arrBackGroud[i][j + 1])
{
return 0;
}
}
}
return 1;
}
//加速向下
void OnDown(HWND hWnd)
{
OnTimer(hWnd);
}
//變形 上鍵
void OnUp(HWND hWnd)
{
HDC hDc = GetDC(hWnd);
switch (g_nSqareID)//g_nSqareID
{
case 0:
case 1:
case 2:
case 3:
case 4://普通變形
if (1 == CanSqareChangeSape())//3 * 3變形限制
{
ChangeSqare();//3 * 3變形
}
else
{
return;
}
break;
case 5:// 正方形
return;
break;
case 6://長條形
if (1 == CanLineSqareChange())//長條變形限制
{
ChangeLineSqare();//長條變形
}
break;
}
//顯示
OnPaint(hDc);
}
//3 * 3變形
void ChangeSqare()
{
int nTemp = 2;
//用於交換的小方塊
char arrSqare[3][3] = { 0 };
//小方塊複製出來
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
arrSqare[i][j] = g_arrBackGroud[g_nLine + i][g_nList + j];
}
}
//變形後複製回去
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
g_arrBackGroud[g_nLine + i][g_nList + j] = arrSqare[nTemp][i];
nTemp--;
}
nTemp = 2;
}
}
//3 * 3變形限制
int CanSqareChangeSape()
{
//限制與其他小方塊連在一起變形
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (2 == g_arrBackGroud[g_nLine + i][g_nList + j])
{
return 0;
}
}
}
//限制超出邊境變形
/*if (g_nList < 0 || g_nList + 2 > 9) 第一種不好有些限制不能進行變形
{
return 0;
}*/
if (g_nList < 0)
{
g_nList = 0;
}
else if (g_nList + 2 > 9)
{
g_nList = 7;
}
return 1;
}
//長條變形
void ChangeLineSqare()
{
if (1 == g_arrBackGroud[g_nLine][g_nList - 1])//橫的出現
{
//清零
g_arrBackGroud[g_nLine][g_nList - 1] = 0;
g_arrBackGroud[g_nLine][g_nList + 1] = 0;
g_arrBackGroud[g_nLine][g_nList + 2] = 0;
if (2 == g_arrBackGroud[g_nLine + 1][g_nList])
{
//賦值
g_arrBackGroud[g_nLine - 1][g_nList] = 1;
g_arrBackGroud[g_nLine - 2][g_nList] = 1;
g_arrBackGroud[g_nLine - 3][g_nList] = 1;
}
else if (2 == g_arrBackGroud[g_nLine + 2][g_nList])
{
//賦值
g_arrBackGroud[g_nLine + 1][g_nList] = 1;
g_arrBackGroud[g_nLine - 1][g_nList] = 1;
g_arrBackGroud[g_nLine - 2][g_nList] = 1;
}
else
{
//賦值
g_arrBackGroud[g_nLine - 1][g_nList] = 1;
g_arrBackGroud[g_nLine + 1][g_nList] = 1;
g_arrBackGroud[g_nLine + 2][g_nList] = 1;
}
}
else//豎的出現
{
//清零
g_arrBackGroud[g_nLine - 1][g_nList] = 0;
g_arrBackGroud[g_nLine + 1][g_nList] = 0;
g_arrBackGroud[g_nLine + 2][g_nList] = 0;
if (2 == g_arrBackGroud[g_nLine][g_nList + 1] || 9 == g_nList)
{
//賦值
g_arrBackGroud[g_nLine][g_nList - 1] = 1;
g_arrBackGroud[g_nLine][g_nList - 2] = 1;
g_arrBackGroud[g_nLine][g_nList - 3] = 1;
//標記改變
g_nList = g_nList - 2;
}
else if (2 == g_arrBackGroud[g_nLine][g_nList + 2] || 8 == g_nList)
{
//賦值
g_arrBackGroud[g_nLine][g_nList + 1] = 1;
g_arrBackGroud[g_nLine][g_nList - 1] = 1;
g_arrBackGroud[g_nLine][g_nList - 2] = 1;
//標記改變
g_nList = g_nList - 1;
}
else if (2 == g_arrBackGroud[g_nLine][g_nList - 1] || 0 == g_nList)
{
//賦值
g_arrBackGroud[g_nLine][g_nList + 1] = 1;
g_arrBackGroud[g_nLine][g_nList + 3] = 1;
g_arrBackGroud[g_nLine][g_nList + 2] = 1;
//標記改變
g_nList = g_nList + 1;
}
else
{
//賦值
g_arrBackGroud[g_nLine][g_nList - 1] = 1;
g_arrBackGroud[g_nLine][g_nList + 1] = 1;
g_arrBackGroud[g_nLine][g_nList + 2] = 1;
}
}
}
//長條變形限制
int CanLineSqareChange()
{
int i = 0, j = 0;
for (i = 1; i < 4; i++)
{
if (2 == g_arrBackGroud[g_nLine][g_nList + i] || g_nList + i > 9)
{
break;
}
}
for (j = 1; j < 4; j++)
{
if (2 == g_arrBackGroud[g_nLine][g_nList - j] || g_nList - j < 0)
{
break;
}
}
if ((i - 1 + j - 1) < 3)
{
return 0;
}
return 1;
}
//消除已滿的行數
void DestroyOneLineSqare()
{
int i = 0, j = 0;
int nSum = 0;
int nTempi = 0;
for (i = 19; i >= 0; i--)
{
for (j = 0; j < 10; j++)
{
nSum += g_arrBackGroud[i][j];
}
if (20 == nSum)
{
//消除一行
for (nTempi = i - 1; nTempi >= 10; nTempi--)
{
for (j = 0; j < 10; j++)
{
g_arrBackGroud[nTempi + 1][j] = g_arrBackGroud[nTempi][j];
}
}
//記分用
g_nScore++;
//爲了能消除多行
i = 20;
}
//清零
nSum = 0;
}
}
//遊戲結束
int CanGomeOver()
{
int i = 0;
for (i = 0; i < 10; i++)
{
if (2 == g_arrBackGroud[0][i])
{
//遊戲結束
MessageBox(NULL, L"遊戲結束", L"提示", MB_OK);//消息盒子(句柄 可寫可不寫,字符串指針 內容, 字符串指針, 風格)
return 0;
}
}
return 1;
}
接下來我們來玩一玩這個遊戲
點擊調試
按回車鍵開啓計時器
開始遊戲
一切工作正常
那麼今天的教程就到這裏了