Win32俄羅斯方塊
elsHead.h
#pragma once
#ifndef DEF_ELS_HEAD
#define DEF_ELS_HEAD
#define DEF_TIMER1 1234
#define WIDTH 700
#define HEIGHT 655
#include <time.h>
#include <windows.h>
void onPaint(HDC hdc);
void onCreat();
// 顯示方塊
void paintSqare(HDC hdc);
// 產生隨機塊
int createRandSqare();
// 隨機塊貼近背景
void copySqareToBack();
// 按鍵
void onReturn(HWND hwnd);
void onTimer(HWND hwnd);
void onUp(HWND hwnd);
void onLeft(HWND hwnd);
void onRight(HWND hwnd);
// 方塊移動
void sqareDown();
void sqareLeft();
void sqareRight();
// 方塊停在最底下
int canSqareDown();
// 把1變成2
void change();
// 方塊停止下落
int sqareStop();
// 方塊左右移動
int canSqareRight();
int canSqareLeft();
// 方塊停止左右移動
int sqareLeftStop();
int sqareRightStop();
// 消除完整行
void destroyOneLine();
// 方塊變形
void sqareChange();
#endif
elsHead.cpp
#include "elsHead.h"
// 背景陣列
char g_arrBackGround[20][16] = { 0 };
char g_arrSqare[2][4] = { 0 };
char g_;
int g_row = 0;
int g_list = 0;
int g_sqareID;
void onPaint(HDC hdc) {
// 相容性DC
HDC comdc = CreateCompatibleDC(hdc);
// 建立一張紙
HBITMAP hBitmap = CreateCompatibleBitmap(hdc, WIDTH, HEIGHT);
// 關聯起來
SelectObject(comdc, hBitmap);
paintSqare(comdc);
// 傳遞
BitBlt(hdc, // 目標DC
5, // 起始x
5, // 起始y
480, // 目標區域x
600, // 目標區域y
comdc, // 源DC
0, 0, SRCCOPY);
// 釋放DC
DeleteObject(hBitmap);
DeleteDC(comdc);
}
void onCreat()
{
srand((unsigned int)time(NULL));
createRandSqare();
copySqareToBack();
}
// 顯示方塊
void paintSqare(HDC comdc)
{
int i = 0;
int j = 0;
// 遍歷
for (i = 0;i < 20;i++)
{
for (j = 0;j < 16;j++)
{
// 如果是1或2 畫出方塊
if(g_arrBackGround[i][j] == 1 || g_arrBackGround[i][j] == 2)
Rectangle(comdc, 30 * j , 30 * i, 30 + 30 * j, 30 + 30 * i);
}
}
}
// 產生隨機塊
int createRandSqare()
{
int n;
n = rand() % 7 + 1;
g_sqareID = n;
// 方塊型別
switch (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] = 1;g_arrSqare[1][1] = 1;g_arrSqare[1][2] = 0;g_arrSqare[1][3] = 0;
break;
// 一條的
case 2:
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_row = 0;
g_list = 6;
break;
// 上面兩個下面兩個,上邊靠左
case 3:
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_row = 0;
g_list = 6;
break;
// 上面倒著的
case 4:
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_row = 0;
g_list = 6;
break;
// 七型,右邊高
case 5:
g_arrSqare[0][0] = 0;g_arrSqare[0][1] = 0;g_arrSqare[0][2] = 1;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_row = 0;
g_list = 6;
break;
// 七型,左邊高
case 6:
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_row = 0;
g_list = 6;
break;
// 山形
case 7:
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_row = 0;
g_list = 6;
break;
}
return 0;
}
// 隨機塊貼近背景
void copySqareToBack()
{
int i, j;
i = 0;
j = 0;
for ( i = 0; i < 2; i++)
{
for (j = 0; j < 4; j++)
{
g_arrBackGround[i][j + 6] = g_arrSqare[i][j];
}
}
}
// 按鍵訊息
void onReturn(HWND hwnd)
{
// 開啟定時器
SetTimer(hwnd, DEF_TIMER1, 1000, NULL);
}
void onRight(HWND hwnd)
{
// 滿足條件右移
if (canSqareRight() == 1 && sqareRightStop() == 1 )
{
// 獲取當前視窗的控制程式碼,記得釋放
HDC hdc = GetDC(hwnd);
sqareRight();
g_list++;
// 顯示方塊,並且相容性DC
onPaint(hdc);
// 釋放
ReleaseDC(hwnd, hdc);
}
}
void onLeft(HWND hwnd)
{
// 滿足條件左移
if (canSqareLeft() == 1 && sqareLeftStop() == 1)
{
// 獲取當前視窗的控制程式碼,記得釋放
HDC hdc = GetDC(hwnd);
sqareLeft();
g_list--;
// 顯示方塊,並且相容性DC
onPaint(hdc);
// 釋放
ReleaseDC(hwnd, hdc);
}
}
void onDown(HWND hwnd)
{
onTimer(hwnd);
}
void onUp(HWND hwnd)
{
HDC hdc = GetDC(hwnd);
if (g_sqareID >= 2 && g_sqareID <= 7)
{
sqareChange();
}
onPaint(hdc);
ReleaseDC(hwnd, hdc);
}
// 定時器響應函式
void onTimer(HWND hwnd)
{
// 獲取當前視窗的控制程式碼,記得釋放
HDC hdc = GetDC(hwnd);
if (canSqareDown() == 1 && sqareStop() == 1)
{
sqareDown();
g_row++;
}
else
{
// 把底層的 1 變成 2,這樣可以繼續判斷
change();
// 消除
destroyOneLine();
// 新的產生隨機塊
createRandSqare();
// 複製到新的背景上
copySqareToBack();
}
// 顯示方塊,並且相容性DC
onPaint(hdc);
// 釋放
ReleaseDC(hwnd, hdc);
}
// 方塊移動
void sqareDown()
{
int i, j;
for (i = 19;i >= 0;i--)
{
for (j = 0;j < 16;j++)
{
if (g_arrBackGround[i][j] == 1)
{
g_arrBackGround[i + 1][j] = 1;
g_arrBackGround[i][j] = 0;
}
}
}
}
void sqareLeft()
{
int i, j;
for (i = 0;i < 20;i++)
{
for (j = 0;j < 16;j++)
{
if (g_arrBackGround[i][j] == 1)
{
g_arrBackGround[i][j-1] = 1;
g_arrBackGround[i][j] = 0;
}
}
}
}
void sqareRight()
{
int i, j;
for (i = 0;i < 20;i++)
{
for (j = 15;j >= 0;j--)
{
if (g_arrBackGround[i][j] == 1)
{
g_arrBackGround[i][j + 1] = 1;
g_arrBackGround[i][j] = 0;
}
}
}
}
// 方塊是否到邊界停住
int canSqareDown()
{
int i;
for (i = 0;i < 16;i++)
{
if (g_arrBackGround[19][i] == 1)
{
return 0;
}
}
return 1;
}
int canSqareLeft()
{
int i;
for (i = 0;i < 20;i++)
{
if (g_arrBackGround[i][0] == 1)
return 0;
}
return 1;
}
int canSqareRight()
{
int i;
for (i = 0;i < 20;i++)
{
if (g_arrBackGround[i][15] == 1)
return 0;
}
return 1;
}
// 把1變成2
void change()
{
int i, j;
for (i = 0;i < 20;i++)
{
for (j = 0;j < 16;j++)
{
if (g_arrBackGround[i][j] == 1)
{
g_arrBackGround[i][j] = 2;
}
}
}
}
// 方塊遇到新方塊停止下落
int sqareStop()
{
int i, j;
for (i = 19;i >= 0;i--)
{
for (j = 0;j < 16;j++)
{
if (g_arrBackGround[i][j] == 1)
{
if (g_arrBackGround[i + 1][j] == 2)
{
return 0;
}
}
}
}
return 1;
}
int sqareLeftStop()
{
int i, j;
for (i = 19;i >= 0;i--)
{
for (j = 0;j < 16;j++)
{
if (g_arrBackGround[i][j] == 1)
{
if (g_arrBackGround[i][j - 1] == 2)
{
return 0;
}
}
}
}
return 1;
}
int sqareRightStop()
{
int i, j;
for (i = 0;i < 20;i++)
{
for (j = 15;j >= 0;j--)
{
if (g_arrBackGround[i][j] == 1)
{
if (g_arrBackGround[i][j + 1] == 2)
{
return 0;
}
}
}
}
return 1;
}
// 消除一行
void destroyOneLine()
{
int i,j;
int sum = 0;
int temp = 0;
for (i = 19;i >= 0;i--)
{
for (j = 0;j < 16;j++)
{
sum += g_arrBackGround[i][j];
}
if (sum == 32)
{
for (temp = i - 1;temp>=0;temp--)
for (j = 0;j < 16;j++)
{
g_arrBackGround[temp + 1][j] = g_arrBackGround[temp][j];
}
}
sum = 0;
}
}
void sqareChange()
{
int i, j;
char nArrSqare[3][3] = { 0 };
// 把方塊複製出來
for (i = 0;i < 3;i++)
{
for (j = 0;j < 3;j++)
{
nArrSqare[i][j] = g_arrBackGround[g_row + i][g_list + j];
}
}
// 變形後複製回去
for (i = 0;i < 3;i++)
{
for (j = 0;j < 3;j++)
{
g_arrBackGround[g_row + i][g_list + j] = nArrSqare[2-j][i];
}
}
}
main.c
#include "elsHead.h"
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);
void onPaint(HDC hdc);
/* 主程式*/
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
WNDCLASSEX wc; /* A properties struct of our window */
HWND hwnd; /* A 'HANDLE', hence the H, or a pointer to our window */
MSG msg; /* A temporary location for all messages */
/* zero out the struct and set the stuff we want to modify */
memset(&wc, 0, sizeof(wc));
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = WndProc; /* This is where we will send messages to */
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_HAND); //系統游標
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 2);
wc.lpszClassName = "WindowClass";
wc.hIcon = LoadIcon(NULL, IDI_INFORMATION); /* Load a standard icon */
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); /* use the name "A" to use the project icon */
if (!RegisterClassEx(&wc)) {
MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, "WindowClass", "Tetris", WS_VISIBLE | WS_OVERLAPPEDWINDOW,
60, /* x */
60, /* y */
WIDTH, /* width */
HEIGHT, /* height */
NULL, NULL, hInstance, NULL);
if (hwnd == NULL) {
MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
/*
This is the heart of our program where all input is processed and
sent to WndProc. Note that GetMessage blocks code flow until it receives something, so
this loop will not produce unreasonably high CPU usage */
while (GetMessage(&msg, NULL, 0, 0) > 0) { /* If no error is received...*/
TranslateMessage(&msg); /* Translate key codes to chars if present */
DispatchMessage(&msg); /* Send it to WndProc */
}
return msg.wParam;
}
/* 回撥函式 */
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
switch (Message) {
PAINTSTRUCT p;
HDC hdc;
// 視窗建立初期只產生一次,一般做資料初始化的工作
case WM_CREATE:
//GetLastError();
onCreat();
break;
// 視窗產生變化,必須更新時,由這個訊息通知程式
case WM_PAINT:
/* getDC,視窗可操作區域的標識 */
hdc = BeginPaint(hwnd, &p);
onPaint(hdc);
/* 關閉DC */
EndPaint(hwnd, &p);
//GetLastError();
break;
// 鍵盤資訊
case WM_KEYDOWN:
switch (wParam)
{
case VK_RETURN:
onReturn(hwnd);
break;
case VK_RIGHT:
onRight(hwnd);
break;
case VK_LEFT:
onLeft(hwnd);
break;
case VK_UP:
onUp(hwnd);
break;
case VK_DOWN:
onDown(hwnd);
break;
}
// 定時器訊息
case WM_TIMER:
onTimer(hwnd);
break;
case WM_DESTROY: {
PostQuitMessage(0);
break;
}
/* All other messages (a lot of them) are processed using default procedures */
default:
return DefWindowProc(hwnd, Message, wParam, lParam);
}
return 0;
}
相關文章
- 俄羅斯方塊練習
- canvas實現俄羅斯方塊Canvas
- 俄羅斯方塊(JS+CSS)JSCSS
- Tetris 俄羅斯方塊遊戲遊戲
- 【Java遊戲】java俄羅斯方塊!Java遊戲
- Flutter Web 實戰 - 俄羅斯方塊FlutterWeb
- 使用JavaScript實現一個俄羅斯方塊JavaScript
- 最新《 java實戰開發俄羅斯方塊教程》Java
- Python 實戰開發俄羅斯方塊遊戲Python遊戲
- 基於Flutter的俄羅斯方塊小遊戲Flutter遊戲
- 如何讓 Emacs 俄羅斯方塊變得更難Mac
- wxpython入門第十一步(俄羅斯方塊)Python
- 基於MonoGame重製《俄羅斯方塊》遊戲MonoGAM遊戲
- c#實現簡單的俄羅斯方塊C#
- 俄羅斯方塊聯機小遊戲的實現遊戲
- 如何讓AI教機器自己玩俄羅斯方塊?AI
- 用React、Redux、Immutable做俄羅斯方塊 | 掘金技術徵文ReactRedux
- 從俄羅斯方塊,邁向強化學習大門強化學習
- 俄羅斯方塊歷史發展與變革創新
- 初學者——Java之實現簡易俄羅斯方塊Java
- 使用C#和MonoGame開發俄羅斯方塊遊戲C#MonoGAM遊戲
- Python:遊戲:300行程式碼實現俄羅斯方塊Python遊戲行程
- 函數語言程式設計嘗試之俄羅斯方塊函數程式設計
- “漢字俄羅斯方塊”《一字不落》今日上架Steam
- 為了上班摸魚我用Python製作了俄羅斯方塊?Python
- python開發俄羅斯方塊小遊戲程式碼例項Python遊戲
- [分享]純python3手寫Tetris(俄羅斯方塊)遊戲Python遊戲
- 300行Python程式碼實現俄羅斯方塊,致敬逝去的童年Python
- 用 SQL 寫的俄羅斯方塊遊戲「GitHub 熱點速覽」SQL遊戲Github
- pyqt5製作俄羅斯方塊小遊戲-----原始碼解析QT遊戲原始碼
- 俄羅斯玩偶
- 俄羅斯:‘區塊鏈屬於我們’區塊鏈
- 回顧「俄羅斯方塊」曾經的一段蒸汽波時代
- 《俄羅斯方塊》系列 35 週年 一窺遊戲歷年玩法演變遊戲
- 超越《俄羅斯方塊》後,《我的世界》想打造一個更具野心的世界
- Python3+pygame實現的俄羅斯方塊 程式碼完整 有演示效果PythonGAM
- 【補檔STM32】STM32F103俄羅斯方塊遊戲實現遊戲
- 俄羅斯方塊+塔防 國產獨立遊戲《方境戰記》5月25日發售遊戲
- 恰逢35歲生日 俄羅斯方塊的一切都變得井井有條