记录一些阅读 «SFML Game Development» «SFML Game Development By Example» 等的样板代码, 以及做些笔记.

主循环

void Application::run()
{
	sf::Clock clock;
	sf::Time timeSinceLastUpdate = sf::Time::Zero;
	sf::Time timePerFrame = sf::seconds(1.f/60.f);
	while (mWindow.isOpen())
	{
		sf::Time dt = clock.restart();	// dt: deltaTime 两次循环时间差
		timeSinceLastUpdate += dt;	// 游戏世界中, 两帧之间的时间差
		while (timeSinceLastUpdate > timePerFrame)
		{
			timeSinceLastUpdate -= timePerFrame;
			processInput();	// 处理用户输入(比如键盘鼠标窗口)
			update(timePerFrame);
			if (mStateStack.isEmpty())
				mWindow.close();
		}
		updateStatistics(dt);	// 更新 FPS 等信息
		render();	// 渲染
	}
}
// 参考: http://sshpark.com.cn/2019/06/05/用C++和SFML写游戏-Game类的创建(2)/

代码命名规则

类成员变量以 m 开头, 如: mWindow, mIsMovingUp. 类成员函数(方法)以小写开头: update(), 类静态变量及静态函数以大写开头: PlayerSpeed, 和 Java 驼峰命名一致.

资源加载

资源加载一般在程序入口 Application (也叫 Game) 类初始化时一同初始化.

// Application.h
class Application
{
	// 省略一些函数以及成员变量
	private:
		sf::RenderWindow mWindow;	// 窗口
		TextureHolder mTextures;	// 素材加载
	  	FontHolder mFonts;	// 字体加载
};
// Application.cpp
Application::Application()
: mWindow(sf::VideoMode(1024, 768), "Graphics", sf::Style::Close)
, mTextures() // 素材资源初始化
, mFonts() // 素材资源初始化
{
	mWindow.setKeyRepeatEnabled(false);
	mWindow.setFramerateLimit(60);
	mFonts.load(Fonts::Main, "Media/Sansation.ttf"); // 素材加载
	mTextures.load(Textures::TitleScreen, "Media/Textures/TitleScreen.png"); // 素材加载
	mTextures.load(Textures::Buttons, "Media/Textures/Buttons.png");// 素材加载
}

TextureHolder, FontHolder 在 ResourceHolder.hpp 中定义:

// ResourceHolder.hpp
template <typename Resource, typename Identifier>
class ResourceHolder
{
	public:
		template <typename Parameter>
		void load(Identifier id, const std::string& filename, const Parameter& secondParam);
		Resource& get(Identifier id);
		const Resource& get(Identifier id) const;
	private:
		std::map<Identifier, std::unique_ptr<Resource>>	mResourceMap;
};

typedef ResourceHolder<sf::Texture, Textures::ID> TextureHolder; // Textures 是命名空间, ID 是枚举类型
typedef ResourceHolder<sf::Font, Fonts::ID> FontHolder;

namespace Textures
{
	enum ID
	{
		Entities,
		Jungle,
		TitleScreen,
		Buttons,
		Explosion,
		Particle,
		FinishLine,
	};
}

在 Application 初始化时候, 调用 TextureHolder (也就是 ResourceHolder) 的 load 方法加载素材并存入 mResourceMap:

mTextures.load(Textures::TitleScreen, "Media/Textures/TitleScreen.png");

通过 mTextures.get(Textures::TitleScreen) 调用素材.