C++ Win32API 贪吃蛇游戏
程序代码:
#include <windows.h>
#include <list>
#include <ctime>// 定义游戏区域大小
const int width = 20;
const int height = 20;// 定义贪吃蛇的方向
enum Direction { UP, DOWN, LEFT, RIGHT };// 定义贪吃蛇的节点
struct SnakeNode {int x, y;
};// 全局变量
HINSTANCE hInst;
HWND hWnd;
bool gameOver;
std::list<SnakeNode> snake;
SnakeNode food;
Direction dir;
int score = 0;// 函数声明
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void SetupGame();
void DrawGame(HDC);
void UpdateGame();
void GenerateFood();int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {hInst = hInstance;WNDCLASSEX wcex;MSG msg;// 注册窗口类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(NULL, IDI_APPLICATION);wcex.hCursor = LoadCursor(NULL, IDC_ARROW);wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);wcex.lpszMenuName = NULL;wcex.lpszClassName = TEXT("SnakeGame");wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);RegisterClassEx(&wcex);// 创建窗口hWnd = CreateWindow(TEXT("SnakeGame"), TEXT("贪吃蛇游戏"), WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, 0, 800, 600, NULL, NULL, hInstance, NULL);ShowWindow(hWnd, nCmdShow);UpdateWindow(hWnd);// 初始化游戏SetupGame();// 消息循环while (GetMessage(&msg, NULL, 0, 0)) {TranslateMessage(&msg);DispatchMessage(&msg);}return (int)msg.wParam;
}LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {PAINTSTRUCT ps;HDC hdc;switch (message) {case WM_PAINT:hdc = BeginPaint(hWnd, &ps);DrawGame(hdc);EndPaint(hWnd, &ps);break;case WM_KEYDOWN:switch (wParam) {case VK_UP:dir = UP;break;case VK_DOWN:dir = DOWN;break;case VK_LEFT:dir = LEFT;break;case VK_RIGHT:dir = RIGHT;break;}break;case WM_TIMER:UpdateGame();break;case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hWnd, message, wParam, lParam);}return 0;
}void SetupGame() {gameOver = false;dir = RIGHT;snake.clear();snake.push_back({ width / 2, height / 2 });GenerateFood();SetTimer(hWnd, 1, 100, NULL); // 设置定时器,每100毫秒更新一次
}void DrawGame(HDC hdc) {RECT rect;GetClientRect(hWnd, &rect);FillRect(hdc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));// 绘制食物HBRUSH hFoodBrush = CreateSolidBrush(RGB(255, 0, 0)); // 红色HBRUSH hOldBrush = (HBRUSH)SelectObject(hdc, hFoodBrush);Rectangle(hdc, food.x * 20, food.y * 20, (food.x + 1) * 20, (food.y + 1) * 20);SelectObject(hdc, hOldBrush);DeleteObject(hFoodBrush);// 绘制贪吃蛇HBRUSH hSnakeBrush = CreateSolidBrush(RGB(0, 0, 255)); // 蓝色hOldBrush = (HBRUSH)SelectObject(hdc, hSnakeBrush);for (auto& node : snake) {Rectangle(hdc, node.x * 20, node.y * 20, (node.x + 1) * 20, (node.y + 1) * 20);}SelectObject(hdc, hOldBrush);DeleteObject(hSnakeBrush);
}void UpdateGame() {if (gameOver) return;// 更新贪吃蛇的位置SnakeNode head = snake.front();switch (dir) {case UP: head.y--; break;case DOWN: head.y++; break;case LEFT: head.x--; break;case RIGHT: head.x++; break;}// 检查是否吃到食物if (head.x == food.x && head.y == food.y) {snake.push_front(head);GenerateFood();}else {snake.pop_back();snake.push_front(head);}// 重绘窗口InvalidateRect(hWnd, NULL, TRUE);
}void GenerateFood() {srand(time(NULL));food.x = rand() % width;food.y = rand() % height;
}
运行结果: