【问题标题】:OOP structure, and possibly some stuff about threads [closed]OOP结构,可能还有一些关于线程的东西[关闭]
【发布时间】:2014-02-16 05:48:24
【问题描述】:

我正在用 SDL 编写一个 2D 游戏,在这个游戏中,我想创建一个“鸟”类,它将在屏幕上为一只简单的鸟制作动画。我认为这是最好的工作方式是有一个基类来绘制我想要的东西,然后有子类('bird' 类,'player' 类,最后是子弹类等)。基类的draw成员函数会调用子类的成员函数来绘制自己(使用基类中的函数),那么首先,这是构造我的游戏的合理方式吗?

其次,当我调用例如我的“鸟”类的绘制函数时,该函数需要知道它正在播放动画的哪一帧,并返回适当的图像。每次调用函数时增加帧号会更好,还是让函数在单独的线程上运行,这样在调用函数的任意时间它都会返回正确的帧,但这意味着我'd 需要一个单独的线程来处理屏幕上的每个动画精灵。

我考虑做第二种的原因是,在第一种方法中,运行相同程序的不同计算机将以不同的速度运行,因此动画也会如此,所以我唯一的选择是固定数量每秒调用渲染函数的次数。在第二种方法中,帧计数器在单独的线程中运行,我可以在函数显示下一帧之前设置特定的时间延迟,这意味着整个动画的速度完全不受渲染次数的影响函数被调用。

最后一个快速问题 - 对于我的“鸟”类,如果该类的每个实例都是单独的鸟,或者有一个控制 X 多只鸟的实例会更好吗?它有什么不同吗?

【问题讨论】:

    标签: c++ multithreading oop sdl


    【解决方案1】:

    你应该在https://gamedev.stackexchange.com/问这种类型的问题

    但无论如何,要回答您的问题,您可以通过多种方式构建它。对于小型游戏,您可能最好使用某种倾向于组合胜于继承的基本 OOP 结构。 (wikipedia entryan SO question on this topic)。这应该会给你一些灵活性和可重用性,并有助于避免意大利面。

    通常你希望你的帧更新发生在主线程上。无需完全消除已经要处理随机性元素的编码项目中的确定性!尽管跨多个线程执行对象更新并非闻所未闻,但在绝对需要之前,您可能希望推迟执行此操作。避免premature optimization

    您需要研究计时机制并管理 FPS 和游戏时钟。有一些不需要多线程编程的可访问、简单的技术。

    另一件要考虑的事情是,有时游戏体验并不会因为你的编程概念很花哨而变得更有趣。您可能会发现,当动画和 FPS 减速与运动不同步时,玩家会感到沮丧。

    与你的游戏效率相关的变量太多了,很难回答这个问题 - 但这些天我不太关心慢速机器,而是首先制作一款具有有趣机制并且足够酷的酷游戏 视觉上刺激的图形和着色器,我不需要与 John Carmack 竞争。

    其次,当我调用例如我的“鸟”类的绘图函数时,该函数需要知道它正在播放动画的哪一帧,并返回适当的图像。

    这对我来说是个危险信号。我可能会假设最坏的情况,但与其掩饰它,不如让我们谈谈它。在具有少量精灵的“游戏”中,您可以将单独的图像加载到内存中并根据需要显示它们。但是随着时间的推移,这可能会很快变得丑陋,并且您开始将对象添加到您的应用程序中。对于您要显示的每个图像,硬件(实现您所针对的任何 GL 规范的东西)都需要为这些图像保留一些​​内存。本身并不是一件可怕的事情。棘手的瓶颈部分是图形硬件想要实际绘制东西的时候。它必须将硬件上的一般内存中的内容保存在视频内存中。因此,精灵表(或纹理图集)变得非常有用 - 而不是说“嘿,画另一个图像”,你只说“嘿画同一个大图像的不同部分”(那些不同的“部分”将是框架您的动画;多个动画可以存在于纹理图集中;纹理图集的大小通常为 2 的幂,这对于 GPU 来说是最佳的)。 Side note on powers of 2.

    来自this SO question

    GPU 编程的神圣法则是,你与 GPU 交谈越少,她就越爱你。

    当然,您需要在这与管理着色器之间取得平衡,但您可以在深入研究时研究并尝试这一点。

    另一个途径,实际上就像是在破解上作曲,是Entity-Based Component System。这允许您向对象添加行为和属性(例如对来自控制器/键盘的输入命令做出反应的能力,或者在屏幕上绘图的能力,或者承受伤害或修改“健康”或无敌的能力,对物理/重力作出反应的能力)。

    对于小型游戏,我建议您不要这样做,除非您将其视为大型学习练习。但即便如此,将其中一些概念分解成小块并一次玩一场游戏可能是个好主意。

    希望对你有帮助,祝你好运。

    【讨论】:

    • 干杯,这是一个非常有帮助的答案。关于“返回适当的图像”的部分,我的意思是返回精灵表的适当部分。
    • 是的,我打算将这个游戏的创建视为一种学习练习——但显然只是在一定程度上,我并不那么渴望了解互斥锁和信号量以及所有更精细的细节多线程程序,而我仍然掌握正确构建面向对象编程的窍门。我现在也丝毫不担心优化。
    【解决方案2】:

    一般的经验法则是拥有一个包含动画的容器。

    由于对象具有不同的动画规则,您可能希望有一个“动画”函数并传递对象的位置信息(例如帧;x、y 和 z 坐标等)。

    另一个视图是让对象记住它们的位置。这可以简化帧的编码。框架会告诉所有对象进行动画处理,并且对象会随着框架关心它们的位置而改变它们的位置。

    【讨论】:

    • 那么在大多数情况下,引入多个线程会使事情变得过于复杂?
    • 您将有一个线程唤醒,检查容器并对需要动画的对象进行动画处理,然后重新进入睡眠状态。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-03
    • 1970-01-01
    相关资源
    最近更新 更多