This commit is contained in:
wcjbr
2026-08-16 13:32:51 +08:00
parent 9b5d76a6ac
commit d36fd6d2ee
25 changed files with 2836 additions and 4 deletions
+117
View File
@@ -0,0 +1,117 @@
#include <engine.hpp>
#include <chrono>
#include <cstdio>
#include <memory>
#include <string>
#include <thread>
#include <vector>
#include <openceg.hpp>
namespace openceg {
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";
if (argc > 1) {
config_path = argv[1];
}
ConfigLoader loader;
if (!loader.load(config_path)) {
std::fprintf(stderr, "%s\n", loader.last_error().c_str());
return 1;
}
const GameConfig& config = loader.config();
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));
}
for (auto& actor : actor_storage) {
actor->initialize();
}
render::RenderLoop render_loop;
for (const InputBindingConfig& binding : config.input_bindings) {
render_loop.input().add_action(binding.action);
for (int key : binding.keys) {
render_loop.input().bind_key(binding.action, key);
}
for (int button : binding.mouse_buttons) {
render_loop.input().bind_mouse_button(binding.action, button);
}
}
// 引擎级默认退出动作,不包含具体游戏逻辑。
render_loop.input().add_action("quit");
render_loop.input().bind_key("quit", 256);
render_loop.set_actors(std::move(actors));
render_loop.start(config.window.width, config.window.height,
config.window.title.c_str());
auto last = std::chrono::steady_clock::now();
while (!render_loop.should_close()) {
render_loop.poll_events();
if (render_loop.input().is_action_just_pressed("quit")) {
break;
}
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());
}
render_loop.input().end_frame();
std::this_thread::sleep_for(std::chrono::milliseconds(2));
}
render_loop.stop();
return 0;
}
} // namespace openceg