【问题标题】:how to draw a maze using openGL for iphone development? [closed]如何使用openGL为iphone开发绘制迷宫? [关闭]
【发布时间】:2009-08-04 15:48:00
【问题描述】:

我想知道是否有人可以让我开始使用 openGL 像迷宫一样构建。我需要编写代码来绘制迷宫还是像在单独的窗口中绘制图片一样?我需要创建一个游戏引擎来开始吗?我正在为 iphone 开发做这个,所以任何建议对我来说都是一个很好的开始。谢谢大家的回复。

【问题讨论】:

  • 如果您的问题是关于 iphone 开发的,请在问题正文中编辑并说明;这有很大的不同。

标签: iphone objective-c xcode iphone-sdk-3.0


【解决方案1】:

一个非常简单的方法,它会给你一些类似于 Wolfenstein 3D 的结果(但使用 OpenGL 的优点要容易得多 :-P)是让世界由一个 2D 网格组成,例如:

+-+-+-+-+-+-+-+
| | | | | | | |
+-+-+-+-+-+-+-+
| | | | | | | |
+-+-+-+-+-+-+-+
| | | | | | | |
+-+-+-+-+-+-+-+
| | | | | | | |
+-+-+-+-+-+-+-+

每个单元格都应包含有关单元格的信息,例如单元格是空的还是实心的,如果是实心的,它有什么材料,或者如果它是空的,地板和天花板有什么材料。如果它为空,您还可以添加其他信息,例如灯光投射、对某些实体的引用(用于添加游戏模型或其他东西)、逻辑标志(例如“退出”或“开始”或“危险”的标志)等. 一个简单的结构类似于(在 C 中):

#define SOLID 0x0001
#define START 0x0002
#define EXIT 0x0004
#define HAZARD 0x0008

struct _cell_t
{
    unsigned int flags;
    GLuint texture;
    entity_t* entity;
} cell_t;

在上述结构中,flags 是单元格的标志。如果设置了SOLID 标志,则单元格是实心(墙),如果设置了START 标志,则单元格是玩家的开始位置,如果设置了EXIT 标志,则单元格是迷宫的出口位置,并且最后,如果设置了HAZARD,则单元格会对播放器造成伤害。当然,您可以在那里添加更多标志(例如投射光的LIGHT 标志、将单元格标记为秘密区域的一部分的SECRET 标志等),但您明白了:-)。

texture 字段是一个 OpenGL ES 纹理名称(使用glGenTextures 生成并使用glTexImage2D 填充)。这用于渲染迷宫(为了简单起见,这里我只使用一个纹理,但如果你想显示更有趣的世界,你应该为实体单元指定四个纹理,为空单元指定两个纹理 - 这四个纹理将是每一侧的纹理一个单元格/墙壁,两个纹理将是单元格的地板和天花板)。

entity 字段只是对实体的引用,如果您想添加实体。静态实体(如花瓶、灯、桌子等)通常由网格和材质组成。当然,如果您想添加动态实体(例如怪物、拾取物品等),您需要将动画信息添加到实体结构中,并将“动态”实体列表与单元格分开,因为这些实体会移动环游世界,因此不会“属于”一个单元格(出于优化原因,您可能希望在每个单元格中分配一个“临时”实体,但优化是您应该在之后让引擎/游戏运行)。

现在要渲染迷宫,只需渲染所有单元格(稍后您可能想要进行一些泛洪填充或光线投射测试以仅渲染可见的内容,但现在再次不必担心)。对于每个单元格,检查单元格的标志是否包含SOLID 标志,如果是,则渲染组成单元格的四个四边形(想象一个没有顶部和底部的立方体)。如果单元格没有SOLID 标志,则渲染单元格的地板和天花板的两个四边形(想象同一个立方体,但现在只有一个顶部和一个底部)。如果您正在渲染的单元格有一个不为空的entity 字段,那么也渲染该实体。

如果你这样做,你就会有一个迷宫:-)。一些优化提示:

  • 您会很快意识到您正在渲染许多永远不会看到的四边形。如果这确实对速度有影响(并且在您尝试仅渲染可见单元格之后),您可能希望扩展包含单元格壁实际存在的标志的结构。例如,想象这三个连续的单元格:ABC。单元格AC 有三面墙(A 的左、上、下和B 的右、上、下),B 的单元格有两面墙(上和下)。要标记墙壁是否存在,请检查每个单元格周围的单元格。
    • 如果一个单元格上方有一个SOLID 单元格,则它的“向上”墙不存在。其左侧单元格、右侧单元格和下方单元格也是如此。
    • 如果单元格位于地图边缘,则始终缺少一堵墙。如果在拐角处,总是缺少两堵墙。
    • 在初始化游戏时进行此计算,而不是在渲染时!
    • 确定哪些单元格可见后进行这些测试。在开始为此编写代码之前,请保留一份备份(希望您会使用一些版本控制系统,例如 Subversion,但即使不只是将代码复制到某处)并比较两个版本的结果。不移除空墙而是使用 VBO 对所有墙壁使用相同的网格实际上可能更快 - 特别是在 iPhone 3GS 上。
  • 如果您添加动态实体并拥有我上面提到的“临时实体”,您实际上可以自动丢弃不可见的动态实体,一旦您有一种方法来确定哪些单元格是可见的,哪些不可见:如果一个单元格不可见,它的关联的动态实体也将不可见(但请注意:一个实体可以触摸多个单元格)。
  • 一种非常简单但非常粗略的不渲染所有单元格的方法,就是只渲染相机周围的单元格,例如:

.

+-+-+-+-+-+-+-+
| |X|X|X| | | |
+-+-+-+-+-+-+-+
| |X|C|X| | | |
+-+-+-+-+-+-+-+
| |X|X|X| | | |
+-+-+-+-+-+-+-+
| | | | | | | |
+-+-+-+-+-+-+-+

(这里 C 是摄像头所在的单元格,X 是摄像头周围的单元格 - 当然,出于说明目的,我只使用了与摄像头相隔一个单元格的单元格,但您应该使用更多的单元格 - 比如 16以单元格为例。只要确保您的地图永远不会有一个可以看到超过 16 个单元格或任何您决定的空白区域)

当然,投射光线可能会产生更好的效果:-)。

嗯,我认为这些信息足以为您提供一个起点:-)。当然,Stackoverflow 在这里可以解决您可能遇到的任何其他问题:-P

【讨论】:

    【解决方案2】:

    生成迷宫的代码应该独立于绘图。您可以尝试先在控制台中生成视觉效果,然后再使用 OpenGL。

    这是您可以在控制台中使用的那种布局,其中 S == Start et E == End。

    +=+=+=+
    |S|   |
    + + + +
    |   |E|
    +-+-+-+
    

    底层结构可以是一个二维结构数组,它告诉你可以从迷宫中的特定位置移动到哪里:

    struct {
      bool Left;
      bool Right;
      bool Up;
      bool Down;
    }
    

    现在要生成迷宫,我相信有很多方法可以做到。一个简单的解决方案:用墙初始化迷宫(每个布尔值都为 false),然后在 S 和 E 之间建立一条可行走的路径。然后随机设置布尔值而不影响你的路径。

    玩得开心:)

    【讨论】:

      【解决方案3】:

      使用地图编辑器。开始使用 QuArK 之类的内容。

      还可以查看Game Level Builder。这可能比您要查找的要多,但我想我还是会在这里引用它。

      【讨论】:

        【解决方案4】:

        您甚至可能不需要为此使用 OpenGL。 John Blackburn 有一个post,他在其中展示了如何仅使用 Core Animation 制作迷宫般的结构。如果这样的解决方案的性能对您来说足够好,它可以节省大量代码。

        【讨论】:

          【解决方案5】:

          我已经这样做了,我建议你这样做,是之前所说的混合。

          1) 编写一个能够实际创建迷宫的算法,这里有几个选项,一些非常简单的选项(恕我直言),是 Kruskal 和 Primm。你应该看看Here

          2) 如果你打算做一些精灵作品,或者游戏中的东西实际移动,我建议使用预制的游戏引擎,只是为了节省一些工作给你。如果您想更深入地了解游戏引擎技术,您可以稍后再进行。我推荐一个名为Cocos2D 的优秀开源2d 游戏引擎。

          祝你好运,迷宫生成是我几年前进入 C++(然后退出它 :P)的方式。

          【讨论】:

            猜你喜欢
            • 2019-04-09
            • 2015-09-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-08-02
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多