1 Star 0 Fork 1

pete王/贪吃蛇

forked from 小明/贪吃蛇 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贪吃蛇.c 9.05 KB
一键复制 编辑 原始数据 按行查看 历史
小明 提交于 2022-12-09 10:01 . 添加代码
// #define UNICODE
/*
开启 #define UNICODE 后,用 GCC 编译需要使用 -finput-charset=GBK
例子:
gcc 贪吃蛇.c -finput-charset=GBK -mwindows -m32 -s -o 贪吃蛇.exe
*/
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define STRING_TITLE "贪吃蛇 1.0"
#define STRING_ERROR_TITLE "警告:"
#define STRING_ERROR_REGISTER "窗口注册失败!"
#define STRING_ERROR_CREATE "窗口创建失败!"
#define STRING_POINTS "积分: "
#define STRING_GAMEOVER "游戏结束"
#define STRING_CLASSNAME "WindowClass"
#define MAP_WIDTH 21
#define MAP_HEIGHT 21
#define QUEUE_LENGTH (MAP_WIDTH * MAP_HEIGHT + 1)
typedef HBRUSH (WINAPI *FunCreateSolidBrush)(COLORREF);
typedef HGDIOBJ (WINAPI *FunGetStockObject)(int);
typedef HGDIOBJ (WINAPI *FunSelectObject)(HDC, HGDIOBJ);
typedef COLORREF (WINAPI *FunSetTextColor)(HDC, COLORREF);
typedef BOOL (WINAPI *FunRectangle)(HDC, int, int, int, int);
typedef BOOL (WINAPI *FunDeleteObject)(HGDIOBJ);
typedef HWND (WINAPI *FunGetConsoleWindow)();
FunCreateSolidBrush funCreateSolidBrush;
FunGetStockObject funGetStockObject;
FunSelectObject funSelectObject;
FunSetTextColor funSetTextColor;
FunRectangle funRectangle;
FunDeleteObject funDeleteObject;
FunGetConsoleWindow funGetConsoleWindow;
enum {
DIRECTION_TOP = 1,
DIRECTION_BOTTOM = 2,
DIRECTION_LEFT = 3,
DIRECTION_RIGHT = 4
};
enum {
TYPE_BACKGROUND = 0,
TYPE_BODY = 1,
TYPE_FOOD = 2
};
int gMap[MAP_HEIGHT][MAP_WIDTH];
int gDirection, gCollision;
int gPoints;
struct Coordinate {
int top;
int left;
};
struct Coordinate gGroup[MAP_WIDTH * MAP_HEIGHT];
int gHead, gTail;
struct Coordinate gQueue[QUEUE_LENGTH];
void EnterQueue(int top, int left)
{
if (gTail == QUEUE_LENGTH)
{
gTail = 0;
}
gMap[top][left] = 1;
gQueue[gTail].top = top;
gQueue[gTail++].left = left;
}
void ExitQueue()
{
struct Coordinate element;
if (gHead == QUEUE_LENGTH)
{
gHead = 0;
}
element = gQueue[gHead++];
gMap[element.top][element.left] = 0;
}
void RefreshImage(HDC hdc)
{
TCHAR text[MAX_PATH];
int top, left;
HBRUSH hBackground = funCreateSolidBrush(RGB(232, 255, 255));
HBRUSH hBody = funCreateSolidBrush(RGB(130, 219, 255));
HBRUSH hFood = funCreateSolidBrush(RGB(30, 198, 0));
RECT rect;
rect.left = 10;
rect.top = 9;
rect.right = rect.left + 150;
rect.bottom = rect.top + 20;
funSelectObject(hdc, funGetStockObject(NULL_PEN));
funSelectObject(hdc, funGetStockObject(DEFAULT_GUI_FONT));
funSetTextColor(hdc, RGB(52, 102, 182));
wsprintf(text, TEXT(STRING_POINTS)TEXT("%d"), gPoints);
DrawText(hdc, text, -1, &rect, DT_LEFT | DT_EDITCONTROL | DT_WORDBREAK);
if (gCollision == TRUE)
{
rect.left = 195;
rect.right = rect.left + 100;
funSetTextColor(hdc, RGB(255, 0, 0));
DrawText(hdc, TEXT(STRING_GAMEOVER), -1, &rect, DT_LEFT | DT_EDITCONTROL | DT_WORDBREAK);
}
for (top = 0; top < MAP_HEIGHT; top++)
{
for (left = 0; left < MAP_WIDTH; left++)
{
switch (gMap[top][left])
{
case TYPE_BACKGROUND:
funSelectObject(hdc, hBackground);
break;
case TYPE_BODY:
funSelectObject(hdc, hBody);
break;
case TYPE_FOOD:
funSelectObject(hdc, hFood);
break;
}
funRectangle(hdc, 10 + left * 20, 30 + top * 20, 10 + left * 20 + 20, 30 + top * 20 + 20);
}
}
funDeleteObject(hBackground);
funDeleteObject(hBody);
funDeleteObject(hFood);
}
void AddFood()
{
int top, left;
int index, length = 0;
for (top = 0; top < MAP_HEIGHT; top++)
{
for (left = 0; left < MAP_WIDTH; left++)
{
if (gMap[top][left] == TYPE_BACKGROUND)
{
gGroup[length].top = top;
gGroup[length++].left = left;
}
}
}
if (length == 0)
{
gCollision = TRUE;
}
else
{
srand(time(NULL));
index = rand() % length;
top = gGroup[index].top;
left = gGroup[index].left;
gMap[top][left] = TYPE_FOOD;
}
}
DWORD WINAPI DrawThread(LPVOID lpParamter)
{
HWND hwnd = (HWND)lpParamter;
int top = 0, left = 0, type;
HDC hdc = GetDC(hwnd);
EnterQueue(top, left);
AddFood();
gDirection = DIRECTION_RIGHT;
while (gCollision == FALSE)
{
switch (gDirection)
{
case DIRECTION_TOP:
top--;
break;
case DIRECTION_BOTTOM:
top++;
break;
case DIRECTION_LEFT:
left--;
break;
case DIRECTION_RIGHT:
left++;
break;
}
type = gMap[top][left];
if (left < 0 || left > (MAP_WIDTH - 1) || top < 0 || top > (MAP_HEIGHT - 1) || type == TYPE_BODY)
{
gCollision = TRUE;
}
else
{
if (type == TYPE_FOOD)
{
EnterQueue(top, left);
gPoints = gPoints + 5;
AddFood();
}
else
{
EnterQueue(top, left);
ExitQueue();
}
}
RefreshImage(hdc);
Sleep(100);
}
ReleaseDC(hwnd, hdc);
return 0;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
switch (Message)
{
case WM_CREATE:
CreateThread(NULL, 0, DrawThread, hwnd, 0, NULL);
break;
case WM_SIZE:
case WM_PAINT:
BeginPaint(hwnd, &ps);
RefreshImage(ps.hdc);
EndPaint(hwnd, &ps);
break;
case WM_KEYDOWN:
if (gDirection != DIRECTION_BOTTOM && (wParam == 87 || wParam == 38)) // 按 W 或 ↑ 上
{
gDirection = DIRECTION_TOP;
}
else if (gDirection != DIRECTION_TOP && (wParam == 83 || wParam == 40)) // 按 S 或 ↓ 下
{
gDirection = DIRECTION_BOTTOM;
}
else if (gDirection != DIRECTION_RIGHT && (wParam == 65 || wParam == 37)) // 按 A 或 ← 左
{
gDirection = DIRECTION_LEFT;
}
else if (gDirection != DIRECTION_LEFT && (wParam == 68 || wParam == 39)) // 按 D 或 → 右
{
gDirection = DIRECTION_RIGHT;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, Message, wParam, lParam);
}
return 0;
}
void InitializeFunction()
{
HMODULE hModule = LoadLibrary(TEXT("gdi32.dll"));
funCreateSolidBrush = (FunCreateSolidBrush) GetProcAddress(hModule, "CreateSolidBrush");
funGetStockObject = (FunGetStockObject) GetProcAddress(hModule, "GetStockObject");
funSelectObject = (FunSelectObject) GetProcAddress(hModule, "SelectObject");
funSetTextColor = (FunSetTextColor) GetProcAddress(hModule, "SetTextColor");
funRectangle = (FunRectangle) GetProcAddress(hModule, "Rectangle");
funDeleteObject = (FunDeleteObject) GetProcAddress(hModule, "DeleteObject");
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG msg;
memset(&wc, 0, sizeof(wc));
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszClassName = TEXT(STRING_CLASSNAME);
if (!RegisterClassEx(&wc))
{
MessageBox(NULL, TEXT(STRING_ERROR_REGISTER), TEXT(STRING_ERROR_TITLE), MB_ICONEXCLAMATION | MB_OK);
return 0;
}
InitializeFunction();
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT(STRING_CLASSNAME), TEXT(STRING_TITLE),
WS_VISIBLE | WS_MINIMIZEBOX | WS_SYSMENU,
CW_USEDEFAULT, CW_USEDEFAULT, 450, 490, NULL, NULL, hInstance, NULL);
if (hwnd == NULL)
{
MessageBox(NULL, TEXT(STRING_ERROR_CREATE), TEXT(STRING_ERROR_TITLE), MB_ICONEXCLAMATION | MB_OK);
return 0;
}
while (GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
int main()
{
HMODULE hModule = LoadLibrary(TEXT("kernel32.dll"));
funGetConsoleWindow = (FunGetConsoleWindow)GetProcAddress(hModule, "GetConsoleWindow");
ShowWindow(funGetConsoleWindow(), FALSE);
return WinMain(GetModuleHandle(NULL), 0, 0, 0);
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C
1
https://gitee.com/wang9907/snake.git
git@gitee.com:wang9907/snake.git
wang9907
snake
贪吃蛇
master

搜索帮助