png支持

This commit is contained in:
ArchZer0
2026-08-17 10:26:27 +08:00
parent 07aeced2e4
commit 63d97f058a
25 changed files with 893 additions and 261 deletions
+111 -44
View File
@@ -10,6 +10,70 @@
#include <boundard.hpp>
namespace boundard {
namespace {
std::shared_ptr<Actor> create_actor(const ActorConfig& actor_config, Game& game,
BehaviorRegistry& behaviors) {
auto mesh = std::make_shared<Mesh>();
if (actor_config.mesh.shape == "quad") {
*mesh = Mesh::quad();
} else {
// 当前渲染器只提供 quad;未知形状先按 quad 创建,便于后续扩展。
*mesh = Mesh::quad();
}
mesh->set_color(actor_config.mesh.color);
mesh->texture = actor_config.mesh.texture;
auto actor = std::make_shared<Actor>(actor_config.name, game, mesh);
actor->set_position(actor_config.position);
actor->set_facing(actor_config.facing);
if (!actor_config.init_function.empty()) {
auto handler = behaviors.init(actor_config.init_function);
if (handler) {
actor->set_init_handler(std::move(handler));
} else {
std::fprintf(stderr, "未找到 init 处理函数: %s\n",
actor_config.init_function.c_str());
}
}
if (!actor_config.tick_function.empty()) {
auto handler = behaviors.tick(actor_config.tick_function);
if (handler) {
actor->set_tick_handler(std::move(handler));
} else {
std::fprintf(stderr, "未找到 tick 处理函数: %s\n",
actor_config.tick_function.c_str());
}
}
return actor;
}
std::shared_ptr<Scene> build_scene(const SceneConfig& scene, Game& game,
BehaviorRegistry& behaviors) {
auto runtime_scene = std::make_shared<Scene>(scene.name);
for (const ActorConfig& actor_config : scene.actors) {
auto actor = create_actor(actor_config, game, behaviors);
runtime_scene->add_actor(std::move(actor));
}
return runtime_scene;
}
const SceneConfig* find_scene(const std::vector<SceneConfig>& scenes,
const std::string& name) {
for (const SceneConfig& scene : scenes) {
if (scene.name == name) {
return &scene;
}
}
return nullptr;
}
} // namespace
int run_engine(int argc, char** argv, const char* default_config_path) {
std::string config_path = default_config_path != nullptr ? default_config_path : "config.ceg";
@@ -27,49 +91,31 @@ int run_engine(int argc, char** argv, const char* default_config_path) {
Game& game = Game::getInstance();
BehaviorRegistry& behaviors = BehaviorRegistry::getInstance();
std::vector<std::shared_ptr<Actor>> actor_storage;
std::vector<Actor*> actors;
for (const ActorConfig& actor_config : config.actors) {
auto mesh = std::make_shared<Mesh>();
if (actor_config.mesh.shape == "quad") {
*mesh = Mesh::quad();
} else {
// 当前渲染器只提供 quad;未知形状先按 quad 创建,便于后续扩展。
*mesh = Mesh::quad();
}
mesh->set_color(actor_config.mesh.color);
auto actor = std::make_shared<Actor>(actor_config.name, game, mesh);
actor->set_position(actor_config.position);
actor->set_facing(actor_config.facing);
if (!actor_config.init_function.empty()) {
auto handler = behaviors.init(actor_config.init_function);
if (handler) {
actor->set_init_handler(std::move(handler));
} else {
std::fprintf(stderr, "未找到 init 处理函数: %s\n",
actor_config.init_function.c_str());
}
}
if (!actor_config.tick_function.empty()) {
auto handler = behaviors.tick(actor_config.tick_function);
if (handler) {
actor->set_tick_handler(std::move(handler));
} else {
std::fprintf(stderr, "未找到 tick 处理函数: %s\n",
actor_config.tick_function.c_str());
}
}
actors.push_back(actor.get());
actor_storage.push_back(std::move(actor));
std::vector<SceneConfig> scenes = config.scenes;
if (scenes.empty() && !config.actors.empty()) {
SceneConfig legacy;
legacy.name = "default";
legacy.path = config_path;
legacy.actors = config.actors;
scenes.push_back(std::move(legacy));
}
for (auto& actor : actor_storage) {
actor->initialize();
std::string start_scene = config.start_scene;
if (start_scene.empty() && !scenes.empty()) {
start_scene = scenes.front().name;
}
const SceneConfig* active_scene = find_scene(scenes, start_scene);
if (active_scene == nullptr && !scenes.empty()) {
active_scene = &scenes.front();
std::fprintf(stderr, "未找到起始场景 %s,已回退到 %s\n", start_scene.c_str(),
active_scene->name.c_str());
}
// 把配置文件中的场景包装为运行时 Scene,并注册到 Game。
for (const SceneConfig& scene_config : scenes) {
std::shared_ptr<Scene> runtime_scene = build_scene(scene_config, game, behaviors);
game.add_scene(std::move(runtime_scene));
}
render::RenderLoop render_loop;
@@ -87,7 +133,22 @@ int run_engine(int argc, char** argv, const char* default_config_path) {
render_loop.input().add_action("quit");
render_loop.input().bind_key("quit", 256);
render_loop.set_actors(std::move(actors));
auto apply_scene = [&](const std::string& name) {
std::shared_ptr<Scene> scene = game.scene(name);
if (scene == nullptr) {
std::fprintf(stderr, "未找到场景: %s\n", name.c_str());
return;
}
scene->initialize();
game.set_current_scene(scene);
render_loop.set_actors(scene->actors());
};
if (active_scene != nullptr) {
apply_scene(active_scene->name);
}
render_loop.start(config.window.width, config.window.height,
config.window.title.c_str());
@@ -98,12 +159,18 @@ int run_engine(int argc, char** argv, const char* default_config_path) {
break;
}
const std::string requested_scene = game.take_scene_request();
if (!requested_scene.empty() && requested_scene != game.current_scene_name()) {
apply_scene(requested_scene);
}
const auto now = std::chrono::steady_clock::now();
const float dt = std::chrono::duration<float>(now - last).count();
last = now;
for (auto& actor : actor_storage) {
actor->process(dt, render_loop.input());
std::shared_ptr<Scene> scene = game.current_scene();
if (scene != nullptr) {
scene->process(dt, render_loop.input());
}
render_loop.input().end_frame();