俄羅斯方塊程式碼(自寫)
阿新 • • 發佈:2019-02-19
所用編譯器: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; }