module; #include #include #include #include export module game.game; import core.drawing.sprite; import core.drawing.tile_map; import core.drawing.tile_set; import core.engine; import core.render_server; import wrappers.sdl; import wrappers.sdl_image; export namespace game { class Game { // Whether this class is currently instantiated (to prevent multiple instances) static bool instantiated_; // Reference to the engine core::Engine& engine_; // Sprites for testing core::Sprite player_sprite_; std::vector sprites_; // Tile set and tile map (TODO: tile set should be moved to resource manager in engine) core::TileSet tile_set_; core::TileMap tile_map_; // Private constructor explicit Game(core::Engine& engine) : engine_(engine), player_sprite_{ core::Sprite::create_from_texture( engine_.get_render_server(), "assets/sprites/neocat_64.png", std::nullopt, sdl::FPoint{0, 0}, sdl::FPoint{-32, -32} ) }, tile_set_{ core::TileSet::create_from_texture( engine_.get_render_server(), "assets/tilesets/terrain.png", 32, { // Tile 0: No tile {0, 0}, // Tile 1: Actual first tile in the texture {0, 0}, {1, 0}, {2, 0}, {3, 0}, } ) }, tile_map_(0, 32, 16, 12, {50, 50}) { // Initialize tile map with example data for (auto x = 0; x < 10; x++) { for (auto y = 0; y < 10; y++) { const auto tile_index = 2 + (x + y) % 2; tile_map_.set_tile(x, y, tile_index); } } } public: Game() = delete; // No copy or move operations because we have a reference to the engine Game(const Game&) = delete; Game& operator=(const Game&) = delete; Game(Game&&) = delete; Game& operator=(Game&&) = delete; ~Game() { instantiated_ = false; } static std::unique_ptr create(core::Engine& engine) { // Prevent the class from being instantiated multiple times assert(!instantiated_); return std::unique_ptr{ new Game(engine) }; } // Handles an SDL event. Returns true if the event has been handled. bool handle_event(const sdl::Event* event) { if (event->type == sdl::EventType::MouseMotion) { player_sprite_.set_position({event->motion.x, event->motion.y}); return true; } if (event->type == sdl::EventType::MouseButtonUp) { sprites_.push_back( core::Sprite::create_from_texture( engine_.get_render_server(), "assets/sprites/neofox_64.png", std::nullopt, sdl::FPoint{event->motion.x, event->motion.y}, sdl::FPoint{-32, -32} ) ); return true; } return false; } void update() { } void render() const { const auto& render_server = engine_.get_render_server(); render_server.start_frame(); // Render tilemap tile_map_.draw(render_server, tile_set_); // Render sprites for (const core::Sprite& sprite : sprites_) { sprite.draw(render_server); } player_sprite_.draw(render_server); render_server.finish_frame(); } void shutdown() { } }; bool Game::instantiated_ = false; }