0

ちらつきが止まらない。dubbel-buffering を追加するようアドバイスを受けました。それ、どうやったら出来るの?

#include <iostream>
#include <windows.h>
#include <string>
#include <fstream>
#include <vector>

using namespace std;

namespace {
    const int ID_NEW = 1;
    const int ID_QUIT = 2;
    const int ID_ABOUT = 3;
    const int NORTH_BUTTON_ID = 4;
    const int SOUTH_BUTTON_ID = 5;
    const int WEST_BUTTON_ID = 6;
    const int EAST_BUTTON_ID = 7;
    const int ID_FINISHED_GAME = 8;
    int x = 0;
    int y = 0;
    int xStart = 0;
    int yStart = 0;
    int windowHeight = 400;
    int windowWidth = 500;
    char level1[20][21];
    int noOfMoves = 0;
}

void readLevel(string fileName, char level[20][21]) {
    char character{};
    ifstream file(fileName);
    int i = 0;
    int j = 0;
    if (file.is_open()) {
        while (file >> character) {
            level[j][i] = character;
            if (level[j][i] == 's') {
                y = yStart = j;
                x = xStart = i;
            }
            if (++i % 20 == 0) {
                i = 0;
                j++;
            }
        }
        file.close();
    }
}

void restart(){
    x = xStart;
    y = yStart;
    noOfMoves = 0;
}

LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    HDC hdc{ 0 };
    PAINTSTRUCT ps{ 0 };
    switch (msg) {
    case WM_CLOSE:
        PostQuitMessage(0);
        return 0;
    case WM_COMMAND:
        switch (LOWORD(wParam)){
        case ID_ABOUT:
            MessageBox(hwnd, L"About this program!", L"About", MB_OK);
            return 0;
        case ID_NEW:
            restart();
            return 0;
        case ID_QUIT:
            if (MessageBox(0, L"Do you really want to quit?", L"Are you sure?", MB_YESNO) == IDYES) {
                PostQuitMessage(0);
                return 0;
            }
        case NORTH_BUTTON_ID:
            if (level1[y - 1][x] != '1') {
                y -= 1;
                noOfMoves++;
            }
            break;
        case SOUTH_BUTTON_ID:
            if (level1[y + 1][x] != '1'){
                y += 1;
                noOfMoves++;
            }
            break;
        case WEST_BUTTON_ID:
            if (level1[y][x - 1] != '1'){
                x -= 1;
                noOfMoves++;
            }
            break;
        case EAST_BUTTON_ID:
            if (level1[y][x + 1] != '1') {
                x += 1;
                noOfMoves++;
            }
            break;
        }
        if (level1[y][x] == 'e') {
            wstring moves = L"Congratulations, you finished the game with " + to_wstring(noOfMoves);
            MessageBox(hwnd, moves.c_str(), L"Finished game", MB_OK);
        }
    case WM_PAINT: {
                       char wall[2] = { "W" };
                       char floor[2] = { 'W' };
                       char current[2] = { "X" };
                       char goal[2] = { "G" };
                       wstring position = L"Position = [" + to_wstring(x) + L", " + to_wstring(y) + L"]";
                       wstring moves = L"Move = " + to_wstring(noOfMoves);
                       hdc = BeginPaint(hwnd, &ps);
                       TextOut(hdc, 20, 200, position.c_str(), position.size());
                       TextOut(hdc, 20, 220, moves.c_str(), moves.size());
                       for (int i = 0; i < 20; i++) {
                           for (int j = 0; j < 20; j++) {
                               if (level1[j][i] == '1') {
                                   SetTextColor(hdc, RGB(0, 0, 0));
                                   SetBkColor(hdc, RGB(0, 0, 0));
                                   TextOut(hdc, 14 * i + 190, 14 * j + 20, LPCTSTR(wall), strlen(wall));
                               }
                               SetBkColor(hdc, RGB(255, 255, 255));
                               if (level1[j][i] == '0') {
                                   SetTextColor(hdc, RGB(255, 255, 255));
                                   TextOut(hdc, 14 * i + 190, 14 * j + 20, LPCTSTR(floor), strlen(floor));
                               }
                               SetTextColor(hdc, RGB(0, 0, 0));
                               if (i == x && j == y)
                                   TextOut(hdc, 14 * i + 190, 14 * j + 20, LPCTSTR(current), strlen(current));
                               if (level1[j][i] == 'e')
                                   TextOut(hdc, 14 * i + 190, 14 * j + 20, LPCTSTR(goal), strlen(goal));
                           }
                       }
                       EndPaint(hwnd, &ps);
                       break;

    }
    case WM_ERASEBKGND:
        return true;
    }
    return DefWindowProc(hwnd, msg, wParam, lParam);
}

HMENU CreateMainMenu() {
    HMENU main = CreateMenu();
    HMENU file = CreateMenu();
    AppendMenu(file, MF_STRING, ID_NEW, L"&New");
    AppendMenu(file, MF_SEPARATOR, 0, 0);
    AppendMenu(file, MF_STRING, ID_QUIT, L"&Quit");
    AppendMenu(main, MF_POPUP, (UINT_PTR)file, L"&File");
    HMENU help = CreateMenu();
    AppendMenu(help, MF_STRING, ID_ABOUT, L"&About");
    AppendMenu(main, MF_POPUP, (UINT_PTR)help, L"&Help");
    return main;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow) {
    readLevel("level1.txt", level1);
    WNDCLASS wc = { 0 };
    wc.hbrBackground = NULL;
    wc.lpfnWndProc = WinProc;
    wc.hInstance = hInstance;
    wc.lpszClassName = L"MyWindowClass";
    RegisterClass(&wc);
    HWND hwnd = CreateWindow(L"MyWindowClass", L"The Maze",
        WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
        windowWidth, windowHeight, 0, CreateMainMenu(), hInstance, 0);
    HWND buttonNorth = CreateWindow(L"BUTTON", L"NORTH", WS_CHILD | WS_VISIBLE,
        10, 20, 150, 40, hwnd, (HMENU)NORTH_BUTTON_ID, hInstance, 0);
    HWND buttonSouth = CreateWindow(L"BUTTON", L"SOUTH", WS_CHILD | WS_VISIBLE,
        10, 60, 150, 40, hwnd, (HMENU)SOUTH_BUTTON_ID, hInstance, 0);
    HWND buttonEast = CreateWindow(L"BUTTON", L"EAST", WS_CHILD | WS_VISIBLE,
        10, 140, 150, 40, hwnd, (HMENU)EAST_BUTTON_ID, hInstance, 0);
    HWND buttonWest = CreateWindow(L"BUTTON", L"WEST", WS_CHILD | WS_VISIBLE,
        10, 100, 150, 40, hwnd, (HMENU)WEST_BUTTON_ID, hInstance, 0);
    UpdateWindow(hwnd);
    ShowWindow(hwnd, nCmdShow);
    MSG msg = { 0 };
    BOOL isRunning = true;
    while (isRunning) {
        while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
            if (msg.message == WM_QUIT)
                isRunning = false;
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        wc.hbrBackground = NULL;
        InvalidateRect(hwnd, NULL, FALSE);
        Sleep(10);
    }
    return 0;
}
4

1 に答える 1