Advertisement
alien_fx_fiend

2D Snake Game Win32 (Don't use this!!) Use previous

Jul 26th, 2024
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.89 KB | None | 0 0
  1. This is a C++ Win32 GDI-based Snake game code, I get the following errors when trying to build the project (after the errors I've posted my current full source code for scrutiny):
  2. Severity Code Description Project File Line Suppression State
  3. Error (active) E0513 a value of type "LRESULT (__stdcall Game::*)(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)" cannot be assigned to an entity of type "WNDPROC" Snake-Game-Win32 D:\Download\cpp-projekt\FuzenOp_SiloTest\Snake-Game-Win32\2D-Snake.cpp 281
  4. Error (active) E0067 expected a '}' Snake-Game-Win32 D:\Download\cpp-projekt\FuzenOp_SiloTest\Snake-Game-Win32\2D-Snake.cpp 313
  5. Here is my full source code for scrutiny:
  6. #include <windows.h>
  7. #include <vector>
  8. #include <ctime>
  9. #include <cstdlib>
  10.  
  11. #define WINDOW_WIDTH 800
  12. #define WINDOW_HEIGHT 600
  13. #define GRID_SIZE 20
  14. #define SNAKE_INITIAL_LENGTH 5
  15. #define MOVE_INTERVAL 100
  16.  
  17. enum Direction { UP, DOWN, LEFT, RIGHT };
  18.  
  19. struct Point {
  20.    int x, y;
  21.    Point(int _x = 0, int _y = 0) : x(_x), y(_y) {}
  22. };
  23.  
  24. class Snake {
  25. private:
  26.    std::vector<Point> body;
  27.    Direction currentDirection;
  28.    Direction nextDirection;
  29.    bool growing;
  30.  
  31. public:
  32.    Snake() : currentDirection(RIGHT), nextDirection(RIGHT), growing(false) {
  33.        for (int i = 0; i < SNAKE_INITIAL_LENGTH; ++i) {
  34.            body.push_back(Point(5 - i, 5));
  35.        }
  36.    }
  37.  
  38.    void move() {
  39.        currentDirection = nextDirection;
  40.        Point newHead = body.front();
  41.        switch (currentDirection) {
  42.        case UP: newHead.y--; break;
  43.        case DOWN: newHead.y++; break;
  44.        case LEFT: newHead.x--; break;
  45.        case RIGHT: newHead.x++; break;
  46.        }
  47.  
  48.        newHead.x = (newHead.x + WINDOW_WIDTH / GRID_SIZE) % (WINDOW_WIDTH / GRID_SIZE);
  49.        newHead.y = (newHead.y + WINDOW_HEIGHT / GRID_SIZE) % (WINDOW_HEIGHT / GRID_SIZE);
  50.  
  51.        body.insert(body.begin(), newHead);
  52.        if (!growing) {
  53.            body.pop_back();
  54.        }
  55.        growing = false;
  56.    }
  57.  
  58.    void grow() { growing = true; }
  59.  
  60.    void setDirection(Direction dir) {
  61.        if ((dir == UP || dir == DOWN) && (currentDirection == LEFT || currentDirection == RIGHT)) {
  62.            nextDirection = dir;
  63.        }
  64.        else if ((dir == LEFT || dir == RIGHT) && (currentDirection == UP || currentDirection == DOWN)) {
  65.            nextDirection = dir;
  66.        }
  67.    }
  68.  
  69.    bool checkCollision() const {
  70.        for (size_t i = 1; i < body.size(); ++i) {
  71.            if (body[0].x == body[i].x && body[0].y == body[i].y) {
  72.                return true;
  73.            }
  74.        }
  75.        return false;
  76.    }
  77.  
  78.    const std::vector<Point>& getBody() const { return body; }
  79. };
  80.  
  81. class Game {
  82. private:
  83.    Snake snake;
  84.    Point food;
  85.    bool gameOver;
  86.    bool paused;
  87.    int score;
  88.  
  89.    HWND hwnd;
  90.    HDC hdc, memDC;
  91.    HBITMAP memBitmap;
  92.    HBRUSH snakeBrush, foodBrush, backgroundBrush;
  93.  
  94. public:
  95.    Game(HWND hWnd) : hwnd(hWnd), gameOver(false), paused(false), score(0) {
  96.        srand(static_cast<unsigned>(time(nullptr)));
  97.        spawnFood();
  98.  
  99.        hdc = GetDC(hwnd);
  100.        memDC = CreateCompatibleDC(hdc);
  101.        memBitmap = CreateCompatibleBitmap(hdc, WINDOW_WIDTH, WINDOW_HEIGHT);
  102.        SelectObject(memDC, memBitmap);
  103.  
  104.        snakeBrush = CreateSolidBrush(RGB(255, 0, 0));
  105.        foodBrush = CreateSolidBrush(RGB(255, 0, 0));
  106.        backgroundBrush = CreateSolidBrush(RGB(0, 0, 0));
  107.    }
  108.  
  109.    ~Game() {
  110.        DeleteObject(snakeBrush);
  111.        DeleteObject(foodBrush);
  112.        DeleteObject(backgroundBrush);
  113.        DeleteObject(memBitmap);
  114.        DeleteDC(memDC);
  115.        ReleaseDC(hwnd, hdc);
  116.    }
  117.  
  118.    void spawnFood() {
  119.        std::vector<Point> availableSpots;
  120.        for (int x = 0; x < WINDOW_WIDTH / GRID_SIZE; ++x) {
  121.            for (int y = 0; y < WINDOW_HEIGHT / GRID_SIZE; ++y) {
  122.                Point p(x, y);
  123.                if (!isSnakeOnPoint(p)) {
  124.                    availableSpots.push_back(p);
  125.                }
  126.            }
  127.        }
  128.  
  129.        if (availableSpots.empty()) {
  130.            gameOver = true;
  131.            return;
  132.        }
  133.  
  134.        food = availableSpots[rand() % availableSpots.size()];
  135.    }
  136.  
  137.    bool isSnakeOnPoint(const Point& p) const {
  138.        for (const auto& segment : snake.getBody()) {
  139.            if (segment.x == p.x && segment.y == p.y) {
  140.                return true;
  141.            }
  142.        }
  143.        return false;
  144.    }
  145.  
  146.    void update() {
  147.        if (gameOver || paused) return;
  148.  
  149.        snake.move();
  150.  
  151.        if (snake.checkCollision()) {
  152.            gameOver = true;
  153.            return;
  154.        }
  155.  
  156.        if (snake.getBody().front().x == food.x && snake.getBody().front().y == food.y) {
  157.            snake.grow();
  158.            spawnFood();
  159.            score++;
  160.        }
  161.    }
  162.  
  163.    void render() {
  164.        RECT rect = { 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT };
  165.        FillRect(memDC, &rect, backgroundBrush);
  166.  
  167.        for (const auto& segment : snake.getBody()) {
  168.            RECT snakeRect = {
  169.                segment.x * GRID_SIZE,
  170.                segment.y * GRID_SIZE,
  171.                (segment.x + 1) * GRID_SIZE,
  172.                (segment.y + 1) * GRID_SIZE
  173.            };
  174.            FillRect(memDC, &snakeRect, snakeBrush);
  175.        }
  176.  
  177.        RECT foodRect = {
  178.            food.x * GRID_SIZE,
  179.            food.y * GRID_SIZE,
  180.            (food.x + 1) * GRID_SIZE,
  181.            (food.y + 1) * GRID_SIZE
  182.        };
  183.        FillRect(memDC, &foodRect, foodBrush);
  184.  
  185.        WCHAR scoreText[32];
  186.        swprintf_s(scoreText, L"Score: %d", score);
  187.        SetBkMode(memDC, TRANSPARENT);
  188.        SetTextColor(memDC, RGB(255, 255, 255));
  189.        TextOut(memDC, 10, 10, scoreText, wcslen(scoreText));
  190.  
  191.        if (gameOver) {
  192.            const WCHAR* gameOverText = L"Game Over! Press any arrow key to restart.";
  193.            TextOut(memDC, WINDOW_WIDTH / 2 - 150, WINDOW_HEIGHT / 2, gameOverText, wcslen(gameOverText));
  194.        }
  195.        else if (paused) {
  196.            const WCHAR* pausedText = L"Paused. Press any arrow key to start.";
  197.            TextOut(memDC, WINDOW_WIDTH / 2 - 120, WINDOW_HEIGHT / 2, pausedText, wcslen(pausedText));
  198.        }
  199.  
  200.        BitBlt(hdc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, memDC, 0, 0, SRCCOPY);
  201.    }
  202.  
  203.    void togglePause() {
  204.        paused = !paused;
  205.    }
  206.  
  207.    void reset() {
  208.        snake = Snake();
  209.        spawnFood();
  210.        score = 0;
  211.        gameOver = false;
  212.        paused = false;
  213.    }
  214.  
  215.    void handleKeyPress(WPARAM wParam) {
  216.        switch (wParam) {
  217.        case VK_UP:
  218.        case VK_DOWN:
  219.        case VK_LEFT:
  220.        case VK_RIGHT:
  221.            if (gameOver) {
  222.                reset();
  223.            }
  224.            else {
  225.                Direction newDir;
  226.                switch (wParam) {
  227.                case VK_UP: newDir = UP; break;
  228.                case VK_DOWN: newDir = DOWN; break;
  229.                case VK_LEFT: newDir = LEFT; break;
  230.                case VK_RIGHT: newDir = RIGHT; break;
  231.                }
  232.                snake.setDirection(newDir);
  233.                if (paused) paused = false;
  234.            }
  235.            break;
  236.        case VK_SPACE:
  237.            togglePause();
  238.            break;
  239.        case VK_ESCAPE:
  240.            reset();
  241.            break;
  242.        }
  243.    }
  244.  
  245. Game* game = nullptr;
  246.  
  247. LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  248.    switch (uMsg) {
  249.    case WM_CREATE:
  250.        game = new Game(hwnd);
  251.        SetTimer(hwnd, 1, MOVE_INTERVAL, nullptr);
  252.        return 0;
  253.  
  254.    case WM_DESTROY:
  255.        KillTimer(hwnd, 1);
  256.        delete game;
  257.        PostQuitMessage(0);
  258.        return 0;
  259.  
  260.    case WM_TIMER:
  261.        game->update();
  262.        InvalidateRect(hwnd, nullptr, FALSE);
  263.        return 0;
  264.  
  265.    case WM_PAINT:
  266.    {
  267.        PAINTSTRUCT ps;
  268.        HDC hdc = BeginPaint(hwnd, &ps);
  269.        game->render();
  270.        EndPaint(hwnd, &ps);
  271.    }
  272.    return 0;
  273.  
  274.    case WM_KEYDOWN:
  275.        game->handleKeyPress(wParam);
  276.        return 0;
  277.    }
  278.  
  279.    return DefWindowProc(hwnd, uMsg, wParam, lParam);
  280. }
  281.  
  282. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
  283.    const wchar_t CLASS_NAME[] = L"SnakeGameWindow";
  284.  
  285.    WNDCLASS wc = {};
  286.    wc.lpfnWndProc = WindowProc;
  287.    wc.hInstance = hInstance;
  288.    wc.lpszClassName = CLASS_NAME;
  289.    wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
  290.  
  291.    RegisterClass(&wc);
  292.  
  293.    HWND hwnd = CreateWindowEx(
  294.        0,
  295.        CLASS_NAME,
  296.        L"Snake Game",
  297.        WS_OVERLAPPEDWINDOW,
  298.        CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH, WINDOW_HEIGHT,
  299.        nullptr,
  300.        nullptr,
  301.        hInstance,
  302.        nullptr
  303.    );
  304.  
  305.    if (hwnd == nullptr) {
  306.        return 0;
  307.    }
  308.  
  309.    ShowWindow(hwnd, nCmdShow);
  310.  
  311.    MSG msg = {};
  312.    while (GetMessage(&msg, nullptr, 0, 0)) {
  313.        TranslateMessage(&msg);
  314.        DispatchMessage(&msg);
  315.    }
  316.  
  317.    return 0;
  318. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement