OpenGL 2D游戏问题

4

我想使用OpenGL制作一个2D的像Worms一样有可摧毁地形的游戏。

  • 实现这个功能的最佳方法是什么?
    • 逐像素绘制?(嗯,不好吧?)
    • 将世界作为纹理并对其进行操作(是否可能?)

提前感谢您的帮助。

7个回答

15

考虑到Worms游戏中地形的外观,我想到了这个想法。但是我不确定你如何在OpenGL中实现它。这更像是一种分层2D绘图方法。无论如何我还是要发布这个想法。我使用Paint.NET模拟了这种方法。

首先,你有一个背景天空层。

alt text

然后你有一个地形层。

alt text

地形层被掩蔽以便顶部部分不被绘制。将地形层放在天空层上方以形成场景。

alt text

现在是主要的想法。每当发生爆炸或其他改变地形的事件时,您可以在地形层上绘制圆形或其他形状,使用地形层本身作为绘图掩模(因此只绘制与现有地形重叠部分的圆形部分),以擦除部分地形。使用透明/掩蔽颜色的笔刷进行填充,并使用类似于地形的颜色进行粗笔触绘制。

alt text

您可以重复此过程以添加更多变形。如果没有太多的变形需要渲染,您可以将此层保留在内存中并在发生变形时添加它们,甚至可以每帧在内存中进行渲染。

alt text


非常好的插图,帮助我理解你的意思 :) 感谢你的回答。 - Mrfrank
就我个人而言,我能够使用掩码和剪辑区域在代码(Python和wxPython)中实现这一点。结果看起来就像Worms游戏一样,他们可能使用了这种方法或非常相似的方法。但是我无法帮助OpenGL方面的问题。 - FogleBird

2

我猜你最好使用具有正确映射的纹理填充多边形(线性映射不会拉伸纹理以使用所有纹素,而是将裁剪区域留出),然后在它们被摧毁时重新塑造它们。


我已经考虑过这个问题,尽管对我来说能够访问和操作每个像素非常重要,但使用多边形方法是不可能实现的。 - Mrfrank
2
如果你足够精确地操作边缘(没有什么能阻止你将顶点放置在像素边界上),那么它就是可以的。如果你做得好,甚至可以轻松地用反锯齿绘制你的形状。 - fortran

0

抱歉,我不需要关于碰撞检测的帮助,我甚至都没有提到它:o 谢谢你的回答。 - Mrfrank
好的 - 抱歉 - 我以为你在寻找一种可以轻松用于游戏其余部分的地形处理方法。您可能需要查看此教程,了解如何编写纹理(因此添加透明部分以表示土地被取走的位置): http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=29 - Marc

0
我想象的方式是这样的:
  • 应用纹理的平面
  • 用于地面碰撞的路径(点/线段向量)

当某些物体爆炸时,您将使用几何布尔运算 (矩形-圆) 处理纹理(揭示背景)和 '可行走' 路径。

我想说的是,您要执行几何布尔运算,并使用结果来更新纹理(使用 alpha 蒙版或其他方法)和更新用于跟踪可行走区域的数据结构(无论是哪一个)。

将事物分开,而不仅依赖于 gl 绘图方法。


0

我认为首先要将前景绘制到模板缓冲区中,这样模板缓冲区就会在任何有前景的地方设置为1位,而在其他地方(你想让天空显示的地方)则为0。

然后,要绘制一个帧,你需要绘制天空,启用模板缓冲区,并绘制前景。对于初始帧(在任何爆炸摧毁前景的部分之前),模板缓冲区实际上不会起作用。

然而,当你有了爆炸时,你需要将其绘制到模板缓冲区中(清除该圆形的模板缓冲区)。然后像以前一样重新绘制数据:绘制天空,启用模板缓冲区,并绘制前景。

这样可以让你获得想要的效果(前景消失在所需位置),而无需修改前景纹理。如果你不想使用模板缓冲区,我认为明显的替代方法是启用混合,并且只操作前景纹理的alpha通道--在受爆炸影响的地方将alpha设置为0(透明)。在我看来,模板缓冲区是一种更简洁的方法,但操作alpha通道也很简单。


0

我认为,这只是一个快速的想法,一个好的方法可能是绘制大量的线条。

我在考虑将景观表示为一堆线段,对于屏幕的每一列,您都有0.. n个垂直线条,组成地面:

 12    789
0123  6789
0123456789
0123456789

在上面的代码中,“0”列组成了一条单独的线,以此类推。我没有尝试说明单个像素列有多行的情况,因为在这种粗略的格式下有点困难。
我不确定这样做是否高效,但至少它对于OpenGL原语是有意义的。
您可以通过启用纹理映射并为每个线段指定所需的纹理坐标来着色和纹理化线条。

但是我该如何为地形添加颜色/纹理呢? - Mrfrank

-1
通常我看到的做法是将每个实体作为纹理四边形,然后更新动画的纹理。对于可破坏地形,最好将地形分成瓦片,然后只更新已更改的瓦片。不要使用GLdrawpixels,它可能是最慢的方法(除了每帧从磁盘重新加载纹理,尽管它会很接近)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接