hello_world34 2024-05-26 15:31 采纳率: 0%
浏览 4

WindowsC++

使用Windows和c++编程做一个小游戏
目的是做一个游戏,现在其中一个模块不知道怎么做;


!!最恶心的就是只能用这些个东西做啊,其他都不让用
问题:运行这个游戏后,玩家进入界面,有两个功能:选择地图,自定义地图。‘选择地图’则进入选择地图界面挑选地图进入游戏(这些功能都还没做(╯°□°)╯︵ ┻━┻)。
自定义地图,其实也就是画一些线段,矩形(也可以理解为四条线段),然后要怎么把这个自定义的地图保存起来,用什么方式保存起来下一步用的时候怎么拿进来处理。(这些功能都还没做)
因为我的游戏运行是需要利用地图中的所有线段,所以上面保存以后还要能方便我的读取.

游戏地图是类似下图这样的(随便画的):

img


一点想法(不知行不行)

保存为bmp格式的?(因为存储了每个像素),所以大概会好读取一点?然后把它变成一个二维数组,背景用0表示,墙壁(线段)用1表示,这样就得到了数组

img

然后再遍历这个数组,进行处理,返回一个**vector<line>**(LINE是我自己定义的结构体)</line>

struct LINE {
    POINT p1;
    POINT p2;
};

至于获取线段,直接遍历就行,像下面这样。

//读取二维数组(0,1表示),返回一个表示地图中的 线段 数组
vector<LINE> ReadFromArray(vector<vector<int>> matrix) {
    vector<LINE> allLines;

    //行遍历
    for (int i = 0; i < matrix.size(); i++) {
        int cnt = 0;
        for (int j = 0; j < matrix[i].size(); j++) {
            if (matrix[i][j]==1)//墙壁
                cnt++;
            else {
                if (cnt >= 2) {
                    allLines.push_back({ POINT{j - 1,i},POINT{j - cnt,i} });
                }
                cnt = 0;
            }
        }
        if (cnt >= 2) {
            int j = matrix[i].size();
            allLines.push_back({ POINT{j - 1,i},POINT{j - cnt,i} });
        }
    }

    //列遍历
    for (int i = 0; i < matrix[0].size(); i++) {
        int cnt = 0;
        for (int j = 0; j < matrix.size(); j++) {
            if (matrix[j][i] == 1)//墙壁
                cnt++;
            else {
                if (cnt >= 2) {
                    allLines.push_back({ POINT{i,j - 1},POINT{i,j - cnt} });
                }
                cnt = 0;
            }
        }
        if (cnt >= 2) {
            int j = matrix.size();
            allLines.push_back({ POINT{i,j - 1},POINT{i,j - cnt} });
        }
    }

    //到这里所有直线段已经加入vector
    return allLines;
}
  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-05-26 15:31
    关注

    引自免费微信小程序:皆我百晓生

    为了实现这个功能,你需要按照以下步骤操作:

    1. 创建一个窗口并显示地图
    2. 实现绘图功能
    3. 保存地图到文件
    4. 从文件加载地图

    首先,确保你已经包含了必要的头文件,并且创建了一个简单的窗口。这里是一个基本的Win32 API窗口示例:

    #include <windows.h>
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
    struct LINE {
        POINT p1;
        POINT p2;
    };
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
        // ... 其他初始化代码 ...
    
        // 创建窗口
        HWND hWnd = CreateWindow("Static", "My Game", WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL, hInstance, NULL);
    
        ShowWindow(hWnd, nCmdShow);
        UpdateWindow(hWnd);
    
        MSG msg;
        while (GetMessage(&msg, NULL, 0, 0)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    
        return msg.wParam;
    }
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
        switch (message) {
            case WM_PAINT:
                // 在这里绘制地图
                break;
            case WM_DESTROY:
                PostQuitMessage(0);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
        }
        return 0;
    }
    

    接下来,我们添加绘图功能。在WM_PAINT消息处理函数中,使用GDI来绘制线段和矩形。你需要先调用BeginPaintEndPaint来正确地开始和结束绘画过程。

    HDC hdc;
    PAINTSTRUCT ps;
    
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        // 清空屏幕
        FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW+1));
        
        // 绘制自定义地图
        // 这里只是一个示例,你需要根据用户输入的线段和矩形来绘制
        Rectangle(hdc, 50, 50, 150, 150); // 一个矩形
        MoveToEx(hdc, 10, 10, NULL);
        LineTo(hdc, 50, 50); // 一条线段
        
        EndPaint(hWnd, &ps);
        break;
    

    现在,我们需要将地图保存到文件。你可以使用BMP格式,但更好的方法可能是使用更轻量级的文本格式,比如JSON,这样可以减少文件大小,也更容易解析。这里我们使用JSON作为例子。首先,定义一个函数来将地图数据转换成JSON字符串:

    #include <nlohmann/json.hpp>
    
    std::string MapToJson(const std::vector<std::vector<int>>& matrix) {
        nlohmann::json jsonMap;
        for (const auto& row : matrix) {
            jsonMap.push_back(row);
        }
        return jsonMap.dump();
    }
    

    然后,在用户点击保存按钮时,调用此函数并将结果写入文件:

    case WM_COMMAND:
        if (LOWORD(wParam) == IDC_SAVEBTN && HIWORD(wParam) == BN_CLICKED) {
            std::ofstream file("map.json");
            if (file.is_open()) {
                file << MapToJson(matrix);
                file.close();
                MessageBox(hWnd, "Map saved!", "Info", MB_OK);
            } else {
                MessageBox(hWnd, "Failed to save map!", "Error", MB_OK);
            }
        }
        break;
    

    最后,你需要一个函数来从文件中加载地图。这可以通过读取JSON文件并解析它来完成:

    std::vector<std::vector<int>> JsonToMap(const std::string& jsonString) {
        nlohmann::json jsonMap = nlohmann::json::parse(jsonString);
        std::vector<std::vector<int>> matrix;
        for (const auto& row : jsonMap) {
            std::vector<int> rowInts(row.begin(), row.end());
            matrix.push_back(rowInts);
        }
        return matrix;
    }
    

    当游戏启动时,检查是否有已保存的地图文件,如果有,则加载它:

    bool LoadMap(std::vector<std::vector<int>>& matrix) {
        std::ifstream file("map.json");
        if (file.is_open()) {
            std::string contents((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
            file.close();
            matrix = JsonToMap(contents);
            return true;
        }
        return false;
    }
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
        // ... 其他初始化代码 ...
        
        std::vector<std::vector<int>> matrix;
        if (!LoadMap(matrix)) {
            // 初始化一个空地图或其他默认地图
        }
    
        // 创建窗口 ...
    }
    

    这样,你就有了一个可以保存和加载自定义地图的游戏。在实际游戏中,你可能还需要添加更多交互逻辑,例如让用户绘制线段和矩形、处理鼠标事件等。不过,这些基础功能应该足够让你开始构建你的游戏了。记得根据你的具体需求调整代码,以适应你的游戏设计。

    评论 编辑记录

报告相同问题?

问题事件

  • 修改了问题 5月26日
  • 创建了问题 5月26日