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;
}

运行结果:

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值