aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Doxyfile2
-rw-r--r--game/PreviewScene.cpp22
-rw-r--r--game/background/StartSubScene.cpp4
-rw-r--r--game/missile/SpawnEvent.h5
-rw-r--r--game/preview/NpcScript.cpp8
-rw-r--r--game/preview/NpcSubScene.cpp4
-rw-r--r--game/preview/PrevPlayerScript.cpp53
-rw-r--r--game/preview/PrevPlayerScript.h17
-rw-r--r--game/preview/PrevPlayerSubScene.cpp8
-rw-r--r--src/crepe/api/Asset.h4
-rw-r--r--src/crepe/api/Config.h27
-rw-r--r--src/doc/feature/bgm.dox22
-rw-r--r--src/doc/feature/config.dox61
-rw-r--r--src/doc/feature/gameobject.dox4
-rw-r--r--src/doc/feature/scene.dox15
-rw-r--r--src/doc/feature/script.dox48
-rw-r--r--src/doc/feature/script_ecs.dox57
-rw-r--r--src/doc/feature/sfx.dox24
-rw-r--r--src/doc/features.dox55
-rw-r--r--src/doc/index.dox9
-rw-r--r--src/doc/layout.xml6
-rw-r--r--src/doc/style.css27
-rw-r--r--src/test/InputTest.cpp30
23 files changed, 416 insertions, 96 deletions
diff --git a/Doxyfile b/Doxyfile
index 07c86d1..78f486b 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -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);