diff --git a/assets/games/liminal/example-scene.xml b/assets/games/liminal/example-scene.xml index 69c5c707..5d3fdab1 100644 --- a/assets/games/liminal/example-scene.xml +++ b/assets/games/liminal/example-scene.xml @@ -16,7 +16,7 @@ <set property="craig->material->color.a" value="0" /> <!-- Fade out the black overlay --> - <animate item="square->material->color.a" from="1" to="0" time="1" curve="easeOut" /> + <set property="square->material->color.a" from="1" to="0" duration="1" curve="easeOut" /> <!-- Example Text, also showing how in future we can support multiple languages --> <text character="eth"> @@ -24,7 +24,7 @@ </text> <!-- Fade in craig --> - <animate item="craig->material->color.a" from="0" to="1" time="1" curve="easeOut" /> + <set item="craig->material->color.a" from="0" to="1" duration="1" curve="easeOut" /> <text character="craig"> <string lang="en">Hi, I'm Craig.</string> </text> @@ -35,12 +35,12 @@ at the same time. This will make craig exit screen left. --> <parallel> - <animate item="craig->material->color.a" from="1" to="0" time="1" curve="easeOut" /> - <position item="craig" x="-2" time="1" curve="easeOut" /> + <set item="craig->material->color.a" from="1" to="0" duration="1" curve="easeOut" /> + <position item="craig" x="-2" duration="1" curve="easeOut" /> </parallel> <!-- Now Craig is gone, so sad, let's now fade the screen out and present some choices --> - <animate item="square->material->color.a" from="0" to="1" time="1" curve="easeOut" /> + <set item="square->material->color.a" from="0" to="1" duration="1" curve="easeOut" /> <!-- Here I am creating a marker --> <marker name="craigCool" /> @@ -90,7 +90,7 @@ <choice-set key="isCraigCool" value="yes" /> <!-- We can also wait some time --> - <wait time="1" /> + <wait duration="1" /> <!-- Now change scenes. Changing scenes is handled in-engine to stop the game diff --git a/src/dawn/games/vn/components/VNManager.hpp b/src/dawn/games/vn/components/VNManager.hpp index 7f5f1748..5f6d5842 100644 --- a/src/dawn/games/vn/components/VNManager.hpp +++ b/src/dawn/games/vn/components/VNManager.hpp @@ -32,7 +32,7 @@ namespace Dawn { this->events.push_back(event); return event; } - + /** * Sets the currently active visual novel event. This is assumed to be * the only way to handle events (no multiples currently). diff --git a/src/dawn/games/vn/events/VNAnimateEvent.hpp b/src/dawn/games/vn/events/VNAnimateEvent.hpp new file mode 100644 index 00000000..565a2430 --- /dev/null +++ b/src/dawn/games/vn/events/VNAnimateEvent.hpp @@ -0,0 +1,49 @@ +// Copyright (c) 2023 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "VNEvent.hpp" +#include "display/animation/SimplerCallbackAnimation.hpp" + +namespace Dawn { + template<typename T> + class VNAnimateEvent : public VNEvent { + public: + T from; + T to; + float_t duration; + + protected: + SimplerCallbackAnimation<T> animation; + + void onStart() override { + if(duration > 0) { + animation.clear(); + + animation.addKeyframe(0, from); + animation.addKeyframe(duration, to); + + + animation.callback = [&](T v){ + this->setValue(v); + }; + + // On-end + useEvent([&]() { + this->next(); + }, animation.event2AnimationEnd); + + useEvent([&](float_t delta) { + animation.tick(delta); + }, getScene()->eventSceneUpdate); + } else { + this->setValue(to); + this->next(); + } + } + + virtual void setValue(T value) = 0; + }; +} \ No newline at end of file diff --git a/src/dawn/games/vn/events/VNEvent.hpp b/src/dawn/games/vn/events/VNEvent.hpp index 6dd4ae3e..50840513 100644 --- a/src/dawn/games/vn/events/VNEvent.hpp +++ b/src/dawn/games/vn/events/VNEvent.hpp @@ -5,6 +5,7 @@ #pragma once #include "games/vn/components/VNManager.hpp" +#include "scene/SceneItem.hpp" namespace Dawn { class VNEvent : public StateOwner { diff --git a/src/dawn/games/vn/events/VNPositionEvent.hpp b/src/dawn/games/vn/events/VNPositionEvent.hpp index c3d359fe..7595e5a6 100644 --- a/src/dawn/games/vn/events/VNPositionEvent.hpp +++ b/src/dawn/games/vn/events/VNPositionEvent.hpp @@ -4,20 +4,27 @@ // https://opensource.org/licenses/MIT #pragma once -#include "VNEvent.hpp" -#include "scene/SceneItem.hpp" -#include "display/animation/SimplerCallbackAnimation.hpp" +#include "VNAnimateEvent.hpp" -#define VN_POSITION_EVENT_VALUE_UNCHANGED -123456789 +#define VN_POSITION_EVENT_VALUE_UNCHANGED std::numeric_limits<float>::min() namespace Dawn { - class VNPositionEvent : public VNEvent { + class VNPositionEvent : public VNAnimateEvent<glm::vec3> { public: - float_t x = VN_POSITION_EVENT_VALUE_UNCHANGED; - float_t y = VN_POSITION_EVENT_VALUE_UNCHANGED; - float_t z = VN_POSITION_EVENT_VALUE_UNCHANGED; SceneItem *item = nullptr; - float_t duration; + + VNPositionEvent() { + from = glm::vec3( + VN_POSITION_EVENT_VALUE_UNCHANGED, + VN_POSITION_EVENT_VALUE_UNCHANGED, + VN_POSITION_EVENT_VALUE_UNCHANGED + ); + to = glm::vec3( + VN_POSITION_EVENT_VALUE_UNCHANGED, + VN_POSITION_EVENT_VALUE_UNCHANGED, + VN_POSITION_EVENT_VALUE_UNCHANGED + ); + } protected: SimplerCallbackAnimation<glm::vec3> animation; @@ -26,33 +33,19 @@ namespace Dawn { assertNotNull(item); auto start = item->transform.getLocalPosition(); - auto destination = glm::vec3( - x == VN_POSITION_EVENT_VALUE_UNCHANGED ? start.x : x, - y == VN_POSITION_EVENT_VALUE_UNCHANGED ? start.y : y, - z == VN_POSITION_EVENT_VALUE_UNCHANGED ? start.z : z - ); + if(from.x == VN_POSITION_EVENT_VALUE_UNCHANGED) start.x = from.x; + if(from.y == VN_POSITION_EVENT_VALUE_UNCHANGED) start.y = from.y; + if(from.z == VN_POSITION_EVENT_VALUE_UNCHANGED) start.z = from.z; - if(duration > 0) { - animation.clear(); + if(to.x == VN_POSITION_EVENT_VALUE_UNCHANGED) to.x = start.x; + if(to.y == VN_POSITION_EVENT_VALUE_UNCHANGED) to.y = start.y; + if(to.z == VN_POSITION_EVENT_VALUE_UNCHANGED) to.z = start.z; + + VNAnimateEvent::onStart(); + } - animation.addKeyframe(0, start); - animation.addKeyframe(duration, destination); - - animation.callback = [&](glm::vec3 v){ - this->item->transform.setLocalPosition(v); - }; - - useEvent([&]() { - this->next(); - }, animation.event2AnimationEnd); - - useEvent([&](float_t delta) { - animation.tick(delta); - }, getScene()->eventSceneUpdate); - } else { - this->item->transform.setLocalPosition(destination); - this->next(); - } + void setValue(glm::vec3 value) override { + this->item->transform.setLocalPosition(value); } }; } \ No newline at end of file diff --git a/src/dawn/games/vn/events/VNSetEvent.hpp b/src/dawn/games/vn/events/VNSetEvent.hpp new file mode 100644 index 00000000..bd9b1e50 --- /dev/null +++ b/src/dawn/games/vn/events/VNSetEvent.hpp @@ -0,0 +1,27 @@ +// Copyright (c) 2023 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "VNAnimateEvent.hpp" + +namespace Dawn { + template<typename T> + class VNSetEvent : public VNAnimateEvent<T> { + public: + T *modifies = nullptr; + + protected: + void onStart() override { + assertNotNull(this->modifies); + this->from = *modifies; + + VNAnimateEvent<T>::onStart(); + } + + void setValue(T value) override { + *modifies = value; + } + }; +} \ No newline at end of file diff --git a/src/dawn/games/vn/events/VNTextEvent.hpp b/src/dawn/games/vn/events/VNTextEvent.hpp new file mode 100644 index 00000000..9171986c --- /dev/null +++ b/src/dawn/games/vn/events/VNTextEvent.hpp @@ -0,0 +1,20 @@ +// Copyright (c) 2023 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "VNEvent.hpp" + +namespace Dawn { + class VNTextEvent : public VNEvent { + public: + std::string text; + + protected: + void onStart() override { + std::cout << "TEXT: " << text << std::endl; + this->next(); + } + }; +} \ No newline at end of file diff --git a/src/dawn/games/vn/events/VNWaitEvent.hpp b/src/dawn/games/vn/events/VNWaitEvent.hpp new file mode 100644 index 00000000..e03f2302 --- /dev/null +++ b/src/dawn/games/vn/events/VNWaitEvent.hpp @@ -0,0 +1,18 @@ +// Copyright (c) 2023 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "VNAnimateEvent.hpp" + +namespace Dawn { + class VNWaitEvent : public VNAnimateEvent<float_t> { + public: + + protected: + void setValue(T value) override { + // Do nothing + } + }; +} \ No newline at end of file diff --git a/src/dawnliminal/scenes/HelloWorldScene.hpp b/src/dawnliminal/scenes/HelloWorldScene.hpp index a62c843d..56000366 100644 --- a/src/dawnliminal/scenes/HelloWorldScene.hpp +++ b/src/dawnliminal/scenes/HelloWorldScene.hpp @@ -9,7 +9,9 @@ #include "prefabs/SimpleSpinningCubePrefab.hpp" #include "games/vn/components/VNManager.hpp" #include "games/vn/events/VNDummyEvent.hpp" +#include "games/vn/events/VNTextEvent.hpp" #include "games/vn/events/VNPositionEvent.hpp" +#include "games/vn/events/VNSetEvent.hpp" namespace Dawn { class HelloWorldScene : public Scene { @@ -17,6 +19,8 @@ namespace Dawn { Camera *camera; UICanvas *canvas; + int32_t test = 0; + void stage() override { canvas = UICanvas::create(this); @@ -32,14 +36,21 @@ namespace Dawn { auto eventTest = vnManager->createEvent<VNDummyEvent>(); auto positionEvent = vnManager->createEvent<VNPositionEvent>(); - positionEvent->x = 2.0f; + positionEvent->to.x = 2.0f; positionEvent->item = cube; positionEvent->duration = 3.0f; + auto vnTextEvent = vnManager->createEvent<VNTextEvent>(); + vnTextEvent->text = "Hello World!"; + + auto setPropertyEvent = vnManager->createEvent<VNSetEvent<int32_t>>(); + setPropertyEvent->modifies = &test; + setPropertyEvent->to = 10; + eventTest ->then(positionEvent) - ->then(vnManager->createEvent<VNDummyEvent>()) - ->then(vnManager->createEvent<VNDummyEvent>()) + ->then(vnTextEvent) + ->then(setPropertyEvent) ; vnManager->setEvent(eventTest); }