diff options
-rw-r--r-- | Doxyfile | 2 | ||||
-rw-r--r-- | game/PreviewScene.cpp | 22 | ||||
-rw-r--r-- | game/background/StartSubScene.cpp | 4 | ||||
-rw-r--r-- | game/missile/SpawnEvent.h | 5 | ||||
-rw-r--r-- | game/preview/NpcScript.cpp | 8 | ||||
-rw-r--r-- | game/preview/NpcSubScene.cpp | 4 | ||||
-rw-r--r-- | game/preview/PrevPlayerScript.cpp | 53 | ||||
-rw-r--r-- | game/preview/PrevPlayerScript.h | 17 | ||||
-rw-r--r-- | game/preview/PrevPlayerSubScene.cpp | 8 | ||||
-rw-r--r-- | src/crepe/api/Asset.h | 4 | ||||
-rw-r--r-- | src/crepe/api/Config.h | 27 | ||||
-rw-r--r-- | src/doc/feature/bgm.dox | 22 | ||||
-rw-r--r-- | src/doc/feature/config.dox | 61 | ||||
-rw-r--r-- | src/doc/feature/gameobject.dox | 4 | ||||
-rw-r--r-- | src/doc/feature/scene.dox | 15 | ||||
-rw-r--r-- | src/doc/feature/script.dox | 48 | ||||
-rw-r--r-- | src/doc/feature/script_ecs.dox | 57 | ||||
-rw-r--r-- | src/doc/feature/sfx.dox | 24 | ||||
-rw-r--r-- | src/doc/features.dox | 55 | ||||
-rw-r--r-- | src/doc/index.dox | 9 | ||||
-rw-r--r-- | src/doc/layout.xml | 6 | ||||
-rw-r--r-- | src/doc/style.css | 27 | ||||
-rw-r--r-- | src/test/InputTest.cpp | 30 |
23 files changed, 416 insertions, 96 deletions
@@ -20,6 +20,8 @@ TAB_SIZE = 2 HTML_INDEX_NUM_ENTRIES = 999 HTML_EXTRA_STYLESHEET = src/doc/style.css SHOW_HEADERFILE = NO +DISABLE_INDEX = NO +GENERATE_TREEVIEW = NO REPEAT_BRIEF = NO diff --git a/game/PreviewScene.cpp b/game/PreviewScene.cpp index 14a5560..bc28192 100644 --- a/game/PreviewScene.cpp +++ b/game/PreviewScene.cpp @@ -1,7 +1,10 @@ #include "PreviewScene.h" #include "Config.h" -#include "background/BackgroundSubScene.h" +#include "background/AquariumSubScene.h" +#include "background/ForestSubScene.h" +#include "background/HallwaySubScene.h" +#include "background/StartSubScene.h" #include "hud/HudScript.h" #include "hud/HudSubScene.h" #include "hud/SpeedScript.h" @@ -40,13 +43,26 @@ using namespace std; void PreviewScene::load_scene() { - BackgroundSubScene background(*this); + StartSubScene start; + HallwaySubScene hallway; + ForestSubScene forest; + AquariumSubScene aquarium; + + float begin_x = 400; + + begin_x = start.create(*this, begin_x); + + begin_x = hallway.create(*this, begin_x, 1, Color::YELLOW); + + begin_x = aquarium.create(*this, begin_x); + + begin_x = hallway.create(*this, begin_x, 2, Color::GREEN); GameObject camera = new_object("camera", "camera", vec2(650, 0)); camera.add_component<Camera>( ivec2(990, 720), vec2(VIEWPORT_X, VIEWPORT_Y), Camera::Data { - .bg_color = Color::RED, + .bg_color = Color::BLACK, } ); diff --git a/game/background/StartSubScene.cpp b/game/background/StartSubScene.cpp index d2d30ea..ba80517 100644 --- a/game/background/StartSubScene.cpp +++ b/game/background/StartSubScene.cpp @@ -296,7 +296,7 @@ void StartSubScene::create_wall_fragments(crepe::Scene & scn, float begin_x) { frag_5_sprite.active = false; Rigidbody & frag_5_rb = frag_5.add_component<Rigidbody>(Rigidbody::Data { .gravity_scale = 1.0, - .linear_velocity = vec2(600, -800), + .linear_velocity = vec2(600, -500), .linear_velocity_coefficient = vec2(0.25, 0.15), .angular_velocity = 100, .angular_velocity_coefficient = 0.55, @@ -440,7 +440,7 @@ void StartSubScene::create_wall_fragments(crepe::Scene & scn, float begin_x) { frag_11_sprite.active = false; Rigidbody & frag_11_rb = frag_11.add_component<Rigidbody>(Rigidbody::Data { .gravity_scale = 1.0, - .linear_velocity = vec2(600, -800), + .linear_velocity = vec2(600, -400), .linear_velocity_coefficient = vec2(0.3, 0.3), .angular_velocity = 200, .angular_velocity_coefficient = 0.55, diff --git a/game/missile/SpawnEvent.h b/game/missile/SpawnEvent.h index 3b9638c..84b1987 100644 --- a/game/missile/SpawnEvent.h +++ b/game/missile/SpawnEvent.h @@ -10,9 +10,8 @@ struct MissileSpawnEvent : public crepe::Event {}; class MissileSpawnEventHandler : public crepe::Script { private: static constexpr int MISSILE_OFFSET = VIEWPORT_X; - static constexpr int RANGE = GAME_HEIGHT / 4.5; - static constexpr int MIN_RANGE = -RANGE; - static constexpr int MAX_RANGE = RANGE; + static constexpr int MIN_RANGE = -150; + static constexpr int MAX_RANGE = 150; public: void init(); diff --git a/game/preview/NpcScript.cpp b/game/preview/NpcScript.cpp index 5a93c2b..86117d4 100644 --- a/game/preview/NpcScript.cpp +++ b/game/preview/NpcScript.cpp @@ -9,7 +9,7 @@ using namespace crepe; void NpcScript::fixed_update(duration_t dt) { auto & rb = this->get_component<Rigidbody>(); - auto & npc = this->get_component<Sprite>(); + auto npc = this->get_components<Sprite>(); auto & transform = this->get_component<Transform>(); if (transform.position.x < 200) { @@ -20,8 +20,10 @@ void NpcScript::fixed_update(duration_t dt) { } if (rb.data.linear_velocity.x < 0) { - npc.data.flip = {true, false}; + npc.front().get().data.flip = {true, false}; + npc.back().get().data.flip = {true, false}; } else { - npc.data.flip = {false, false}; + npc.front().get().data.flip = {false, false}; + npc.back().get().data.flip = {false, false}; } } diff --git a/game/preview/NpcSubScene.cpp b/game/preview/NpcSubScene.cpp index c9ab5b6..5ededb6 100644 --- a/game/preview/NpcSubScene.cpp +++ b/game/preview/NpcSubScene.cpp @@ -49,7 +49,7 @@ NpcSubScene::NpcSubScene(Scene & scn) { .looping = true, } ); - npc.add_component<BoxCollider>(vec2 {50, 50}); + npc.add_component<BoxCollider>(vec2 {40, 50}); npc.add_component<Rigidbody>(Rigidbody::Data { .mass = 10, @@ -57,7 +57,7 @@ NpcSubScene::NpcSubScene(Scene & scn) { .body_type = Rigidbody::BodyType::DYNAMIC, .linear_velocity = {-50, 0}, //.max_linear_velocity = 40, - .collision_layers = {COLL_LAY_BOT_TOP, COLL_LAY_PLAYER, 100}, + .collision_layers = {COLL_LAY_BOT_TOP, 100}, .collision_layer = COLL_LAY_PLAYER, }); diff --git a/game/preview/PrevPlayerScript.cpp b/game/preview/PrevPlayerScript.cpp index fce5c5a..ae25dad 100644 --- a/game/preview/PrevPlayerScript.cpp +++ b/game/preview/PrevPlayerScript.cpp @@ -21,10 +21,6 @@ bool PrevPlayerScript::key_pressed(const KeyPressEvent & ev) { this->body->data.flip = {false, false}; this->head->data.flip = {false, false}; break; - - case Keycode::SPACE: - this->get_component<Rigidbody>().data.linear_velocity.y = -move_speed; - break; case Keycode::D0: this->body_anim->set_anim(0); this->head_anim->set_anim(0); @@ -70,13 +66,8 @@ bool PrevPlayerScript::key_pressed(const KeyPressEvent & ev) { this->head->data.position_offset -= 10; break; case Keycode::P: - this->get_component<AudioSource>().play(); - break; - case Keycode::Q: - this->get_components_by_name<Camera>("camera").front().get().data.zoom -= 0.01; - break; - case Keycode::E: - this->get_components_by_name<Camera>("camera").front().get().data.zoom += 0.01; + this->get_components_by_name<AudioSource>("background_music").front().get().active + = true; break; case Keycode::J: this->get_components_by_name<Transform>("camera").front().get().position.x @@ -104,6 +95,8 @@ bool PrevPlayerScript::key_pressed(const KeyPressEvent & ev) { } void PrevPlayerScript::init() { + this->rb = get_component<Rigidbody>(); + auto animations = this->get_components<Animator>(); body_anim = animations[0]; head_anim = animations[1]; @@ -115,12 +108,50 @@ void PrevPlayerScript::init() { subscribe<KeyPressEvent>([this](const KeyPressEvent & ev) -> bool { return this->key_pressed(ev); }); + subscribe<KeyPressEvent>([this](const KeyPressEvent & ev) -> bool { + if (ev.repeat) return false; + return this->on_key_down(ev); + }); + subscribe<KeyReleaseEvent>([this](const KeyReleaseEvent & ev) -> bool { + return this->on_key_up(ev); + }); }; void PrevPlayerScript::fixed_update(crepe::duration_t dt) { + if (this->get_key_state(Keycode::SPACE)) { + this->rb->add_force_linear( + vec2(0, -1) * (engine_gravity * PLAYER_GRAVITY_SCALE * dt.count()) + ); + } + auto & savemgr = this->get_save_manager(); const auto & pos = this->get_component<Transform>().position; savemgr.set("player_x", pos.x); savemgr.set("player_y", pos.y); }; + +bool PrevPlayerScript::on_key_down(const KeyPressEvent & ev) { + if (ev.key == Keycode::SPACE) { + const vec2 UP = {0, -1}; + this->help_kick(UP); + } + return false; +} + +bool PrevPlayerScript::on_key_up(const KeyReleaseEvent & ev) { + if (ev.key == Keycode::SPACE) { + const vec2 DOWN = {0, 1}; + this->help_kick(DOWN); + } + return false; +} + +void PrevPlayerScript::help_kick(const vec2 & direction) { + // softly "kick" the player (at start/end of flight) + vec2 & velocity = this->rb->data.linear_velocity; + float kick_amount = std::min( + velocity.length() * PLAYER_HELP_KICK_SCALE, engine_gravity * PLAYER_HELP_KICK_MAX + ); + velocity += direction * kick_amount; +} diff --git a/game/preview/PrevPlayerScript.h b/game/preview/PrevPlayerScript.h index cc3184e..ae66449 100644 --- a/game/preview/PrevPlayerScript.h +++ b/game/preview/PrevPlayerScript.h @@ -1,10 +1,10 @@ - +#include <crepe/api/Animator.h> +#include <crepe/api/Config.h> #include <crepe/api/Event.h> +#include <crepe/api/Rigidbody.h> #include <crepe/api/Script.h> -#include <crepe/util/OptionalRef.h> - -#include <crepe/api/Animator.h> #include <crepe/api/Sprite.h> +#include <crepe/util/OptionalRef.h> class PrevPlayerScript : public crepe::Script { private: @@ -20,4 +20,13 @@ private: void init(); void fixed_update(crepe::duration_t dt); bool key_pressed(const crepe::KeyPressEvent & ev); + +private: + bool on_key_down(const crepe::KeyPressEvent & ev); + bool on_key_up(const crepe::KeyReleaseEvent & ev); + void help_kick(const crepe::vec2 & direction); + +private: + float & engine_gravity = crepe::Config::get_instance().physics.gravity; + crepe::OptionalRef<crepe::Rigidbody> rb; }; diff --git a/game/preview/PrevPlayerSubScene.cpp b/game/preview/PrevPlayerSubScene.cpp index 9ff111c..074cfb4 100644 --- a/game/preview/PrevPlayerSubScene.cpp +++ b/game/preview/PrevPlayerSubScene.cpp @@ -76,6 +76,12 @@ PrevPlayerSubScene::PrevPlayerSubScene(Scene & scn) { .collision_layers = {COLL_LAY_BOT_TOP, 100}, .collision_layer = COLL_LAY_PLAYER, }); - player.add_component<BoxCollider>(vec2(50, 50)); + player.add_component<BoxCollider>(vec2(40, 50)); player.add_component<BehaviorScript>().set_script<PrevPlayerScript>(); + + GameObject music = scn.new_object("background_music", "background_music"); + AudioSource & audio = music.add_component<AudioSource>(Asset {"asset/music/level.ogg"}); + audio.loop = true; + audio.play_on_awake = true; + audio.active = false; } diff --git a/src/crepe/api/Asset.h b/src/crepe/api/Asset.h index bfd0ac7..d802e83 100644 --- a/src/crepe/api/Asset.h +++ b/src/crepe/api/Asset.h @@ -43,13 +43,13 @@ private: /** * \brief Locate asset path, or throw exception if it cannot be found * - * This function resolves asset locations relative to crepe::Config::root_pattern if it is + * This function resolves asset locations relative to Config::asset::root_pattern if it is * set and \p src is a relative path. If \p src is an absolute path, it is canonicalized. * This function only returns if the file can be found. * * \param src Arbitrary path to resource file * - * \returns \p src if crepe::Config::root_pattern is empty + * \returns \p src if Config::asset::root_pattern is empty * \returns Canonical path to \p src * * \throws std::runtime_error if root_pattern cannot be found diff --git a/src/crepe/api/Config.h b/src/crepe/api/Config.h index 65a8302..ab8bb59 100644 --- a/src/crepe/api/Config.h +++ b/src/crepe/api/Config.h @@ -2,25 +2,22 @@ #include <string> +#include "../types.h" #include "../util/Log.h" -#include "types.h" - namespace crepe { /** * \brief Global configuration interface * - * This class stores engine default settings. Properties on this class are only supposed to be - * modified *before* execution is handed over from the game programmer to the engine (i.e. the - * main loop is started). + * This struct stores both engine default settings and global configuration parameters. */ struct Config final { //! Retrieve handle to global Config instance static Config & get_instance(); //! Logging-related settings - struct { + struct log { // NOLINT /** * \brief Log level * @@ -28,7 +25,7 @@ struct Config final { */ Log::Level level = Log::Level::INFO; /** - * \brief Colored log output + * \brief Enable colored log output * * Enables log coloring using ANSI escape codes. */ @@ -36,7 +33,7 @@ struct Config final { } log; //! Save manager - struct { + struct savemgr { // NOLINT /** * \brief Save file location * @@ -46,8 +43,8 @@ struct Config final { std::string location = "save.crepe.db"; } savemgr; - //! physics-related settings - struct { + //! Physics-related settings + struct physics { // NOLINT /** * \brief gravity value of physics system * @@ -56,16 +53,16 @@ struct Config final { float gravity = 10; } physics; - //! default window settings - struct { - //! default screen size in pixels + //! Default window settings + struct window_settings { // NOLINT + //! Default window size (in pixels) ivec2 default_size = {1280, 720}; - //! default window title + //! Default window title std::string window_title = "crepe window"; } window_settings; //! Asset loading options - struct { + struct asset { // NOLINT /** * \brief Pattern to match for Asset base directory * diff --git a/src/doc/feature/bgm.dox b/src/doc/feature/bgm.dox new file mode 100644 index 0000000..968abb8 --- /dev/null +++ b/src/doc/feature/bgm.dox @@ -0,0 +1,22 @@ +// vim:ft=doxygen +namespace crepe { +/** + +\defgroup feature_bgm Playing background music +\ingroup feature +\brief Add background music to a scene using the AudioSource component + +This page shows how to implement background music using the AudioSource +effects. + +\see AudioSource + +\par Example + +\note This example assumes you already have a GameObject. If not, read +\"\ref feature_gameobject\" first. + +\todo Merge #60 + +*/ +} diff --git a/src/doc/feature/config.dox b/src/doc/feature/config.dox new file mode 100644 index 0000000..ae3a054 --- /dev/null +++ b/src/doc/feature/config.dox @@ -0,0 +1,61 @@ +// vim:ft=doxygen +namespace crepe { +/** + +\defgroup feature_config Engine configuration +\ingroup feature +\brief Configure default values and global options + +Default values and options that apply to the engine globally are read from a +singleton struct named Config. + +\see Config + +\par Example + +Configuration options may be set individually or by assigning a [designated +initializer list][desginit]. All of Config's members have default values and can +safely be omitted from initializer lists. + +[desginit]: https://en.cppreference.com/w/cpp/language/aggregate_initialization#Designated_initializers + +```cpp +#include <crepe/api/Config.h> + +int main() { + auto & config = crepe::Config::get_instance(); + + // Designated initializer list + config = { + // specify options here + }; + + // Reset default options + config = {}; + + // Set specific option + config.log.color = false; +} +``` + +\par Options + +\noop Display config properties in monospace font +\htmlonly +<style> +tr td:first-child { font-family: monospace; } +</style> +\endhtmlonly + +|Option|Description| +|-|-| +|\ref Config::asset::root_pattern ".asset.root_pattern"|\copybrief Config::asset::root_pattern| +|\ref Config::log::color ".log.color"|\copybrief Config::log::color| +|\ref Config::log::level ".log.level"|\copybrief Config::log::level| +|\ref Config::physics::gravity ".physics.gravity"|\copybrief Config::physics::gravity| +|\ref Config::savemgr::location ".savemgr.location"|\copybrief Config::savemgr::location| +|\ref Config::window_settings::default_size ".window_settings.default_size"|\copybrief Config::window_settings::default_size| +|\ref Config::window_settings::window_title ".window_settings.window_title"|\copybrief Config::window_settings::window_title| + +*/ +} diff --git a/src/doc/feature/gameobject.dox b/src/doc/feature/gameobject.dox index c561874..ac3927c 100644 --- a/src/doc/feature/gameobject.dox +++ b/src/doc/feature/gameobject.dox @@ -2,9 +2,9 @@ namespace crepe { /** -\defgroup feature_gameobject GameObjects +\defgroup feature_gameobject Entity basics \ingroup feature -\brief GameObject to create a Scene +\brief Building game entities using a GameObject GameObjects are the fundamental building blocks of a Scene. They represent entities in the game world and can have various components attached to them to define their diff --git a/src/doc/feature/scene.dox b/src/doc/feature/scene.dox index 4124e37..b680eec 100644 --- a/src/doc/feature/scene.dox +++ b/src/doc/feature/scene.dox @@ -40,31 +40,28 @@ added to the loop/scene manger via loop_mgr::add_scene<>(). The templated argument should define the concrete scene to be added. ```cpp -#include <crepe/api/LoopManager.h> -#include <crepe/api/GameObject.h> +#include <crepe/api/Engine.h> #include <crepe/api/Scene.h> -#include <crepe/types.h> using namespace crepe; class MyScene : public Scene { public: void load_scene() { - ComponentManager & mgr = this->component_manager; - GameObject object1 = mgr.new_object("object1", "tag_my_scene", vec2{0, 0}, 0, 1); - GameObject object2 = mgr.new_object("object2", "tag_my_scene", vec2{1, 0}, 0, 1); + GameObject object1 = new_object("object1", "tag_my_scene", vec2{0, 0}, 0, 1); + GameObject object2 = new_object("object2", "tag_my_scene", vec2{1, 0}, 0, 1); } string get_name() const { return "my_scene"; } }; int main() { - LoopManager loop_mgr; + Engine foo; // Add the scenes to the loop manager - loop_mgr.add_scene<MyScene>(); + foo.add_scene<MyScene>(); - loop_mgr.start(); + return foo.main(); } ``` diff --git a/src/doc/feature/script.dox b/src/doc/feature/script.dox index d25a63b..162b0f5 100644 --- a/src/doc/feature/script.dox +++ b/src/doc/feature/script.dox @@ -2,19 +2,14 @@ namespace crepe { /** -\defgroup feature_script Scripting +\defgroup feature_script Scripting basics \ingroup feature -\brief User-defined scripts for game objects +\brief Create a concrete Script and attach it to a GameObject Scripts can be used to implement game behavior, and allow arbitrary code to run as part of the game loop. Scripts are implemented as derivative classes of -Script, which are added to game objects using the BehaviorScript \ref Component -"component". - -\todo This section is incomplete: -- Utility functions to get components/events/etc inside script -- How to listen for events -- Extensions of script (keylistener) +Script, which are added to \ref GameObject "game objects" using the \ref +BehaviorScript \ref Component "component". \see Script \see BehaviorScript @@ -22,11 +17,14 @@ Script, which are added to game objects using the BehaviorScript \ref Component \par Example -First, define a class that inherits from Script. This class acts as an -interface, and has two functions (\ref Script::init "\c init()" and \ref -Script::update "\c update()"), which may be implemented (they are empty by -default). From now on, this derivative class will be referred to as a *concrete -script*. +\note This example assumes you already have a GameObject. If not, read +\"\ref feature_gameobject\" first. + +First, define a class (anywhere) that inherits from Script. The Script class +acts as an interface, and has three functions (\ref Script::init "\c init()", +\ref Script::fixed_update "\c fixed_update()" and \ref Script::frame_update +"\c frame_update()"), which *may* be implemented (they are empty by default). +From now on, this derivative class will be referred to as a *concrete script*. ```cpp #include <crepe/api/Script.h> @@ -36,25 +34,33 @@ class MyScript : public crepe::Script { void init() { // called once } - void update() { + + void fixed_update(crepe::duration_t delta_time) { // called on fixed update } + void frame_update(crepe::duration_t delta_time) { + // called for every rendered frame + } }; ``` -Concrete scripts can be instantiated and attached to \ref GameObject -"game objects" using the BehaviorScript \ref Component "component". +After defining a concrete script, it can be instantiated and attached to \ref +feature_gameobject "game objects" during \ref feature_scene +"scene initialization" using a BehaviorScript component: ```cpp using namespace crepe; -GameObject obj = component_manager.new_object("name"); +GameObject obj; -// create BehaviorScript instance +// Create a BehaviorScript component to hold MyScript BehaviorScript & behavior_script = obj.add_component<BehaviorScript>(); -// attach (and instantiate) MyScript to behavior_script + +// Instantiate (and attach) MyScript to behavior_script behavior_script.set_script<MyScript>(); +``` -// the above can also be done in a single call for convenience: +The above can also be done in a single call for convenience: +```cpp obj.add_component<BehaviorScript>().set_script<MyScript>(); ``` diff --git a/src/doc/feature/script_ecs.dox b/src/doc/feature/script_ecs.dox new file mode 100644 index 0000000..8bd3376 --- /dev/null +++ b/src/doc/feature/script_ecs.dox @@ -0,0 +1,57 @@ +// vim:ft=doxygen +namespace crepe { +/** + +\defgroup feature_script_ecs Using ECS inside Script +\ingroup feature +\brief Query the component manager inside a concrete Script + +Script provides several methods to request references to components during +runtime. These methods may be used in cases where it is either not practical or +impossible to manually pass the references required to implement a certain +behavior. + +\see Script +\see ComponentManager + +\par Example + +\note This example assumes you already have a concrete Script. If not, read +\"\ref feature_script\" first. + +The component manager can be queried for components inside Script using the +following methods: + +- For requesting components on the same GameObject as this Script instance: + - Script::get_component(): \copybrief Script::get_component + - Script::get_components(): \copybrief Script::get_components +- For requesting components in the current Scene: + - Script::get_components_by_id(): \copybrief Script::get_components_by_id + - Script::get_components_by_name(): \copybrief Script::get_components_by_name + - Script::get_components_by_tag(): \copybrief Script::get_components_by_tag + +```cpp +#include <crepe/util/Log.h> +#include <crepe/api/Script.h> +#include <crepe/api/Metadata.h> + +using namespace crepe; + +class MyScript : public Script { + void show_self() { + Metadata & own_metadata = get_component<Metadata>(); + logf("My name is {}", own_metadata.name); + } + + void list_enemies() { + RefVector<Metadata> enemies = get_components_by_tag<Metadata>("enemy"); + logf("There are {} enemies:", enemies.size()); + for (const Metadata & enemy : enemies) { + logf("- {}", enemy.name); + } + } +}; +``` + +*/ +} diff --git a/src/doc/feature/sfx.dox b/src/doc/feature/sfx.dox new file mode 100644 index 0000000..2a5c9cc --- /dev/null +++ b/src/doc/feature/sfx.dox @@ -0,0 +1,24 @@ +// vim:ft=doxygen +namespace crepe { +/** + +\defgroup feature_sfx Playing sound effects +\ingroup feature +\brief Fire a sound effect using the AudioSource component + +This page shows how to implement one-shot sound effects using the AudioSource +component's 'fire and forget'-style API. + +\see AudioSource + +\par Example + +\note This example assumes you already have a GameObject to attach the +AudioSource component to, and uses a Script to control the AudioSource instance. +Separate pages describing these features in more detail can be found at \"\ref +feature_gameobject\" and \"\ref feature_script\" respectively. + +\todo Merge #60 + +*/ +} diff --git a/src/doc/features.dox b/src/doc/features.dox index 21a040a..56d17c7 100644 --- a/src/doc/features.dox +++ b/src/doc/features.dox @@ -3,8 +3,12 @@ \htmlonly <style> -table.memberdecls { display: none; } -ul { margin: 1ex 0pt; } +table.memberdecls, +.groupheader +{ display: none; } +ul, +li +{ margin: 1ex 0pt; } </style> \endhtmlonly @@ -14,15 +18,52 @@ ul { margin: 1ex 0pt; } This page lists engine features and contains usage instructions for each feature. -\par Features +- Basics + - \todo Hello world / engine initialization -- Scripting - - \ref feature_script \n\copybrief feature_script + - \ref feature_config \n\copybrief feature_config -- Game flow management +- Scenes - \ref feature_scene \n\copybrief feature_scene + - \todo Navigating between scenes + +- Input + - \todo Key/Mouse events (w/ Script) -- Entity +- Actors / game objects - \ref feature_gameobject \n\copybrief feature_gameobject +- \todo HUD + +- Animation + - \todo Animation using spritesheet + + - \todo Particle effects + +- Save data + - \ref feature_savemgr \n\copybrief feature_savemgr + +- Audio + - \ref feature_sfx \n\copybrief feature_sfx + - \ref feature_bgm \n\copybrief feature_bgm + +- \todo AI + +- \todo Physics + +- Scripting + - \ref feature_script \n\copybrief feature_script + - \ref feature_script_ecs \n\copybrief feature_script_ecs + + - \todo Subscribing to *any* event inside Script + + - \todo Creating and dispatching custom events + +- \todo Replay + +- Utilities + - \todo Logging + + - \ref feature_proxy \n\copybrief feature_proxy + */ diff --git a/src/doc/index.dox b/src/doc/index.dox index 7796f34..342db98 100644 --- a/src/doc/index.dox +++ b/src/doc/index.dox @@ -5,7 +5,14 @@ Welcome to the documentation for the crêpe game engine. -\see feature +\see \ref install "Engine installation instructions" +\see \ref feature "Example code and usage instructions" +\see [API documentation](annotated.html) + +\noop No bold links in "See also" section +\htmlonly +<style> .section.see a { font-weight: normal; } </style> +\endhtmlonly */ diff --git a/src/doc/layout.xml b/src/doc/layout.xml index 6336655..c98c790 100644 --- a/src/doc/layout.xml +++ b/src/doc/layout.xml @@ -4,7 +4,7 @@ <tab type="mainpage" visible="yes" title="Intro"/> <tab type="user" url="@ref install" title="Installation"/> <tab type="user" url="@ref feature" title="Features"/> - <tab type="user" url="@ref internal" title="Internals"/> + <!-- <tab type="user" url="@ref internal" title="Internals"/> --> <tab type="pages" visible="no" title="" intro=""/> <tab type="topics" visible="no" title="" intro=""/> <tab type="modules" visible="no" title="" intro=""> @@ -22,7 +22,7 @@ <tab type="interfaceindex" visible="$ALPHABETICAL_INDEX" title=""/> <tab type="interfacehierarchy" visible="yes" title="" intro=""/> </tab> - <tab type="classes" visible="yes" title=""> + <tab type="classes" visible="yes" title="API"> <tab type="classlist" visible="yes" title="" intro=""/> <tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/> <tab type="hierarchy" visible="yes" title="" intro=""/> @@ -50,6 +50,7 @@ <inheritancegraph visible="yes"/> <collaborationgraph visible="yes"/> <memberdecl> + <publicmethods title=""/> <nestedclasses visible="yes" title=""/> <publictypes title=""/> <services title=""/> @@ -58,7 +59,6 @@ <signals title=""/> <publicattributes title=""/> <publicstaticattributes title=""/> - <publicmethods title=""/> <publicstaticmethods title=""/> <protectedtypes title=""/> <protectedslots title=""/> diff --git a/src/doc/style.css b/src/doc/style.css index c12240c..efc669b 100644 --- a/src/doc/style.css +++ b/src/doc/style.css @@ -4,3 +4,30 @@ a[href="namespaces.html"] { display: none; } h2.groupheader { margin-top: revert; } + +dl { + padding: 4px 12px !important; + border-radius: 8px !important; + border: 0 !important; +} +dt { + margin-bottom: 0.5ex; +} + +a:hover { + text-decoration: revert !important; + background: unset !important; +} + +dl.section.see, +dl.section.user { + padding: 0 !important; + border-radius: 0 !important; + margin-top: 0; +} +dl.section.see dt, +dl.section.user dt { + font-size: 130%; + margin-bottom: 0.5ex; + margin-top: 1.5ex; +} diff --git a/src/test/InputTest.cpp b/src/test/InputTest.cpp index 9a541a0..a1fe59a 100644 --- a/src/test/InputTest.cpp +++ b/src/test/InputTest.cpp @@ -216,7 +216,8 @@ TEST_F(InputTest, testButtonClick) { EXPECT_EQ(event.metadata.game_object_id, button_obj.id); return false; }); - auto & button = button_obj.add_component<Button>(vec2 {100, 100}, vec2 {0, 0}); + auto & button + = button_obj.add_component<Button>(vec2 {100, 100}, Button::Data {}, vec2 {0, 0}); bool hover = false; button.active = true; @@ -238,9 +239,14 @@ TEST_F(InputTest, buttonPositionCamera) { EXPECT_EQ(event.metadata.game_object_id, button_obj.id); return false; }); - auto & button = button_obj.add_component<Button>(vec2 {10, 10}, vec2 {0, 0}); + auto & button = button_obj.add_component<Button>( + vec2 {10, 10}, + Button::Data { + .world_space = false, + }, + vec2 {0, 0} + ); - button.world_space = false; bool hover = false; button.active = true; this->simulate_mouse_click(999, 999, SDL_BUTTON_LEFT); @@ -261,8 +267,13 @@ TEST_F(InputTest, buttonPositionWorld) { EXPECT_EQ(event.metadata.game_object_id, button_obj.id); return false; }); - auto & button = button_obj.add_component<Button>(vec2 {10, 10}, vec2 {0, 0}); - button.world_space = true; + auto & button = button_obj.add_component<Button>( + vec2 {10, 10}, + Button::Data { + .world_space = true, + }, + vec2 {0, 0} + ); bool hover = false; button.active = true; this->simulate_mouse_click(999, 999, SDL_BUTTON_LEFT); @@ -288,8 +299,13 @@ TEST_F(InputTest, testButtonHover) { EXPECT_EQ(event.metadata.game_object_id, button_obj.id); return false; }); - auto & button = button_obj.add_component<Button>(vec2 {100, 100}, vec2 {0, 0}); - button.active = true; + auto & button = button_obj.add_component<Button>( + vec2 {100, 100}, + Button::Data { + .world_space = true, + }, + vec2 {0, 0} + ); // Mouse on button SDL_Event hover_event; SDL_zero(hover_event); |