首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用SFML构建2D游戏引擎

使用SFML构建2D游戏引擎
EN

Code Review用户
提问于 2016-10-15 19:55:20
回答 1查看 2.6K关注 0票数 6

我一直喜欢制作游戏和使用SFML,直到几天前,我还不得不一遍又一遍地重写代码。所以我决定写一个游戏引擎,这样我就可以重用我的代码了。

我以前从没做过这样的事。我读过这篇文章,看了几段视频。如果你能四处看看,给我点主意,我会很高兴的。请记住,我在这方面只做了不到一周的工作。

GitHub

到目前为止,我只是用我自己的类重新编写了SFML函数和类,但是我改变了一些函数,使事情变得简单了一些。

例如,创建我自己的Sprite类是否有什么好处?它基本上是SFML sprite类的重新皮肤,可能是添加了一些功能,还是我的资源管理器应该只返回SFML sprite,引擎的用户只需要为sf::Sprite使用所有内置的功能?

这里有一个非常简单的程序,它创建一个sprite和一个文本,并在屏幕上绘制它们。我们可以用WASD移动雪碧。

代码语言:javascript
复制
#include <Tengine2D\ResourceManager.hpp>
#include <Tengine2D\Window.hpp>
#include <Tengine2D\Keyboard.hpp>
#include <Tengine2D\Clock.hpp>
#include <Tengine2D\Text.hpp>
#include <Tengine2D\Vector2.hpp>
#include <Tengine2D\GameState.hpp>
#include <Tengine2D\Camera.hpp>

#include <iostream>

int screenWidth = 1600;
int screenHeight = 640;

t2d::Clock _clock;
t2d::GameState gameState;

int main()
{

    t2d::Window _window;
    _window.create(screenWidth, screenHeight, "BELLO!");

    gameState = t2d::GameState::PLAY;

    // Text
    t2d::ResourceManager::createText("Text", "Fonts/times.ttf");
    t2d::ResourceManager::getText("Text").setCharacterSize(50);
    t2d::ResourceManager::getText("Text").setStyle(t2d::TextStyle::Bold);
    t2d::ResourceManager::getText("Text").setColor(t2d::Color::Magenta);
    t2d::ResourceManager::getText("Text").setPosition(screenWidth / 4.0f, screenHeight / 2.0f);
    t2d::ResourceManager::getText("Text").setString("Hello World");

    // Sprite
    t2d::ResourceManager::createSprite("RedPlayer", "Sprites/RedPlayer.png");
    t2d::ResourceManager::getSprite("RedPlayer").setPosition(screenWidth / 4.0f, screenHeight / 2.0f);

    while (gameState != t2d::GameState::QUIT)
    {
        float delta = _clock.restart().asSeconds();

        while (_window.pollEvent())
        {
            if(t2d::Keyboard::keyPressed(t2d::Keyboard::Escape))
            {
                gameState = t2d::GameState::QUIT;
            }
        }

        if (t2d::Keyboard::isKeyPressed(t2d::Keyboard::D))
        {
            t2d::ResourceManager::getSprite("RedPlayer").translate(400 * delta, 0.0f);
        }
        if (t2d::Keyboard::isKeyPressed(t2d::Keyboard::A))
        {
            t2d::ResourceManager::getSprite("RedPlayer").translate(-400 * delta, 0.0f);
        }
        if (t2d::Keyboard::isKeyPressed(t2d::Keyboard::S))
        {
            t2d::ResourceManager::getSprite("RedPlayer").translate(0.0f, 400 * delta);
        }
        if (t2d::Keyboard::isKeyPressed(t2d::Keyboard::W))
        {
            t2d::ResourceManager::getSprite("RedPlayer").translate(0.0f, -400 * delta);
        }

        _window.clear(t2d::Color(150, 150, 5, 255));
        _window.draw(t2d::ResourceManager::getSprite("RedPlayer"));
        _window.draw(t2d::ResourceManager::getText("Text"));
        _window.display();
    }

    return 0;
}
EN

回答 1

Code Review用户

发布于 2018-01-15 18:51:13

就我个人而言,我认为在这个阶段抽象SFML没有任何好处。一般来说,我只看到两种情况,即抽象这样一个基本库确实是有意义的,这是为了:

  1. 如果你想要完全测试你的代码。在这种情况下,您需要能够与“系统”并因此与SFML分离。
  2. 如果你的引擎已经发展到一个阶段,它不仅是一个廉价的技术演示,实际上是一些真实的东西,用于一些真正的游戏。只有这样才有意义去思考,是否有必要重构代码库以允许不同的“后端”。

此外,选项2几乎不可能干净利落地完成,因为所有的框架都提供了不同的功能集,并且在它们之间切换,上面只有一个API,并不能真正发挥作用,并且限制了所述库所使用的特性集。

至于您的代码和问题,SFML将字体和文本、纹理和精灵、声音和缓冲区等分割开来是有原因的。关键是您有大量的资源(字体、纹理、声音缓冲区)和一个轻的“实例”对象(文本、精灵、声音)。这样,您就可以随意移动、复制、操作轻量级实例,而不会在性能上遇到任何问题,而重资源需要加载一次,然后只要轻型实例正在使用,就需要继续运行。

您的资源管理器本身不应该保留文本对象或精灵,而应该只处理大量的资源,并确保只要使用它们,它们就能存活。我建议大家看看托尔资源管理 well和Thor,因为它是SFML的一个很好的补充。

如何存储文本或精灵取决于你,并取决于游戏的类型。对于大多数简单的游戏,直接将它们保存在游戏状态类中就足够了,如果您需要很多,那么只需使用std::vector,但是要记住用过的容器的优点和局限性。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/144306

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档