我不知道如何使用 SDL2 管理我的 类 结构
I don't know how to manage my classes sturctures with SDL2
我尝试用 SDL-2 创建一些 C++ "rogue-like" 游戏。为此,我遵循了 Lazy foo 的教程来了解如何使用 SDL。
我学了3年C++/C#,现在学的是项目管理,没有更多的IT课程了...
这是代码的 github:https://github.com/Paingouin/Roguelike-SDL2-train/tree/master/
我创建了 2 class:LTexture
来帮助管理图片的加载和渲染,Glyph
来管理 animation/scaling 和图片的定位。 .
现在,我想创建一个由 Glyph
对象组成的实体 class,我将用它来表示墙、怪物、物品等...但是,我认为如果我这样做,我会使用太多内存...
也许我应该通过初始化字形指针数组并将其关联到我的实体对象来使用聚合...我不知道,我迷路了...
你能帮帮我吗?而且,您有什么提示或建议可以帮助我正确地组织结构吗?
actually your question can be answered without reffering directly to SDL and same issue may arise with any library(like sfml) and the solution is all about the same:
the answer is the singleton design pattern
since your texture why i say singleton?
let's talk about the wall tile. you might have thousands or even more wall tiles
all have the same texture, do you really want to load it time and time agan per each wall?不。 it's the same texture, you want to have one instance of each given texture, even more: you can save resource work if you use sprite sheet that contains EVERYTHING or have let's say 3 sheets: here's an example in sfml though the idea should be the same in SDL.
https://en.wikipedia.org/wiki/Singleton_pattern
here's an sfml implementation but the idea behind it should be clear and easy to immitate:
class Resources {
sf::Clock m_clock; //holds clock
sf::Texture m_soma,m_lvl,m_enemies; //holds hero,lvl &enemies textures respectively
sf::Font m_font; //holds game font
Resources();
public:
~Resources() {}
Resources(const Resources &) = delete;
Resources& operator=(const Resources &) = delete;
static Resources& instance();
sf::Texture& texture();
sf::Texture& lvlTexture();
sf::Texture& Enemies();
sf::Clock& clock();
sf::Font & Font();
};
cpp file: notice i could use a vector instead of 3 textures
Resources::Resources()
{
//loading textures(hero,lvls,enemies)
if (!m_soma.loadFromFile("..\resources\sprites\soma.png"))
{
std::cerr << "problem loading texture\n";
throw ResourceExceptions("couldn't load player sprites!: must have ..\resources\sprites\soma.png");
}
if (!m_lvl.loadFromFile("..\resources\sprites\lv.png"))
{
std::cerr << "problem loading texture\n";
throw ResourceExceptions("couldn't load level sprites!: must have ..\resources\sprites\lv.png");
}
if (!m_enemies.loadFromFile("..\resources\sprites\enemies.png"))
{
std::cerr << "problem loading texture\n";
throw ResourceExceptions("couldn't load enemies sprites!: must have ..\resources\sprites\enemies.png");
}
//loading font once
if (!m_font.loadFromFile("..\resources\font\gothic.otf"))
{
std::cerr << "problem loading font\n";
throw ResourceExceptions("couldn't load game Font: must have ..\resources\font\gothic.otf");
}
}
Resources & Resources::instance()
{
static Resources resource;
return resource;
}
sf::Texture & Resources::texture()
{
return m_soma;
}
sf::Texture & Resources::lvlTexture()
{
return m_lvl;
}
sf::Texture & Resources::Enemies()
{
return m_enemies;
}
sf::Clock & Resources::clock()
{
return m_clock;
}
sf::Font & Resources::Font()
{
return m_font;
}
例如。 of usage would be:
m_sprite.setTexture(Resources::instance().texture());
//---------------------------------------
same idea can be applied anywhere, even more, if by a chance you'll deal with 3d objects and will render those you'll find that singleton isn't even enough there and you can refer to the "flyweight" design patters
overall i suggest you to read two things:
gameprogrammingpatterns.com
and the legendary book: Design Patterns: Elements of Reusable Object-Oriented Software
there're several code issues that exist in your code:
例如。 the switch case on movement. ask yourself this "what happens if suddenly i want to add an extra action?" "what if for eg. i want it to behave differently according to the previous movement?" your approach will carry you to extensive and LONG switch cases. both will show you ways that will allow you to change code more easily
我尝试用 SDL-2 创建一些 C++ "rogue-like" 游戏。为此,我遵循了 Lazy foo 的教程来了解如何使用 SDL。
我学了3年C++/C#,现在学的是项目管理,没有更多的IT课程了...
这是代码的 github:https://github.com/Paingouin/Roguelike-SDL2-train/tree/master/
我创建了 2 class:LTexture
来帮助管理图片的加载和渲染,Glyph
来管理 animation/scaling 和图片的定位。 .
现在,我想创建一个由 Glyph
对象组成的实体 class,我将用它来表示墙、怪物、物品等...但是,我认为如果我这样做,我会使用太多内存...
也许我应该通过初始化字形指针数组并将其关联到我的实体对象来使用聚合...我不知道,我迷路了...
你能帮帮我吗?而且,您有什么提示或建议可以帮助我正确地组织结构吗?
actually your question can be answered without reffering directly to SDL and same issue may arise with any library(like sfml) and the solution is all about the same: the answer is the singleton design pattern since your texture why i say singleton? let's talk about the wall tile. you might have thousands or even more wall tiles all have the same texture, do you really want to load it time and time agan per each wall?不。 it's the same texture, you want to have one instance of each given texture, even more: you can save resource work if you use sprite sheet that contains EVERYTHING or have let's say 3 sheets: here's an example in sfml though the idea should be the same in SDL. https://en.wikipedia.org/wiki/Singleton_pattern
here's an sfml implementation but the idea behind it should be clear and easy to immitate:
class Resources {
sf::Clock m_clock; //holds clock
sf::Texture m_soma,m_lvl,m_enemies; //holds hero,lvl &enemies textures respectively
sf::Font m_font; //holds game font
Resources();
public:
~Resources() {}
Resources(const Resources &) = delete;
Resources& operator=(const Resources &) = delete;
static Resources& instance();
sf::Texture& texture();
sf::Texture& lvlTexture();
sf::Texture& Enemies();
sf::Clock& clock();
sf::Font & Font();
};
cpp file: notice i could use a vector instead of 3 textures
Resources::Resources()
{
//loading textures(hero,lvls,enemies)
if (!m_soma.loadFromFile("..\resources\sprites\soma.png"))
{
std::cerr << "problem loading texture\n";
throw ResourceExceptions("couldn't load player sprites!: must have ..\resources\sprites\soma.png");
}
if (!m_lvl.loadFromFile("..\resources\sprites\lv.png"))
{
std::cerr << "problem loading texture\n";
throw ResourceExceptions("couldn't load level sprites!: must have ..\resources\sprites\lv.png");
}
if (!m_enemies.loadFromFile("..\resources\sprites\enemies.png"))
{
std::cerr << "problem loading texture\n";
throw ResourceExceptions("couldn't load enemies sprites!: must have ..\resources\sprites\enemies.png");
}
//loading font once
if (!m_font.loadFromFile("..\resources\font\gothic.otf"))
{
std::cerr << "problem loading font\n";
throw ResourceExceptions("couldn't load game Font: must have ..\resources\font\gothic.otf");
}
}
Resources & Resources::instance()
{
static Resources resource;
return resource;
}
sf::Texture & Resources::texture()
{
return m_soma;
}
sf::Texture & Resources::lvlTexture()
{
return m_lvl;
}
sf::Texture & Resources::Enemies()
{
return m_enemies;
}
sf::Clock & Resources::clock()
{
return m_clock;
}
sf::Font & Resources::Font()
{
return m_font;
}
例如。 of usage would be: m_sprite.setTexture(Resources::instance().texture());
//---------------------------------------
same idea can be applied anywhere, even more, if by a chance you'll deal with 3d objects and will render those you'll find that singleton isn't even enough there and you can refer to the "flyweight" design patters overall i suggest you to read two things: gameprogrammingpatterns.com and the legendary book: Design Patterns: Elements of Reusable Object-Oriented Software
there're several code issues that exist in your code: 例如。 the switch case on movement. ask yourself this "what happens if suddenly i want to add an extra action?" "what if for eg. i want it to behave differently according to the previous movement?" your approach will carry you to extensive and LONG switch cases. both will show you ways that will allow you to change code more easily