规划 2D 图块引擎 - 性能问题

发布于 2024-07-27 05:03:31 字数 652 浏览 5 评论 0原文

正如标题所示,我正在充实 2D 平台游戏引擎的设计。 它仍处于设计阶段,但我担心渲染器会遇到问题,如果它们成为问题,我想避免它们。

我使用 SDL 作为我的基础库,并且游戏将设置为使用单个大型 Uint16 数组来保存图块。 这些索引到第二个“图块定义”数组中,该数组被引擎的所有部分使用,从碰撞处理到图形例程,这是我最关心的。

图形引擎设计为以 640x480 分辨率运行,具有 32x32 块。 每帧每层绘制 21x16 个图块(以处理滚动时显示的额外图块),最多可以绘制四层。 层只是单独的图块数组,但图块定义数组对于所有四个层都是通用的。

我担心的是,我希望能够利用该引擎的透明度和动画图块,并且由于我对设计不太熟悉,我担心我当前的解决方案效率太低,无法使用工作顺利。

我的目标 FPS 是每秒 60 帧,并且绘制了所有四个图层,我正在查看每秒需要绘制 21x16x4x60 = 80,640 个单独的 32x32px 图块,此外,精灵还需要许多奇数大小的 blit,并且这似乎有点过分了。 那么,是否有更好的方法来渲染我拥有的图块地图设置? 我正在寻找使用硬件加速来绘制图块地图的可能性,如果它有助于大大提高性能的话。 我也希望能够在稍微旧一点的电脑上运行这个游戏。

如果我想要的太多,那么我认为降低引擎的能力并不是不可能的。

As the title says, I'm fleshing out a design for a 2D platformer engine. It's still in the design stage, but I'm worried that I'll be running into issues with the renderer, and I want to avoid them if they will be a concern.

I'm using SDL for my base library, and the game will be set up to use a single large array of Uint16 to hold the tiles. These index into a second array of "tile definitions" that are used by all parts of the engine, from collision handling to the graphics routine, which is my biggest concern.

The graphics engine is designed to run at a 640x480 resolution, with 32x32 tiles. There are 21x16 tiles drawn per layer per frame (to handle the extra tile that shows up when scrolling), and there are up to four layers that can be drawn. Layers are simply separate tile arrays, but the tile definition array is common to all four layers.

What I'm worried about is that I want to be able to take advantage of transparencies and animated tiles with this engine, and as I'm not too familiar with designs I'm worried that my current solution is going to be too inefficient to work well.

My target FPS is a flat 60 frames per second, and with all four layers being drawn, I'm looking at 21x16x4x60 = 80,640 separate 32x32px tiles needing to be drawn every second, plus however many odd-sized blits are needed for sprites, and this seems just a little excessive. So, is there a better way to approach rendering the tilemap setup I have? I'm looking towards possibilities of using hardware acceleration to draw the tilemaps, if it will help to improve performance much. I also want to hopefully be able to run this game well on slightly older computers as well.

If I'm looking for too much, then I don't think that reducing the engine's capabilities is out of the question.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

黄昏下泛黄的笔记 2024-08-03 05:03:31

我认为问题在于绘制调用的绝对数量,而不是您正在绘制的所有像素的总“填充率”。 请记住 - 您必须每秒进行超过 80000 次调用。 我认为你最大的改进是以某种方式将它们批处理在一起。

降低图块和层的填充率的一种策略是将静态区域组合在一起。 例如,如果您知道某个区域不需要更新,则可以对其进行缓存。 很大程度上取决于图层是否独立滚动(视差样式)。

另外,在 Google 上查看“脏矩形”,看看是否有任何方案可以满足您的需求。

就我个人而言,我只是尝试一下看看。 这可能不会影响你的整体游戏设计,如果你在逻辑和表现之间有很好的分离,你可以优化瓷砖绘制直到奶牛回家。

I think the thing that will be an issue is the sheer amount of draw calls, rather than the total "fill rate" of all the pixels you are drawing. Remember - that is over 80000 calls per second that you must make. I think your biggest improvement will be to batch these together somehow.

One strategy to reduce the fill-rate of the tiles and layers would be to composite static areas together. For example, if you know an area doesn't need updating, it can be cached. A lot depends of if the layers are scrolled independently (parallax style).

Also, Have a look on Google for "dirty rectangles" and see if any schemes may fit your needs.

Personally, I would just try it and see. This probably won't affect your overall game design, and if you have good separation between logic and presentation, you can optimise the tile drawing til the cows come home.

皓月长歌 2024-08-03 05:03:31

确保仅在实际使用 Alpha 的图块上使用 Alpha 透明度,并跳过绘制空白图块。 确保图块表面颜色深度尽可能与屏幕颜色深度匹配(对于具有 Alpha 通道的图块而言,这实际上不是一个选项),并将图块存储在视频内存中,以便 sdl 将在可能的情况下使用硬件加速。 对于不需要部分透明或将抗锯齿边缘与背景混合的简单图块,色键透明度将比拥有完整 Alpha 通道更快。

在 500mhz 系统上,每层每个像素大约有 6.8 个 cpu 周期,或者每个屏幕像素 27 个,(我相信)如果每层的每个图块上都有完整的 alpha 通道,这还不够,但应该如果您尽可能采取上述提到的捷径就可以了。

Make sure to use alpha transparency only on tiles that actually use alpha, and skip drawing blank tiles. Make sure the tile surface color depth matches the screen color depth when possible (not really an option for tiles with an alpha channel), and store tiles in video memory, so sdl will use hardware acceleration when it can. Color key transparency will be faster than having a full alpha channel, for simple tiles where partial transparency or blending antialiased edges with the background aren't necessary.

On a 500mhz system you'll get about 6.8 cpu cycles per pixel per layer, or 27 per screen pixel, which (I believe) isn't going to be enough if you have full alpha channels on every tile of every layer, but should be fine if you take shortcuts like those mentioned where possible.

何时共饮酒 2024-08-03 05:03:31

我同意康布瓦的观点。 如果这只是一款简单的基于图块的 2D 游戏,你真的应该降低标准一点,因为这不是《孤岛危机》。 30FPS非常流畅(研究命令与征服3限制为30FPS)。 即便如此,我还是使用 GDI+ 编写了一个以 14FPS (1900 x 1200) 运行的远程桌面查看器,而且仍然非常流畅。 我认为对于 2D 游戏,您可能没问题,尤其是使用 SDL。

I agree with Kombuwa. If this is just a simple tile-based 2D game, you really ought to lower the standards a bit as this is not Crysis. 30FPS is very smooth (research Command & Conquer 3 which is limited to 30FPS). Even still, I had written a remote desktop viewer that ran at 14FPS (1900 x 1200) using GDI+ and it was still pretty smooth. I think that for your 2D game you'll probably be okay, especially using SDL.

流云如水 2024-08-03 05:03:31

您是否可以将每个完整图层缓冲到其视图中,并为所有四个末端加上额外的图块大小(如果您有垂直滚动),再次使用缓冲区来创建一个新的缓冲区减去第一列并在新的末端列上绘制?
这将减少大量不必要的重画。

此外,如果您想要 60fps,您可以查找为较慢的系统创建跳帧方法的方法,跳过每隔一个或每隔三个绘制阶段。

Can you just buffer each complete layer into its view plus an additional tile size for all four ends(if you have vertical scrolling), use the buffer again to create a new buffer minus the first column and drawing on a new end column?
This would reduce a lot of needless redrawing.

Additionally, if you want a 60fps, you can look up ways to create frame skip methods for slower systems, skipping every other or every third draw phase.

只有影子陪我不离不弃 2024-08-03 05:03:31

我想您一定会惊讶地发现您一秒钟可以绘制多少张这样的图块。 现代图形硬件可以每帧以 60 fps 多次填充 1600x1200 帧缓冲区,因此您的 640x480 帧缓冲区不会有问题。 尝试一下,看看你会得到什么。

您绝对应该利用硬件加速。 这将为您提供 1000 倍的性能,而您只需付出很少的努力。

如果您确实发现需要优化,那么最简单的方法是仅重绘自上一帧以来发生更改的屏幕区域。 听起来您需要了解任何动画图块以及每帧状态已更改的任何图块。 根据游戏的不同,这可以是完全没有任何好处,也可以是大量节省 - 这实际上取决于屏幕每帧的变化量。

I think you will be pleasantly surprised by how many of these tiles you can draw a second. Modern graphics hardware can fill a 1600x1200 framebuffer numerous times per frame at 60 fps, so your 640x480 framebuffer will be no problem. Try it and see what you get.

You should definitely take advantage of hardware acceleration. This will give you 1000x performance for very little effort on your part.

If you do find you need to optimise, then the simplest way is to only redraw the areas of the screen that have changed since the last frame. Sounds like you would need to know about any animating tiles, and any tiles that have changed state each frame. Depending on the game, this can be anywhere from no benefit at all, to a massive saving - it really depends on how much of the screen changes each frame.

無心 2024-08-03 05:03:31

您可能会考虑使用纹理平铺将具有相同纹理的相邻图块合并到更大的多边形中(某种构建过程)。

You might consider merging neighbouring tiles with the same texture into a larger polygon with texture tiling (sort of a build process).

仅此而已 2024-08-03 05:03:31

将帧速率降低到 30fps 怎么样? 我认为对于 2D 游戏来说已经足够了。

What about decreasing the frame rate to 30fps. I think it will be good enough for a 2D game.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文