念一叨

NiVz

上图为美术绘制的「击中音符」的动效。

仍然是游戏创作的课程项目,这次是音游。

就像上一篇所说的,我这次实现并应用了一套更灵活的框架。 它支持基本的场景调度,这允许我将不同场景的逻辑与元素分别写在不同的文件里,例如:

// Scenes/level.cpp
// Register the level-choosing scene.
Scene level_scene("level", &level_init, {
	{ WM_KEYDOWN, { (EventHandler::Handler)&level_keydown } },
	{ WM_PAINT, { (EventHandler::Handler)&level_paint } },
});
// main.cpp
using namespace Win32GameEngine;
LRESULT init(HWND hWnd) {
	// ...
	// Switch to the above-defined scene on start.
	Scene::switchTo("level", hWnd, nullptr);
	return 0;
}

开始选歌菜单。

这样我就能把更多时间花在具体的游戏逻辑的开发上去。 下面是一段游戏内主要游玩部分的绘制代码:

// Scenes/play.cpp
Bitmap background((wstring(textures_dir) + L"background.bmp").c_str());
// Define the content area.
PureColor vinner(0, { 512, 192 });
LRESULT paint(HWND hWnd, WPARAM, LPARAM) {
	PAINTSTRUCT ps;
	HDC hdc = BeginPaint(hWnd, &ps);
	background.paintOn(vscreen.hdc, { 0, 0 });
	background.paintOn(vinner.hdc, { -64, -84 });
	// Get the current time since level (music track) started.
	LONGLONG const progress = getCurrentProgress();
	// And then render the note tracks regarding the process.
	tr_top.paint(vinner.hdc, progress);
	tr_bottom.paint(vinner.hdc, progress);
	vinner.paintOn(vscreen.hdc, { 64, 84 });
	// Lastly, render the HP bar.
	RECT health_bar{ 0, 0, (long)(vwidth * health / 100.0), 8 };
	FillRect(vscreen.hdc, &health_bar, (HBRUSH)GetStockObject(WHITE_BRUSH));
	vscreen.paintOn(hdc, { 0, 0 });
	EndPaint(hWnd, &ps);
	return 0;
}

最后的游戏界面看起来像这样。

虽然肉眼可见地还未成功与 Win32 API 解耦,但整体的框架设计已经在朝着预想的方向发展了! 现在的游戏框架本体已经做到了与应用逻辑解耦。 这意味着后面的游创作业都可以用此框架来开发!

游戏框架游戏本体的项目均已上传至 GitHub,欢迎自行下载编译。

注意:后者的工程依赖于前者,下载后请手动索引。