【问题标题】:C++/SDL - Rectangle Coordinates MappingC++/SDL - 矩形坐标映射
【发布时间】:2019-02-06 18:43:18
【问题描述】:

我正在使用 SDL 开发 2D 游戏。最近我实现了各种使对象(及其矩形)运动的函数,但遇到了很可能是由于矩形坐标映射效率低下造成的性能问题。请看下面:

每当调用 move() 时,矩形的二维坐标都存储在一个整数数组中。例如,坐标[0] 是x 轴上的第一个点,坐标[1] 是x 轴上的最后一个点。坐标 [2] 和 [3] 适用于 y 轴上的点。

map() 函数获取矩形的坐标并将它们存储在静态 std::map(状态类)中。每个 x 和 y 对是 0 或 1,具体取决于是否存在矩形。玩家的坐标未映射。

当玩家移动时,bool 函数 collide() 检查玩家的矩形是否在特定方向上与另一个矩形相邻。如果没有矩形挡住去路,则允许玩家移动。

一切正常,但似乎 map() 函数中的所有这些 for 循环都占用大量 CPU。当在屏幕上移动矩形时,程序会严重滞后。如何更有效地映射矩形坐标?

void move(int x, int y) {
    dstRect.x = x;
    dstRect.y = y;

    coordinate[0] = dstRect.x;
    coordinate[1] = dstRect.x + dstRect.w;
    coordinate[2] = dstRect.y;
    coordinate[3] = dstRect.y + dstRect.h;
}

void map() {
    for (int x = coordinate[0]; x != coordinate[1]; x++) {
        for (int y = coordinate[2]; y != coordinate[3]; y++) {
            Status::map().insert(std::pair<std::vector<int>, int>({ x, y }, 1));
        }
    }
}

bool collide(DIRECTION direction) {
    if (direction == UP || direction == DOWN) {
        for (int x = texture.coordinate[0]; x != texture.coordinate[1]; x++) {
            if (direction == UP) {
                if (Status::map().find({ x, texture.coordinate[2] - 1 })->second == 1) { return true; }
            }
            if (direction == DOWN) {
                if (Status::map().find({ x, texture.coordinate[3] + 1 })->second == 1) { return true; }
            }
        }
    }
    if (direction == RIGHT || direction == LEFT) {
        for (int y = texture.coordinate[2]; y != texture.coordinate[3]; y++) {
            if (direction == RIGHT) {
                if (Status::map().find({ texture.coordinate[1] + 1, y })->second == 1) { return true; }
            }
            if (direction == LEFT) {
                if (Status::map().find({ texture.coordinate[0] - 1, y })->second == 1) { return true; }
            }
        }
    }
    return false;
}

void moveRight() {
    for (int i = 0; i < speed; i ++) {
        if (!collide(RIGHT)) {
            int x = texture.dstRect.x + 1;
            int y = texture.dstRect.y;
            texture.move(x, y);
        }
    }
}

【问题讨论】:

  • 考虑使用单个vector 映射您的状态,其中每个坐标对应一个唯一索引,例如index = x + y * width。编辑:实际上,我认为您的密钥是std::pair&lt;int,int&gt;,但我现在看到它还包含vector。我不明白你的Status::map 代表什么或它的布局。
  • 您的地图似乎是std::map&lt;std::vector&lt;int&gt;, int&gt; 或类似名称。所以我的原始评论适用。每次插入地图时,您都在创建新矢量。每次要比较时都需要遍历向量,然后在搜索时遍历它。这里有很多浪费可以很容易地解释你的性能问题。
  • @FrançoisAndrieux struct Status{static std::map&lt;std::vector&lt;int&gt;, int&gt;&amp; map() { static std::map&lt;std::vector&lt;int&gt;, int&gt; objectMap; return objectMap; }}; 这就是 Status::map() 的布局方式,所以你是对的。我认为以这种方式映射坐标是一个好主意,因此我可以将坐标存储在向量 {x,y} 中并为该位置分配一个数字,具体取决于是否存在矩形。 0 表示没有物体,1 表示无法通过的物体,2 表示奖励宝箱等......
  • 您需要开始将您的“世界”分解为多个区域,以便在执行操作时快速忽略大量对象。例如,将您的世界分成 4 个象限,并将适用的对象分配给适当的存储桶。如果需要更高的分辨率,请将每个象限分解为自己的一组象限,等等。这种机制称为四叉树,它唯一适用于您的问题。
  • @Aumnayan 我以前听说过四叉树机制,但似乎很难实现。

标签: c++ mapping coordinates


【解决方案1】:

遵循@FrançoisAndrieux 的建议并创建了多维向量来存储坐标。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-09
    • 2023-04-01
    相关资源
    最近更新 更多