diff --git a/impl/gamelib/hud/hud.cpp b/impl/gamelib/hud/hud.cpp index cb49d6ec..8a05724c 100644 --- a/impl/gamelib/hud/hud.cpp +++ b/impl/gamelib/hud/hud.cpp @@ -14,12 +14,14 @@ void Hud::doCreate() m_scoreP1Text = std::make_shared(); m_scoreP1Text = jt::dh::createText(renderTarget(), "", 16, jt::Color { 248, 249, 254 }); m_scoreP1Text->setTextAlign(jt::Text::TextAlign::LEFT); + m_scoreP1Text->setIgnoreCamMovement(true); m_scoreP1Text->setPosition({ 10, 4 }); m_scoreP1Display = std::make_shared(m_scoreP1Text, "P1 Score: "); m_scoreP2Text = jt::dh::createText(renderTarget(), "", 16, jt::Color { 248, 249, 254 }); m_scoreP2Text->setTextAlign(jt::Text::TextAlign::RIGHT); + m_scoreP2Text->setIgnoreCamMovement(true); m_scoreP2Text->setPosition({ GP::GetScreenSize().x - 10, 4 }); m_scoreP2Display = std::make_shared(m_scoreP2Text, "P2 Score: "); diff --git a/impl/jamtemplate/common/animation.cpp b/impl/jamtemplate/common/animation.cpp index 1f7d284a..bede4d17 100644 --- a/impl/jamtemplate/common/animation.cpp +++ b/impl/jamtemplate/common/animation.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -186,7 +187,7 @@ bool jt::Animation::hasAnimation(std::string const& animationName) const return (m_frames.count(animationName) != 0); } -std::vector jt::Animation::getAllAvailableAnimationsNames() const +std::vector jt::Animation::getAllAvailableAnimationNames() const { std::vector names; names.resize(m_frames.size()); @@ -196,6 +197,16 @@ std::vector jt::Animation::getAllAvailableAnimationsNames() const return names; } +std::string jt::Animation::getRandomAnimationName() const +{ + if (m_frames.empty()) { + throw std::invalid_argument { + "can not get random animation name if no animation has been added" + }; + } + return jt::SystemHelper::select_randomly(m_frames.cbegin(), m_frames.cend())->first; +} + void jt::Animation::play(std::string const& animationName, size_t startFrameIndex, bool restart) { m_isValid = hasAnimation(animationName); @@ -333,7 +344,7 @@ void jt::Animation::doUpdate(float elapsed) m_frameTime -= m_time[m_currentAnimName][m_currentIdx]; m_currentIdx++; if (m_currentIdx >= m_frames.at(m_currentAnimName).size()) { - if (getIsLooping()) { + if (getCurrentAnimationIsLooping()) { m_currentIdx = 0; } else { m_currentIdx = m_frames.at(m_currentAnimName).size() - 1; @@ -370,7 +381,23 @@ float jt::Animation::getCurrentAnimationSingleFrameTime() const float jt::Animation::getCurrentAnimTotalTime() const { - return getCurrentAnimationSingleFrameTime() * getNumberOfFramesInCurrentAnimation(); + float sum = 0.0f; + for (auto frameTime : m_time.at(m_currentAnimName)) { + sum += frameTime; + } + return sum; +} + +float jt::Animation::getAnimTotalTimeFor(std::string const& animName) +{ + if (!hasAnimation(animName)) { + throw std::invalid_argument { "no animation with name " + animName }; + } + float sum = 0.0f; + for (auto frameTime : m_time.at(animName)) { + sum += frameTime; + } + return sum; } std::size_t jt::Animation::getNumberOfFramesInCurrentAnimation() const @@ -380,7 +407,7 @@ std::size_t jt::Animation::getNumberOfFramesInCurrentAnimation() const std::string jt::Animation::getCurrentAnimationName() const { return m_currentAnimName; } -bool jt::Animation::getIsLooping() const +bool jt::Animation::getCurrentAnimationIsLooping() const { if (!hasAnimation(m_currentAnimName)) { return true; @@ -388,6 +415,14 @@ bool jt::Animation::getIsLooping() const return m_isLooping.at(m_currentAnimName); } +bool jt::Animation::getIsLoopingFor(std::string const& animName) const +{ + if (!hasAnimation(animName)) { + throw std::invalid_argument { "no animation with name " + animName }; + } + return m_isLooping.at(animName); +} + void jt::Animation::setLooping(std::string const& animName, bool isLooping) { if (!hasAnimation(animName)) { @@ -396,6 +431,13 @@ void jt::Animation::setLooping(std::string const& animName, bool isLooping) m_isLooping[animName] = isLooping; } +void jt::Animation::setLoopingAll(bool isLooping) +{ + for (auto& l : m_isLooping) { + l.second = isLooping; + } +} + std::size_t jt::Animation::getCurrentAnimationFrameIndex() const { return m_currentIdx; } void jt::Animation::setFrameTimes( diff --git a/impl/jamtemplate/common/animation.hpp b/impl/jamtemplate/common/animation.hpp index 538adf5f..9d5c1b96 100644 --- a/impl/jamtemplate/common/animation.hpp +++ b/impl/jamtemplate/common/animation.hpp @@ -70,8 +70,15 @@ class Animation : public DrawableImpl { bool hasAnimation(std::string const& animationName) const; /// Get all animation names - /// \return the vector of the animation names - std::vector getAllAvailableAnimationsNames() const; + /// \return vector of the animation names + std::vector getAllAvailableAnimationNames() const; + + /// Get a random animation name + /// + /// Will raise an exception if no animations have been added. + /// + /// \return random animation name + std::string getRandomAnimationName() const; /// Start playing an animation from the pool /// @@ -81,15 +88,30 @@ class Animation : public DrawableImpl { /// continue if already playing void play(std::string const& animationName, size_t startFrameIndex = 0, bool restart = false); - /// Set animation to looping - /// true by default. + /// Set animation looping + /// By default an animations is looping (true). /// If an animation is not looping, it will remain at the last frame of the animation. /// \param isLooping value void setLooping(std::string const& animName, bool isLooping); - /// Get looping + /// Set all animations looping + /// By default an animations is looping (true). + /// If an animation is not looping, it will remain at the last frame of the animation. + /// \param isLooping + void setLoopingAll(bool isLooping); + + /// Get looping value for currently playing animation + /// + /// Returns false if no animation is playing + /// /// \return true if animation is looping, false otherwise - bool getIsLooping() const; + bool getCurrentAnimationIsLooping() const; + + /// Get looping value for a specific animation + /// Raises an exception if no animation with animName found + /// \param animName the animation to check + /// \return + bool getIsLoopingFor(std::string const& animName) const; void setColor(jt::Color const& col) override; jt::Color getColor() const override; @@ -112,32 +134,42 @@ class Animation : public DrawableImpl { /// Get the frame time for one single frame in the current animation /// - /// \return the time set in add for the currently playing animation + /// \return time set in add for the currently playing animation /// will raise an exception if no valid animation is playing float getCurrentAnimationSingleFrameTime() const; /// Get the total time of the current animation /// - /// \return the time for the complete animation to play + /// \return time for the complete animation to play float getCurrentAnimTotalTime() const; + /// Get the total time of the animation with name animName + /// + /// Raises an exception if animName has not been added + /// + /// \param animName the name of the animation + /// \return time for the complete animation to play + float getAnimTotalTimeFor(std::string const& animName); + /// Get the number of frames in this animation /// - /// \return the number of frames in this animation + /// \return number of frames in this animation std::size_t getNumberOfFramesInCurrentAnimation() const; /// Get the name of the current animation /// - /// \return the name of the currently playing animation + /// \return name of the currently playing animation std::string getCurrentAnimationName() const; std::size_t getCurrentAnimationFrameIndex() const; /// Set the animation speed - /// \param factor the factor. Normal value is 1.0, can be in range from -inf to inf. + /// \param factor the animation speed factor. Normal value is 1.0, can be in range from -inf to + /// inf. void setAnimationSpeedFactor(float factor); + /// Get the animation speed - /// \return the factor. Normal value is 1.0, can be in range from -inf to inf. + /// \return animation speed factor. Normal value is 1.0, can be in range from -inf to inf. float getAnimationSpeedFactor() const; private: diff --git a/impl/jamtemplate/common/audio/audio/audio_interface.hpp b/impl/jamtemplate/common/audio/audio/audio_interface.hpp index f21fc708..f7ce782a 100644 --- a/impl/jamtemplate/common/audio/audio/audio_interface.hpp +++ b/impl/jamtemplate/common/audio/audio/audio_interface.hpp @@ -95,9 +95,9 @@ class AudioInterface { virtual ~AudioInterface() = default; // no copy, no move - AudioInterface(const AudioInterface&) = delete; + AudioInterface(AudioInterface const&) = delete; AudioInterface(AudioInterface&&) = delete; - AudioInterface& operator=(const AudioInterface&) = delete; + AudioInterface& operator=(AudioInterface const&) = delete; AudioInterface& operator=(AudioInterface&&) = delete; protected: diff --git a/impl/jamtemplate/common/audio/fades/logging_sound_fade_manager.cpp b/impl/jamtemplate/common/audio/fades/logging_sound_fade_manager.cpp index a42ac89f..af82b85a 100644 --- a/impl/jamtemplate/common/audio/fades/logging_sound_fade_manager.cpp +++ b/impl/jamtemplate/common/audio/fades/logging_sound_fade_manager.cpp @@ -10,14 +10,18 @@ jt::LoggingSoundFadeManager::LoggingSoundFadeManager( void jt::LoggingSoundFadeManager::volumeFade(std::weak_ptr sound, float durationInSeconds, float startVolume, float endVolume) { - m_logger.info("Create sound fade", { "jt", "audio", "sound fade" }); + m_logger.debug("Create sound fade", { "jt", "audio", "sound fade" }); m_decoratee.volumeFade(sound, durationInSeconds, startVolume, endVolume); } -void jt::LoggingSoundFadeManager::update(float elapsed) { +void jt::LoggingSoundFadeManager::update(float elapsed) +{ m_logger.verbose("sound fade manager update", { "jt", "audio", "sound fade" }); - m_decoratee.update(elapsed); } + m_decoratee.update(elapsed); +} -size_t jt::LoggingSoundFadeManager::size() const { +size_t jt::LoggingSoundFadeManager::size() const +{ m_logger.verbose("sound fade manager size", { "jt", "audio", "sound fade" }); - return m_decoratee.size(); } + return m_decoratee.size(); +} diff --git a/impl/jamtemplate/common/bar.cpp b/impl/jamtemplate/common/bar.cpp index 3e519b66..9721b1fc 100644 --- a/impl/jamtemplate/common/bar.cpp +++ b/impl/jamtemplate/common/bar.cpp @@ -15,7 +15,6 @@ jt::Bar::Bar( { m_shapeFull->makeRect(jt::Vector2f { m_width, m_height }, textureManager); m_shapeFull->setColor(jt::colors::Gray); - m_shapeFull->setIgnoreCamMovement(true); if (m_horizontal) { auto const progressHeightFactor = 0.9f; @@ -27,7 +26,6 @@ jt::Bar::Bar( m_shapeProgress->setPosition(jt::Vector2f { 0 + 1, m_height }); } m_shapeProgress->setColor(jt::colors::White); - m_shapeProgress->setIgnoreCamMovement(true); } void jt::Bar::setFrontColor(jt::Color const& col) { m_shapeProgress->setColor(col); } diff --git a/impl/jamtemplate/common/box2dwrapper/box2d_object.cpp b/impl/jamtemplate/common/box2dwrapper/box2d_object.cpp index e7952b01..18196d3b 100644 --- a/impl/jamtemplate/common/box2dwrapper/box2d_object.cpp +++ b/impl/jamtemplate/common/box2dwrapper/box2d_object.cpp @@ -39,6 +39,11 @@ void jt::Box2DObject::addVelocity(jt::Vector2f const& v) m_body->SetLinearVelocity(Conversion::vec(oldV + v)); } +void jt::Box2DObject::addForceToCenter(jt::Vector2f const& f) +{ + m_body->ApplyForceToCenter(Conversion::vec(f), true); +} + float jt::Box2DObject::getRotation() const { return jt::MathHelper::rad2deg(m_body->GetAngle()); } b2Body* jt::Box2DObject::getB2Body() { return m_body; } diff --git a/impl/jamtemplate/common/box2dwrapper/box2d_object.hpp b/impl/jamtemplate/common/box2dwrapper/box2d_object.hpp index 5de995e8..ebba47ff 100644 --- a/impl/jamtemplate/common/box2dwrapper/box2d_object.hpp +++ b/impl/jamtemplate/common/box2dwrapper/box2d_object.hpp @@ -23,28 +23,32 @@ class Box2DObject { virtual ~Box2DObject(); - /// Get the position - /// \return the position + /// Get position + /// \return position jt::Vector2f getPosition() const; - /// Set the position (overwrite box2d simulation) - /// \param position the new position + /// Set position (overwrite box2d simulation) + /// \param position new position void setPosition(jt::Vector2f const& position); - /// Get the velocity - /// \return the velocity + /// Get velocity + /// \return velocity jt::Vector2f getVelocity() const; - /// Set the velocity (overwrite box2d simulation) - /// \param v the new velocity + /// Set velocity (overwrite box2d simulation) + /// \param v new velocity void setVelocity(jt::Vector2f const& v); - /// Add the velocity (overwirte box2d simulation) - /// \param v the velocity to be added + /// Add velocity (overwrite box2d simulation) + /// \param v velocity to be added void addVelocity(jt::Vector2f const& v); - /// Get the rotation in degree - /// \return the rotation in degree + /// Add Force to center + /// \param f force + void addForceToCenter(Vector2f const& f); + + /// Get rotation in degree + /// \return rotation in degree float getRotation() const; /// Get the low level Box2d body pointer diff --git a/impl/jamtemplate/common/ease/ease_from_points.cpp b/impl/jamtemplate/common/ease/ease_from_points.cpp index c030deae..4fdb12bf 100644 --- a/impl/jamtemplate/common/ease/ease_from_points.cpp +++ b/impl/jamtemplate/common/ease/ease_from_points.cpp @@ -1,5 +1,4 @@ #include "ease_from_points.hpp" -#include #include #include diff --git a/impl/jamtemplate/common/lerp.hpp b/impl/jamtemplate/common/lerp.hpp index 04db3663..572b5856 100644 --- a/impl/jamtemplate/common/lerp.hpp +++ b/impl/jamtemplate/common/lerp.hpp @@ -1,7 +1,7 @@ #ifndef JAMTEMPLATE_LERP_HPP #define JAMTEMPLATE_LERP_HPP -#include +#include #include namespace jt { @@ -13,7 +13,7 @@ static T cosine(T const& a, T const& b, T const& t) { assert(t >= 0 && t <= 1); float tRemapCosine = (1.0f - static_cast(cos(t * 3.1415926f))) * 0.5f; - return linear(a, b, tRemapCosine); + return std::lerp(a, b, tRemapCosine); } template @@ -21,7 +21,7 @@ static T cubic(T const& a, T const& b, T const& t) { assert(t >= 0 && t <= 1); float cub = t * t * t; - return linear(a, b, cub); + return std::lerp(a, b, cub); } template @@ -29,7 +29,7 @@ static T cubicInvers(T const& a, T const& b, T const& t) { assert(t >= 0 && t <= 1); float cub = (1 - t) * (1 - t) * (1 - t); - return linear(a, b, cub); + return std::lerp(a, b, cub); } template diff --git a/impl/jamtemplate/common/linterp.hpp b/impl/jamtemplate/common/linterp.hpp index 9f57cc87..82940d8c 100644 --- a/impl/jamtemplate/common/linterp.hpp +++ b/impl/jamtemplate/common/linterp.hpp @@ -2,6 +2,7 @@ #define JAMTEMPLATE_LINTERP_HPP #include +#include namespace jt { @@ -21,12 +22,12 @@ static T precheck(T const& ti) namespace Lerp { -// linear interpolation between values a and b with t between 0 and 1 +/// linear interpolation between values a and b with t between 0 and 1 template static T linear(T const& a, T const& b, T const& ti) { - auto t = precheck(ti); - return (1.0f - t) * a + t * b; + auto const t = precheck(ti); + return std::lerp(a, b, t); } } // namespace Lerp diff --git a/impl/jamtemplate/common/math_helper.cpp b/impl/jamtemplate/common/math_helper.cpp index 3b67f6ac..f2d97ac7 100644 --- a/impl/jamtemplate/common/math_helper.cpp +++ b/impl/jamtemplate/common/math_helper.cpp @@ -18,6 +18,12 @@ float jt::MathHelper::distanceBetween(jt::Vector2f const& a, jt::Vector2f const& return length(dir); } +float jt::MathHelper::distanceBetweenSquared(jt::Vector2f const& a, jt::Vector2f const& b) +{ + auto const dir = b - a; + return lengthSquared(dir); +} + void jt::MathHelper::normalizeMe(jt::Vector2f& v, float lowerBound) { float l = jt::MathHelper::length(v); diff --git a/impl/jamtemplate/common/math_helper.hpp b/impl/jamtemplate/common/math_helper.hpp index 86769acd..6c9f5a8c 100644 --- a/impl/jamtemplate/common/math_helper.hpp +++ b/impl/jamtemplate/common/math_helper.hpp @@ -42,8 +42,18 @@ float lengthSquared(jt::Vector2f const& v); /// \return length float length(jt::Vector2f const& v); +/// CalculateDistanceBetween the two points +/// \param a position a +/// \param b position b +/// \return distance betwen a and b float distanceBetween(jt::Vector2f const& a, jt::Vector2f const& b); +/// Squared Distance between +/// \param a position a +/// \param b position b +/// \return squared distance betwen a and b +float distanceBetweenSquared(jt::Vector2f const& a, jt::Vector2f const& b); + /// In-place normalize a vector /// \param v vector to be normalized /// \param lowerBound lower bound for the distance (to avoid divide by zero) diff --git a/impl/jamtemplate/common/particle_system.hpp b/impl/jamtemplate/common/particle_system.hpp index aaab656b..1ee3a068 100644 --- a/impl/jamtemplate/common/particle_system.hpp +++ b/impl/jamtemplate/common/particle_system.hpp @@ -50,6 +50,15 @@ class ParticleSystem : public GameObject { } }; + /// Execute a function for each particle + /// \param fun function to execute for each particle + void forEach(std::function&)> const& fun) + { + for (auto& p : m_particles) { + fun(p); + } + } + private: ResetCallbackType m_resetCallback {}; mutable jt::CircularBuffer, N> m_particles; diff --git a/impl/jamtemplate/common/rect.cpp b/impl/jamtemplate/common/rect.cpp index f769afb9..9c2f92ff 100644 --- a/impl/jamtemplate/common/rect.cpp +++ b/impl/jamtemplate/common/rect.cpp @@ -1,20 +1,54 @@ #include "rect.hpp" #include +jt::Rectf::Rectf() + : left { 0.0f } + , top { 0.0f } + , width { 0.0f } + , height { 0.0f } +{ +} + +jt::Rectf::Rectf(float l, float t, float w, float h) + : left { l } + , top { t } + , width { w } + , height { h } +{ +} + bool jt::operator==(jt::Rectf const& a, jt::Rectf const& b) { return (a.left == b.left && a.top == b.top && a.width == b.width && a.height == b.height); } + bool jt::operator!=(jt::Rectf const& a, jt::Rectf const& b) { return !(a == b); } -std::ostream& jt::operator<<(std::ostream& os, const jt::Rectf& rect) +std::ostream& jt::operator<<(std::ostream& os, jt::Rectf const& rect) { return os << "[ (" << rect.left << ", " << rect.top << "), (" << rect.width << ", " << rect.height << ") ]"; } +jt::Recti::Recti(int l, int t, int w, int h) + : left { l } + , top { t } + , width { w } + , height { h } +{ +} + bool jt::operator==(jt::Recti const& a, jt::Recti const& b) { return (a.left == b.left && a.top == b.top && a.width == b.width && a.height == b.height); } + bool jt::operator!=(jt::Recti const& a, jt::Recti const& b) { return !(a == b); } + +jt::Recti::Recti() + : left { 0 } + , top { 0 } + , width { 0 } + , height { 0 } +{ +} diff --git a/impl/jamtemplate/common/rect.hpp b/impl/jamtemplate/common/rect.hpp index 02bba9cb..4ddcebc9 100644 --- a/impl/jamtemplate/common/rect.hpp +++ b/impl/jamtemplate/common/rect.hpp @@ -6,6 +6,8 @@ namespace jt { struct Rectf { + Rectf(); + Rectf(float l, float t, float w, float h); float left { 0.0f }; float top { 0.0f }; float width { 0.0f }; @@ -13,6 +15,9 @@ struct Rectf { }; struct Recti { + Recti(); + Recti(int l, int t, int w, int h); + int left { 0 }; int top { 0 }; int width { 0 }; @@ -25,6 +30,6 @@ bool operator!=(jt::Rectf const& a, jt::Rectf const& b); bool operator==(jt::Recti const& a, jt::Recti const& b); bool operator!=(jt::Recti const& a, jt::Recti const& b); -std::ostream& operator<<(std::ostream& os, const Rectf& rect); +std::ostream& operator<<(std::ostream& os, Rectf const& rect); } // namespace jt #endif diff --git a/impl/jamtemplate/common/screeneffects/clouds.cpp b/impl/jamtemplate/common/screeneffects/clouds.cpp index cd6efa20..0f881586 100644 --- a/impl/jamtemplate/common/screeneffects/clouds.cpp +++ b/impl/jamtemplate/common/screeneffects/clouds.cpp @@ -82,3 +82,10 @@ void jt::Clouds::doDraw() const } void jt::Clouds::setEnabled(bool enabled) { m_enabled = enabled; } + +void jt::Clouds::setZ(int zLayer) +{ + m_layer1->setZ(zLayer); + m_layer2->setZ(zLayer); + m_layer3->setZ(zLayer); +} diff --git a/impl/jamtemplate/common/screeneffects/clouds.hpp b/impl/jamtemplate/common/screeneffects/clouds.hpp index ff863848..f97c3870 100644 --- a/impl/jamtemplate/common/screeneffects/clouds.hpp +++ b/impl/jamtemplate/common/screeneffects/clouds.hpp @@ -15,6 +15,8 @@ class Clouds : public jt::GameObject { void setEnabled(bool enabled); + void setZ(int zLayer); + private: mutable std::shared_ptr m_layer1; mutable std::shared_ptr m_layer2; diff --git a/impl/jamtemplate/common/screeneffects/mario_clouds.cpp b/impl/jamtemplate/common/screeneffects/mario_clouds.cpp new file mode 100644 index 00000000..f301fc7d --- /dev/null +++ b/impl/jamtemplate/common/screeneffects/mario_clouds.cpp @@ -0,0 +1,59 @@ +#include "mario_clouds.hpp" +#include +#include +#include + +MarioClouds::MarioClouds(jt::Vector2f const& mapSize, jt::Vector2f const& margin) +{ + m_mapSize = mapSize; + m_margin = margin; +} + +void MarioClouds::doCreate() +{ + for (auto i = 0; i != 75; ++i) { + auto anim = std::make_shared(); + anim->loadFromAseprite("assets/wolken.aseprite", textureManager()); + anim->play(anim->getRandomAnimationName()); + anim->setBlendMode(jt::BlendMode::ADD); + anim->setColor(jt::Color { 255, 255, 255, 200 }); + + anim->setShadow(jt::Color { 10, 10, 10, 30 }, jt::Vector2f { 18, 14 }); + + anim->setPosition(jt::Random::getRandomPointIn(jt::Rectf { -m_margin.x, -m_margin.y, + m_mapSize.x + m_margin.x * 2, m_mapSize.y + m_margin.y * 2 })); + m_clouds.push_back(anim); + } +} + +void MarioClouds::doUpdate(float const elapsed) +{ + + jt::Vector2f const velocity { 5, 0 }; + for (auto& c : m_clouds) { + + auto pos = c->getPosition(); + pos += elapsed * velocity; + + if (pos.x > m_mapSize.x + m_margin.x) { + pos.x = -m_margin.x; + } + c->setPosition(pos); + + c->update(elapsed); + } +} + +void MarioClouds::doDraw() const +{ + for (auto& c : m_clouds) { + c->draw(renderTarget()); + } +} + +void MarioClouds::setZ(int zLayer) +{ + for (auto& c : m_clouds) { + c->setZ(zLayer); + } +} diff --git a/impl/jamtemplate/common/screeneffects/mario_clouds.hpp b/impl/jamtemplate/common/screeneffects/mario_clouds.hpp new file mode 100644 index 00000000..a563bb63 --- /dev/null +++ b/impl/jamtemplate/common/screeneffects/mario_clouds.hpp @@ -0,0 +1,25 @@ +#ifndef FRUITLOVINMONKEYPIRATES_MARIO_CLOUDS_HPP +#define FRUITLOVINMONKEYPIRATES_MARIO_CLOUDS_HPP + +#include +#include + +// TODO add to demo +class MarioClouds : public jt::GameObject { +public: + MarioClouds(jt::Vector2f const& mapSize, jt::Vector2f const& margin); + + void setZ(int zLayer); + +private: + void doCreate() override; + void doUpdate(float const elapsed) override; + void doDraw() const override; + + jt::Vector2f m_mapSize; + jt::Vector2f m_margin; + + std::vector> m_clouds; +}; + +#endif // FRUITLOVINMONKEYPIRATES_MARIO_CLOUDS_HPP diff --git a/impl/jamtemplate/common/screeneffects/particle_system_drop_items.cpp b/impl/jamtemplate/common/screeneffects/particle_system_drop_items.cpp new file mode 100644 index 00000000..09766c69 --- /dev/null +++ b/impl/jamtemplate/common/screeneffects/particle_system_drop_items.cpp @@ -0,0 +1,59 @@ +#include "particle_system_drop_items.hpp" +#include +#include +#include +#include + +ParticleSystemDropItems::ParticleSystemDropItems(std::string const& aseFileName, float radius) + : m_aseFileName { aseFileName } + , m_radius { radius } +{ +} + +void ParticleSystemDropItems::doCreate() +{ + m_tweens = std::make_shared(); + + m_particles = jt::ParticleSystem::createPS( + [this]() { + auto a = std::make_shared(); + a->loadFromAseprite(m_aseFileName, textureManager()); + a->play(a->getRandomAnimationName()); + + a->setOffset(jt::OffsetMode::CENTER); + a->setPosition(jt::Vector2f { -2000.0f, -2000.0f }); + return a; + }, + [this](auto& a, auto pos) { + auto const tweenTime = 0.7f; + a->setPosition(pos); + a->setColor(jt::colors::White); + a->update(0.0f); + + std::shared_ptr twp1 = jt::TweenPosition::create( + a, tweenTime / 2.0f, pos, pos + jt::Random::getRandomPointInCircle(m_radius)); + twp1->addCompleteCallback([this, tweenTime, &a]() { a->flicker(tweenTime / 2.0f); }); + m_tweens->add(twp1); + + auto const fadeOutDuration = 0.05f; + std::shared_ptr twa = jt::TweenAlpha::create(a, fadeOutDuration, 255u, 0u); + twa->setStartDelay(tweenTime - fadeOutDuration); + m_tweens->add(twa); + }); + m_particles->setGameInstance(getGame()); + m_particles->create(); +} + +void ParticleSystemDropItems::doUpdate(float const elapsed) +{ + m_tweens->update(elapsed); + + m_particles->update(elapsed); +} + +void ParticleSystemDropItems::doDraw() const { m_particles->draw(); } + +void ParticleSystemDropItems::fire(int number, jt::Vector2f const& pos) +{ + m_particles->fire(number, pos); +} diff --git a/impl/jamtemplate/common/screeneffects/particle_system_drop_items.hpp b/impl/jamtemplate/common/screeneffects/particle_system_drop_items.hpp new file mode 100644 index 00000000..77273da0 --- /dev/null +++ b/impl/jamtemplate/common/screeneffects/particle_system_drop_items.hpp @@ -0,0 +1,27 @@ +#ifndef JAMTEMAPLTE_PARTICLE_SYSTEM_DROP_ITEMS +#define JAMTEMAPLTE_PARTICLE_SYSTEM_DROP_ITEMS + +#include +#include +#include +#include + +// TODO add to demo +class ParticleSystemDropItems : public jt::GameObject { +public: + ParticleSystemDropItems(std::string const& aseFileName, float radius); + void fire(int number, jt::Vector2f const& pos); + +private: + void doCreate() override; + void doUpdate(float const elapsed) override; + void doDraw() const override; + + std::string m_aseFileName {}; + float m_radius { 0.0f }; + + std::shared_ptr> m_particles { nullptr }; + std::shared_ptr m_tweens { nullptr }; +}; + +#endif // JAMTEMAPLTE_PARTICLE_SYSTEM_DROP_ITEMS diff --git a/impl/jamtemplate/common/screeneffects/scanlines.cpp b/impl/jamtemplate/common/screeneffects/scanlines.cpp index 54e877dc..fbc36bcd 100644 --- a/impl/jamtemplate/common/screeneffects/scanlines.cpp +++ b/impl/jamtemplate/common/screeneffects/scanlines.cpp @@ -14,6 +14,7 @@ void jt::ScanLines::doCreate() m_shape = jt::dh::createShapeRect(m_shapeSize, jt::Color { 0, 0, 0, 40 }, textureManager()); m_shape->setIgnoreCamMovement(true); } + void jt::ScanLines::doDraw() const { if (m_enabled) { @@ -24,5 +25,9 @@ void jt::ScanLines::doDraw() const } } } + void jt::ScanLines::setEnabled(bool enable) { m_enabled = enable; } + void jt::ScanLines::setColor(jt::Color const& col) { m_shape->setColor(col); } + +void jt::ScanLines::setZ(int zLayer) { m_shape->setZ(zLayer); } diff --git a/impl/jamtemplate/common/screeneffects/scanlines.hpp b/impl/jamtemplate/common/screeneffects/scanlines.hpp index 6dd11fa1..4b4e30d1 100644 --- a/impl/jamtemplate/common/screeneffects/scanlines.hpp +++ b/impl/jamtemplate/common/screeneffects/scanlines.hpp @@ -18,6 +18,8 @@ class ScanLines : public jt::GameObject { void setColor(jt::Color const& col); + void setZ(int zLayer); + private: bool m_enabled { true }; mutable std::shared_ptr m_shape; diff --git a/impl/jamtemplate/common/screeneffects/screen_wrap.hpp b/impl/jamtemplate/common/screeneffects/screen_wrap.hpp index 6cecd729..f571a443 100644 --- a/impl/jamtemplate/common/screeneffects/screen_wrap.hpp +++ b/impl/jamtemplate/common/screeneffects/screen_wrap.hpp @@ -6,7 +6,7 @@ namespace jt { -/// wrap drawbel on screen. +/// wrap drawable on screen. /// \param drawable void wrapOnScreen(jt::DrawableInterface& drawable, float margin = 10.0f); diff --git a/impl/jamtemplate/common/screeneffects/star.cpp b/impl/jamtemplate/common/screeneffects/star.cpp index b6592f51..e38d745e 100644 --- a/impl/jamtemplate/common/screeneffects/star.cpp +++ b/impl/jamtemplate/common/screeneffects/star.cpp @@ -92,3 +92,9 @@ void jt::Star::setCamMovementFactor(float factor) m_shape->setCamMovementFactor(factor); m_glow->setCamMovementFactor(factor); } + +void jt::Star::setZ(int zLayer) +{ + m_shape->setZ(zLayer); + m_glow->setZ(zLayer); +} diff --git a/impl/jamtemplate/common/screeneffects/star.hpp b/impl/jamtemplate/common/screeneffects/star.hpp index 6db204e0..2de244e0 100644 --- a/impl/jamtemplate/common/screeneffects/star.hpp +++ b/impl/jamtemplate/common/screeneffects/star.hpp @@ -12,6 +12,8 @@ class Star : public jt::GameObject { void setColor(jt::Color const& col); void setCamMovementFactor(float factor); + void setZ(int zLayer); + private: std::shared_ptr m_shape; std::shared_ptr m_glow; diff --git a/impl/jamtemplate/common/screeneffects/stars.cpp b/impl/jamtemplate/common/screeneffects/stars.cpp index f16e3951..4eda9f02 100644 --- a/impl/jamtemplate/common/screeneffects/stars.cpp +++ b/impl/jamtemplate/common/screeneffects/stars.cpp @@ -40,10 +40,19 @@ void jt::Stars::doDraw() const star->draw(); } } + void jt::Stars::setEnabled(bool enable) { m_enabled = enable; } + void jt::Stars::setCamMovementFactor(float factor) { for (auto& star : m_stars) { star->setCamMovementFactor(factor); } } + +void jt::Stars::setZ(int zLayer) +{ + for (auto& star : m_stars) { + star->setZ(zLayer); + } +} diff --git a/impl/jamtemplate/common/screeneffects/stars.hpp b/impl/jamtemplate/common/screeneffects/stars.hpp index 772d87c1..261390e3 100644 --- a/impl/jamtemplate/common/screeneffects/stars.hpp +++ b/impl/jamtemplate/common/screeneffects/stars.hpp @@ -15,6 +15,7 @@ class Stars : public jt::GameObject { Stars(std::size_t count, jt::Color const& col, jt::Vector2f const& screenSizeHint); void setEnabled(bool enable); void setCamMovementFactor(float factor); + void setZ(int zLayer); private: void doCreate() override; @@ -23,7 +24,7 @@ class Stars : public jt::GameObject { jt::Color m_color; jt::Vector2f m_screenSizeHint; - + bool m_enabled { true }; std::vector> m_stars; diff --git a/impl/jamtemplate/common/screeneffects/trailing_circles.cpp b/impl/jamtemplate/common/screeneffects/trailing_circles.cpp new file mode 100644 index 00000000..00be7535 --- /dev/null +++ b/impl/jamtemplate/common/screeneffects/trailing_circles.cpp @@ -0,0 +1,62 @@ +#include "trailing_circles.hpp" +#include +#include + +void jt::TrailingCircles::doCreate() +{ + m_tweens = std::make_shared(); + m_particles = ParticleSystemType::createPS( + [this]() { + auto a = std::make_shared(); + a->loadFromAseprite("assets/circles.aseprite", textureManager()); + a->play("idle"); + + a->setOffset(jt::OffsetMode::CENTER); + a->setPosition(jt::Vector2f { -2000.0f, -2000.0f }); + return a; + }, + [this](auto& a, auto pos) { + auto const alpha = jt::MathHelper::clamp( + static_cast(jt::Random::getFloat(0.7f, 1.3f) * m_maxAlpha), + std::uint8_t { 0u }, std::uint8_t { 255u }); + jt::Color startColor { 255u, 255u, 255u, alpha }; + a->setColor(startColor); + a->setPosition(pos); + a->play("idle", 0, true); + a->update(0.0f); + + auto twa = jt::TweenAlpha::create(a, + a->getCurrentAnimTotalTime() * jt::Random::getFloat(0.75f, 0.95f), startColor.a, + 0u); + this->m_tweens->add(twa); + }); + + m_particles->setGameInstance(getGame()); +} + +void jt::TrailingCircles::doUpdate(float const elapsed) +{ + m_tweens->update(elapsed); + m_particles->update(elapsed); + + m_timer += elapsed; + if (m_timerMax > 0) { + if (m_timer >= m_timerMax) { + m_timer = 0.0f; + m_particles->fire(1, m_pos); + } + } +} + +void jt::TrailingCircles::doDraw() const { m_particles->draw(); } + +void jt::TrailingCircles::setPosition(jt::Vector2f const& pos) { m_pos = pos; } + +void jt::TrailingCircles::setTimerMax(float max) { m_timerMax = max; } + +void jt::TrailingCircles::setMaxAlpha(std::uint8_t maxAlpha) { m_maxAlpha = maxAlpha; } + +void jt::TrailingCircles::setZ(int zLayer) +{ + m_particles->forEach([zLayer](auto& anim) { anim->setZ(zLayer); }); +} diff --git a/impl/jamtemplate/common/screeneffects/trailing_circles.hpp b/impl/jamtemplate/common/screeneffects/trailing_circles.hpp new file mode 100644 index 00000000..7fc8e139 --- /dev/null +++ b/impl/jamtemplate/common/screeneffects/trailing_circles.hpp @@ -0,0 +1,38 @@ +#ifndef JAMTEMPLATE_TRAILING_CIRCLES_HPP +#define JAMTEMPLATE_TRAILING_CIRCLES_HPP + +#include +#include +#include +#include + +namespace jt { + +// TODO comment +// TODO add to demo +class TrailingCircles : public jt::GameObject { +public: + void setPosition(jt::Vector2f const& pos); + void setTimerMax(float max); + void setMaxAlpha(std::uint8_t maxAlpha); + + void setZ(int zLayer); + +private: + void doCreate() override; + void doUpdate(float const elapsed) override; + void doDraw() const override; + + using ParticleSystemType = jt::ParticleSystem; + + std::shared_ptr m_particles; + std::shared_ptr m_tweens; + + jt::Vector2f m_pos; + float m_timer { 0.0f }; + float m_timerMax { 0.2 }; + std::uint8_t m_maxAlpha { 255u }; +}; +} // namespace jt + +#endif // JAMTEMPLATE_TRAILING_CIRCLES_HPP diff --git a/impl/jamtemplate/common/screeneffects/vignette.cpp b/impl/jamtemplate/common/screeneffects/vignette.cpp index fe6a439a..2c329ae8 100644 --- a/impl/jamtemplate/common/screeneffects/vignette.cpp +++ b/impl/jamtemplate/common/screeneffects/vignette.cpp @@ -15,13 +15,18 @@ void jt::Vignette::doCreate() m_vignette->setIgnoreCamMovement(true); m_vignette->setColor({ 0, 0, 0, 140 }); } + void jt::Vignette::doUpdate(float const elapsed) { m_vignette->update(elapsed); } + void jt::Vignette::doDraw() const { if (m_enabled) { m_vignette->draw(renderTarget()); } } + void jt::Vignette::setEnabled(bool enabled) { m_enabled = enabled; } void jt::Vignette::setColor(jt::Color const& col) { m_vignette->setColor(col); } + +void jt::Vignette::setZ(int zLayer) { m_vignette->setZ(zLayer); } diff --git a/impl/jamtemplate/common/screeneffects/vignette.hpp b/impl/jamtemplate/common/screeneffects/vignette.hpp index 179f17fe..f4871ff9 100644 --- a/impl/jamtemplate/common/screeneffects/vignette.hpp +++ b/impl/jamtemplate/common/screeneffects/vignette.hpp @@ -4,6 +4,7 @@ #include #include #include + namespace jt { class Sprite; @@ -14,6 +15,7 @@ class Vignette : public jt::GameObject { void setEnabled(bool enabled); void setColor(jt::Color const& col); + void setZ(int zLayer); private: void doCreate() override; diff --git a/impl/jamtemplate/common/screeneffects/waves.cpp b/impl/jamtemplate/common/screeneffects/waves.cpp new file mode 100644 index 00000000..e3f4c2b4 --- /dev/null +++ b/impl/jamtemplate/common/screeneffects/waves.cpp @@ -0,0 +1,65 @@ +#include "waves.hpp" +#include +#include +#include + +jt::Waves::Waves(std::string const& filename, jt::Rectf const& size, + std::vector const& exclude, int count) + : m_filename { filename } + , m_size { size } + , m_exclude { exclude } + , m_count { count } +{ +} + +void jt::Waves::doCreate() +{ + for (int i = 0; i != m_count; ++i) { + auto a = std::make_shared(); + a->loadFromAseprite(m_filename, textureManager()); + auto selectedAnimationName = a->getRandomAnimationName(); + a->play(selectedAnimationName); + a->update(0.0f); + auto const numerOfFrames = a->getNumberOfFramesInCurrentAnimation(); + a->play(selectedAnimationName, jt::Random::getInt(0, numerOfFrames - 1), true); + + auto const p = jt::Random::getRandomPointIn(m_size); + bool inExcluded { false }; + for (auto const& r : m_exclude) { + if (jt::MathHelper::checkIsIn(r, p) + || jt::MathHelper::checkIsIn(r, p + jt::Vector2f { 16.0f, 16.0f })) { + inExcluded = true; + break; + } + } + if (inExcluded) { + --i; + continue; + } + + a->setPosition(p); + + m_animations.push_back(a); + } +} + +void jt::Waves::doUpdate(float const elapsed) +{ + for (auto const& a : m_animations) { + a->update(elapsed); + } +} + +void jt::Waves::doDraw() const +{ + for (auto const& a : m_animations) { + a->draw(renderTarget()); + } +} + +void jt::Waves::setZ(int zLayer) +{ + for (auto const& a : m_animations) { + a->setZ(zLayer); + } +} diff --git a/impl/jamtemplate/common/screeneffects/waves.hpp b/impl/jamtemplate/common/screeneffects/waves.hpp new file mode 100644 index 00000000..f0f30024 --- /dev/null +++ b/impl/jamtemplate/common/screeneffects/waves.hpp @@ -0,0 +1,32 @@ +#ifndef JAMTEMPLATE_WAVES_HPP +#define JAMTEMPLATE_WAVES_HPP + +#include +#include +#include + +namespace jt { +// TODO add to demo +class Waves : public jt::GameObject { +public: + Waves(std::string const& filename, jt::Rectf const& size, std::vector const& exclude, + int count); + + void setZ(int zLayer); + +private: + void doCreate() override; + void doUpdate(float const elapsed) override; + void doDraw() const override; + + std::vector> m_animations {}; + + std::string m_filename; + jt::Rectf m_size {}; + std::vector m_exclude {}; + int m_count { 0 }; +}; + +} // namespace jt + +#endif // JAMTEMPLATE_WAVES_HPP diff --git a/impl/jamtemplate/common/screeneffects/wind_particles.cpp b/impl/jamtemplate/common/screeneffects/wind_particles.cpp index 4faaa209..e84e4faf 100644 --- a/impl/jamtemplate/common/screeneffects/wind_particles.cpp +++ b/impl/jamtemplate/common/screeneffects/wind_particles.cpp @@ -44,6 +44,7 @@ void jt::WindParticles::doUpdate(float const elapsed) s->update(elapsed); } } + void jt::WindParticles::doDraw() const { if (!m_enabled) { @@ -55,3 +56,10 @@ void jt::WindParticles::doDraw() const } void jt::WindParticles::setEnabled(bool enabled) { m_enabled = enabled; } + +void jt::WindParticles::setZ(int zLayer) +{ + for (auto const& s : m_shapes) { + s->setZ(zLayer); + } +} diff --git a/impl/jamtemplate/common/screeneffects/wind_particles.hpp b/impl/jamtemplate/common/screeneffects/wind_particles.hpp index e257c055..7e6fa09a 100644 --- a/impl/jamtemplate/common/screeneffects/wind_particles.hpp +++ b/impl/jamtemplate/common/screeneffects/wind_particles.hpp @@ -13,6 +13,8 @@ class WindParticles : public jt::GameObject { void setEnabled(bool enabled); + void setZ(int zLayer); + private: void doCreate() override; void doUpdate(float const elapsed) override; diff --git a/impl/jamtemplate/common/tilemap/tile_layer.cpp b/impl/jamtemplate/common/tilemap/tile_layer.cpp index 7e272360..6109701e 100644 --- a/impl/jamtemplate/common/tilemap/tile_layer.cpp +++ b/impl/jamtemplate/common/tilemap/tile_layer.cpp @@ -1,7 +1,6 @@ #include "tile_layer.hpp" #include #include -#include #include jt::tilemap::TileLayer::TileLayer(std::vector const& tileInfo, @@ -9,6 +8,25 @@ jt::tilemap::TileLayer::TileLayer(std::vector const& tile : m_tileSetSprites { tileSetSprites } , m_tiles { tileInfo } { + calculateMapSize(); +} + +void jt::tilemap::TileLayer::calculateMapSize() +{ + m_mapSizeInPixel = { 0.0f, 0.0f }; + if (m_tiles.empty()) { + return; + } + + for (auto const& t : m_tiles) { + if (t.position.x > m_mapSizeInPixel.x) { + m_mapSizeInPixel.x = t.position.x; + } + if (t.position.y > m_mapSizeInPixel.y) { + m_mapSizeInPixel.y = t.position.y; + } + } + m_mapSizeInPixel += m_tiles.at(0).size; } jt::tilemap::TileLayer::TileLayer(std::tuple const&, @@ -30,10 +48,10 @@ bool jt::tilemap::TileLayer::isTileVisible(jt::tilemap::TileInfo const& tile) co if (tile.position.y + camOffset.y + tile.size.y < 0) { return false; } - if (tile.position.x + camOffset.x >= this->m_screenSizeHint.x + tile.size.x) { + if (tile.position.x + camOffset.x >= m_screenSizeHint.x + tile.size.x) { return false; } - if (tile.position.y + camOffset.y >= this->m_screenSizeHint.y + tile.size.y) { + if (tile.position.y + camOffset.y >= m_screenSizeHint.y + tile.size.y) { return false; } return true; @@ -50,17 +68,16 @@ void jt::tilemap::TileLayer::doDraw(std::shared_ptr const auto const pixelPosForTile = tile.position + posOffset; auto const id = tile.id; - this->m_tileSetSprites.at(id)->setPosition( - jt::Vector2f { pixelPosForTile.x, pixelPosForTile.y }); + m_tileSetSprites.at(id)->setPosition(jt::Vector2f { pixelPosForTile.x, pixelPosForTile.y }); auto color = jt::colors::White; if (m_colorFunction != nullptr) { color = m_colorFunction(tile.position); } - this->m_tileSetSprites.at(id)->setColor(color); - this->m_tileSetSprites.at(id)->setScale(this->m_scale); - this->m_tileSetSprites.at(id)->update(0.0f); - this->m_tileSetSprites.at(id)->setBlendMode(getBlendMode()); - this->m_tileSetSprites.at(id)->draw(sptr); + m_tileSetSprites.at(id)->setColor(color); + m_tileSetSprites.at(id)->setScale(m_scale); + m_tileSetSprites.at(id)->update(0.0f); + m_tileSetSprites.at(id)->setBlendMode(getBlendMode()); + m_tileSetSprites.at(id)->draw(sptr); } } @@ -99,14 +116,12 @@ jt::Vector2f jt::tilemap::TileLayer::getPosition() const { return m_position; } jt::Rectf jt::tilemap::TileLayer::getGlobalBounds() const { - return jt::Rectf { getPosition().x, getPosition().y, std::numeric_limits::max(), - std::numeric_limits::max() }; + return jt::Rectf { getPosition().x, getPosition().y, m_mapSizeInPixel.x, m_mapSizeInPixel.y }; } jt::Rectf jt::tilemap::TileLayer::getLocalBounds() const { - return jt::Rectf { getPosition().x, getPosition().y, std::numeric_limits::max(), - std::numeric_limits::max() }; + return jt::Rectf { getPosition().x, getPosition().y, m_mapSizeInPixel.x, m_mapSizeInPixel.y }; } void jt::tilemap::TileLayer::setScale(jt::Vector2f const& scale) { m_scale = scale; } @@ -132,3 +147,5 @@ void jt::tilemap::TileLayer::setColorFunction( { m_colorFunction = colorFunc; } + +jt::Vector2f jt::tilemap::TileLayer::getMapSizeInPixel() const { return m_mapSizeInPixel; } diff --git a/impl/jamtemplate/common/tilemap/tile_layer.hpp b/impl/jamtemplate/common/tilemap/tile_layer.hpp index ef189df8..e907d092 100644 --- a/impl/jamtemplate/common/tilemap/tile_layer.hpp +++ b/impl/jamtemplate/common/tilemap/tile_layer.hpp @@ -37,6 +37,10 @@ class TileLayer : public DrawableImpl { void doDrawFlash(std::shared_ptr sptr) const override; void doDrawShadow(std::shared_ptr sptr) const override; + /// Get map size in pixel + //// \returns map size in pixel + jt::Vector2f getMapSizeInPixel() const; + private: void doDrawOutline(std::shared_ptr const sptr) const override; @@ -71,7 +75,10 @@ class TileLayer : public DrawableImpl { jt::Vector2f m_scale { 1.0f, 1.0f }; Color m_color { jt::colors::White }; + jt::Vector2f m_mapSizeInPixel { 0.0f, 0.0f }; + bool isTileVisible(TileInfo const& tile) const; + void calculateMapSize(); }; } // namespace tilemap diff --git a/impl/jamtemplate/common/tilemap/tileson_loader.cpp b/impl/jamtemplate/common/tilemap/tileson_loader.cpp index 17729946..1b553dab 100644 --- a/impl/jamtemplate/common/tilemap/tileson_loader.cpp +++ b/impl/jamtemplate/common/tilemap/tileson_loader.cpp @@ -64,17 +64,26 @@ std::vector loadTiles( std::string const& layerName, std::shared_ptr map) { std::vector tiles; + + bool foundLayer { false }; + for (auto& layer : map->getLayers()) { // skip all non-tile layers if (layer.getType() != tson::LayerType::TileLayer) { continue; } if (layer.getName() == layerName) { + foundLayer = true; for (auto& [_, tile] : layer.getTileObjects()) { tiles.emplace_back(parseSingleTile(tile)); } } } + + if (!foundLayer) { + std::cerr << "Warning: no tileset layer found with name : " << layerName << std::endl; + } + return tiles; } @@ -138,7 +147,7 @@ jt::tilemap::TilesonLoader::loadNodesFromLayer(std::string const& layerName) auto node = std::make_shared(); node->setPosition( jt::Vector2u { static_cast(posx), static_cast(posy) }); - + node->setBlocked(isBlocked); nodes.push_back(node); } diff --git a/impl/jamtemplate/common/vector.cpp b/impl/jamtemplate/common/vector.cpp index b6ae6045..3b4628cb 100644 --- a/impl/jamtemplate/common/vector.cpp +++ b/impl/jamtemplate/common/vector.cpp @@ -6,6 +6,7 @@ jt::Vector2f::Vector2f(float x, float y) , y { y } { } + jt::Vector2f::Vector2f() : x { 0.0f } , y { 0.0f } @@ -47,6 +48,7 @@ jt::Vector2f jt::operator*(float const f, jt::Vector2f const& v) { return jt::Vector2f { f * v.x, f * v.y }; } + jt::Vector2f jt::operator*(jt::Vector2f const& v, float const f) { return f * v; } jt::Vector2f jt::operator/(jt::Vector2f const& v, float const f) @@ -59,21 +61,23 @@ std::ostream& jt::operator<<(std::ostream& os, jt::Vector2f const& vec) return os << "(" << vec.x << ", " << vec.y << ")"; } -jt::Vector2u::Vector2u(unsigned int x, unsigned int y) - : x { x } - , y { y } -{ -} jt::Vector2u::Vector2u() : x { 0u } , y { 0u } { } +jt::Vector2u::Vector2u(unsigned int x, unsigned int y) + : x { x } + , y { y } +{ +} + jt::Vector2u jt::operator+(jt::Vector2u const& a, jt::Vector2u const& b) { return jt::Vector2u { a.x + b.x, a.y + b.y }; } + jt::Vector2u jt::operator-(jt::Vector2u const& a, jt::Vector2u const& b) { return jt::Vector2u { a.x - b.x, a.y - b.y }; @@ -85,6 +89,7 @@ jt::Vector2u& jt::operator+=(jt::Vector2u& lhs, jt::Vector2u const& other) lhs.y += other.y; return lhs; } + jt::Vector2u& jt::operator-=(jt::Vector2u& lhs, jt::Vector2u const& other) { lhs.x -= other.x; @@ -96,6 +101,7 @@ bool jt::operator==(jt::Vector2u const& a, jt::Vector2u const& b) { return a.x == b.x && a.y == b.y; } + bool jt::operator!=(jt::Vector2u const& a, jt::Vector2u const& b) { return !(a == b); } std::ostream& jt::operator<<(std::ostream& os, jt::Vector2u const& vec) diff --git a/impl/jamtemplate/sfml/sprite.cpp b/impl/jamtemplate/sfml/sprite.cpp index ee33351a..6fe3a5af 100644 --- a/impl/jamtemplate/sfml/sprite.cpp +++ b/impl/jamtemplate/sfml/sprite.cpp @@ -68,8 +68,8 @@ void jt::Sprite::doUpdate(float /*elapsed*/) { auto const screenPosition = jt::MathHelper::castToInteger( getPosition() + getShakeOffset() + getOffset() + getCompleteCamOffset()); - m_sprite.setPosition(screenPosition.x, screenPosition.y); - m_flashSprite.setPosition(screenPosition.x, screenPosition.y); + m_sprite.setPosition(toLib(screenPosition)); + m_flashSprite.setPosition(toLib(screenPosition)); m_flashSprite.setColor(toLib(getFlashColor())); } @@ -93,7 +93,9 @@ void jt::Sprite::doDrawOutline(std::shared_ptr const sptr jt::Vector2f const oldPos = fromLib(m_sprite.getPosition()); jt::Color const oldCol = fromLib(m_sprite.getColor()); - m_sprite.setColor(toLib(getOutlineColor())); + auto col = getOutlineColor(); + col.a = oldCol.a; + m_sprite.setColor(toLib(col)); for (auto const outlineOffset : getOutlineOffsets()) { m_sprite.setPosition(toLib(jt::MathHelper::castToInteger(oldPos + outlineOffset))); diff --git a/test/unit/jt_test/common/graphics/animation_test.cpp b/test/unit/jt_test/common/animation_test.cpp similarity index 78% rename from test/unit/jt_test/common/graphics/animation_test.cpp rename to test/unit/jt_test/common/animation_test.cpp index aa9fdd00..d86c2985 100644 --- a/test/unit/jt_test/common/graphics/animation_test.cpp +++ b/test/unit/jt_test/common/animation_test.cpp @@ -14,6 +14,7 @@ class AnimationTestFixture : public ::testing::Test { public: jt::TextureManagerInterface& tm { getTextureManager() }; jt::Animation a; + void SetUp() override { tm = getTextureManager(); } }; @@ -36,6 +37,14 @@ TEST_F(AnimationTestFixture, AddAnimationWithEmptyFrameTimesRaisesInvalidArgumen std::invalid_argument); } +TEST_F(AnimationTestFixture, + AddAnimationWithDifferentFrameTimesAndFrameIndicesRaisesInvalidArgumentException) +{ + ASSERT_THROW( + a.add("assets/test/unit/jt_test/coin.png", "", { 16, 16 }, { 1, 2, 3 }, { 0.1f, 0.2f }, tm), + std::invalid_argument); +} + TEST_F( AnimationTestFixture, AddAnimationWithDifferentNumberOfFrameTimesRaisesInvalidArgumentException) { @@ -91,10 +100,16 @@ TEST_F(AnimationTestFixture, AddWithWrongSizeFrameTimesRaisesException) TEST_F(AnimationTestFixture, GetAllAvailableAnimationsNamesReturnsEmptyVectorByDefault) { jt::Animation a {}; - auto const animationNames = a.getAllAvailableAnimationsNames(); + auto const animationNames = a.getAllAvailableAnimationNames(); ASSERT_EQ(animationNames.size(), 0u); } +TEST_F(AnimationTestFixture, GetRandomAnimationNameRaisesExceptionForDefaultAnimtaion) +{ + jt::Animation a {}; + ASSERT_THROW(a.getRandomAnimationName(), std::invalid_argument); +} + TEST_F(AnimationTestFixture, LoadFromJsonWithFileTypeThatIsNotJson) { jt::Animation a {}; @@ -113,16 +128,31 @@ TEST_F(AnimationTestFixture, LoadFromJson) ASSERT_EQ(a.getGlobalBounds().width, 16); ASSERT_EQ(a.getGlobalBounds().height, 16); - auto const animationNames = a.getAllAvailableAnimationsNames(); + auto const animationNames = a.getAllAvailableAnimationNames(); ASSERT_EQ(animationNames.size(), 3u); } - #endif +TEST_F(AnimationTestFixture, LoadFromAseprite) +{ + jt::Animation a {}; + a.loadFromAseprite("assets/test/unit/jt_test/dino_salto.aseprite", tm); + a.play("InAir"); + + ASSERT_EQ(a.getGlobalBounds().left, 0); + ASSERT_EQ(a.getGlobalBounds().top, 0); + ASSERT_EQ(a.getGlobalBounds().width, 24); + ASSERT_EQ(a.getGlobalBounds().height, 18); + + auto const animationNames = a.getAllAvailableAnimationNames(); + ASSERT_EQ(animationNames.size(), 1u); +} + class AnimationTestWithAnimation : public ::testing::Test { protected: jt::TextureManagerInterface& tm { getTextureManager() }; jt::Animation a; + void SetUp() override { addAnimationWithFrameIndices(); } void addAnimationWithFrameIndices(std::vector frameIndices = { 0, 1, 2, 3, 4 }) @@ -155,12 +185,41 @@ TEST_F(AnimationTestWithAnimation, PlayInvalidAnimationWillRaiseInvalidArgument) ASSERT_NO_THROW(a.play("test1234_invalid")); } -TEST_F(AnimationTestWithAnimation, IsLoopingByDefault) { ASSERT_TRUE(a.getIsLooping()); } +TEST_F(AnimationTestWithAnimation, IsLoopingByDefault) +{ + ASSERT_TRUE(a.getCurrentAnimationIsLooping()); +} + +TEST_F(AnimationTestWithAnimation, IsLoopingForIsTrueByDefault) +{ + addAnimationWithFrameIndices(); + ASSERT_TRUE(a.getIsLoopingFor("idle")); +} + +TEST_F(AnimationTestWithAnimation, IsLoopingForRaisesExceptionForInvalidName) +{ + ASSERT_THROW(a.getIsLoopingFor("blarz"), std::invalid_argument); +} + +TEST_F(AnimationTestWithAnimation, IsLoopingAfterSetLoopingAll) +{ + addAnimationWithFrameIndices(); + a.setLoopingAll(false); + ASSERT_FALSE(a.getIsLoopingFor("idle")); +} TEST_F(AnimationTestWithAnimation, IsLoopingAfterPlay) { + addAnimationWithFrameIndices(); a.play("idle"); - ASSERT_TRUE(a.getIsLooping()); + ASSERT_TRUE(a.getCurrentAnimationIsLooping()); +} + +TEST_F(AnimationTestWithAnimation, IsNotLoopingAfterSetLooping) +{ + a.play("idle"); + a.setLooping("idle", false); + ASSERT_FALSE(a.getCurrentAnimationIsLooping()); } TEST_F(AnimationTestWithAnimation, SetFrameTimes) @@ -184,17 +243,26 @@ TEST_F(AnimationTestWithAnimation, SetFrameTimesWithInvalidVectorSize) ASSERT_THROW(a.setFrameTimes("idle", { 1.23f }), std::invalid_argument); } -TEST_F(AnimationTestWithAnimation, IsNotLoopingAfterSetLooping) +TEST_F(AnimationTestWithAnimation, GetTotalTimeForReturnsValidTime) { - a.play("idle"); - a.setLooping("idle", false); - ASSERT_FALSE(a.getIsLooping()); + ASSERT_EQ(a.getAnimTotalTimeFor("idle"), 5.0f); +} + +TEST_F(AnimationTestWithAnimation, GetTotalTimeRaisesExceptionForInvalidName) +{ + ASSERT_THROW(a.getAnimTotalTimeFor("BLARZ"), std::invalid_argument); +} + +TEST_F(AnimationTestWithAnimation, GetRandomAnimationNameReturnsCorrectName) +{ + ASSERT_EQ(a.getRandomAnimationName(), "idle"); } class AnimationPlayingTest : public ::testing::Test { protected: jt::TextureManagerInterface& tm { getTextureManager() }; jt::Animation a; + void SetUp() override { a.add("assets/test/unit/jt_test/coin.png", "idle", { 16, 16 }, { 0, 1, 2, 3, 4 }, 1.0f, tm); diff --git a/test/unit/jt_test/common/box2dwrapper/box2d_object_test.cpp b/test/unit/jt_test/common/box2dwrapper/box2d_object_test.cpp index 19b5ee2e..ef614346 100644 --- a/test/unit/jt_test/common/box2dwrapper/box2d_object_test.cpp +++ b/test/unit/jt_test/common/box2dwrapper/box2d_object_test.cpp @@ -49,7 +49,7 @@ TEST_F(Box2dObjectTest, DestroyWithDeletedWorld) EXPECT_NO_THROW(obj.reset()); } -class Box2dObjectWorldImplTest : public ::testing::Test { +class Box2dObjectWithWorldTest : public ::testing::Test { public: std::shared_ptr m_world; @@ -66,7 +66,7 @@ class Box2dObjectWorldImplTest : public ::testing::Test { } }; -TEST_F(Box2dObjectWorldImplTest, GetPositionReturnsSetPosition) +TEST_F(Box2dObjectWithWorldTest, GetPositionReturnsSetPosition) { auto obj = getBox2DObject(); jt::Vector2f const newPosition { 2.0f, 17.0f }; @@ -74,7 +74,7 @@ TEST_F(Box2dObjectWorldImplTest, GetPositionReturnsSetPosition) ASSERT_EQ(obj.getPosition(), newPosition); } -TEST_F(Box2dObjectWorldImplTest, GetVelocityReturnsSetVelocity) +TEST_F(Box2dObjectWithWorldTest, GetVelocityReturnsSetVelocity) { auto obj = getBox2DObject(); jt::Vector2f const newVelocity { 3.0f, 13.0f }; @@ -82,7 +82,7 @@ TEST_F(Box2dObjectWorldImplTest, GetVelocityReturnsSetVelocity) ASSERT_EQ(obj.getVelocity(), newVelocity); } -TEST_F(Box2dObjectWorldImplTest, GetVelocityReturnsAddedVelocity) +TEST_F(Box2dObjectWithWorldTest, GetVelocityReturnsAddedVelocity) { auto obj = getBox2DObject(); jt::Vector2f const newVelocity { 3.0f, 13.0f }; @@ -90,10 +90,19 @@ TEST_F(Box2dObjectWorldImplTest, GetVelocityReturnsAddedVelocity) ASSERT_EQ(obj.getVelocity(), newVelocity); } -TEST_F(Box2dObjectWorldImplTest, GetRotationReturnsValue) +TEST_F(Box2dObjectWithWorldTest, GetRotationReturnsValue) { auto obj = getBox2DObject(); auto const newRotation = jt::MathHelper::deg2rad(50.0f); obj.getB2Body()->SetTransform(b2Vec2_zero, newRotation); ASSERT_FLOAT_EQ(obj.getRotation(), 50.0f); } + +TEST_F(Box2dObjectWithWorldTest, AddForceToCenter) +{ + auto obj = getBox2DObject(); + ASSERT_EQ(obj.getB2Body()->GetLinearVelocity().x, 0.0f); + obj.addForceToCenter(jt::Vector2f { 100.0f, 0.0f }); + m_world->step(0.01f, 10, 10); + ASSERT_NE(obj.getB2Body()->GetLinearVelocity().x, 0.0f); +} diff --git a/test/unit/jt_test/common/lerp_test.cpp b/test/unit/jt_test/common/lerp_test.cpp index 9256c976..2b6989c2 100644 --- a/test/unit/jt_test/common/lerp_test.cpp +++ b/test/unit/jt_test/common/lerp_test.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include @@ -41,8 +41,7 @@ TEST_F(LerpTestF, bounce) ASSERT_EQ(expected, f(input, 0.0f, 1.0f)); } -class LerpBounceValuesTestFixture : public ::testing::TestWithParam> { -}; +class LerpBounceValuesTestFixture : public ::testing::TestWithParam> { }; TEST_P(LerpBounceValuesTestFixture, ReturnsExpectedValue) { diff --git a/test/unit/jt_test/common/rect_test.cpp b/test/unit/jt_test/common/rect_test.cpp index 71789dfe..210bbb44 100644 --- a/test/unit/jt_test/common/rect_test.cpp +++ b/test/unit/jt_test/common/rect_test.cpp @@ -1,6 +1,36 @@ #include #include +TEST(Rectf, IsDefaultConstructible) +{ + ASSERT_TRUE(std::is_default_constructible::value); +} + +TEST(Rectf, IsConstructibleWithCorrectNumberOfArguments) +{ + auto const constructibleWithFourFloats + = std::is_constructible::value; + ASSERT_TRUE(constructibleWithFourFloats); + + auto const constructibleWithTwoFloats = std::is_constructible::value; + ASSERT_FALSE(constructibleWithTwoFloats); +} + +TEST(Recti, IsDefaultConstructible) +{ + ASSERT_TRUE(std::is_default_constructible::value); +} + +TEST(Recti, IsConstructibleWithCorrectNumberOfArguments) +{ + auto const constructibleWithFourInts + = std::is_constructible::value; + ASSERT_TRUE(constructibleWithFourInts); + + auto const constructibleWithTwoInts = std::is_constructible::value; + ASSERT_FALSE(constructibleWithTwoInts); +} + TEST(RectEQ, Equal) { jt::Rectf const initial { 5.0f, -1.245f, 44.1f, 2.2f }; diff --git a/test/unit/jt_test/common/tilemap/tilemap_tile_layer_test.cpp b/test/unit/jt_test/common/tilemap/tilemap_tile_layer_test.cpp index 27dcc5f5..a2ed66d7 100644 --- a/test/unit/jt_test/common/tilemap/tilemap_tile_layer_test.cpp +++ b/test/unit/jt_test/common/tilemap/tilemap_tile_layer_test.cpp @@ -71,15 +71,13 @@ TEST_F(TilemapTileLayerTest, GetGetOriginReturnsDefaultConstructedVector) TEST_F(TilemapTileLayerTest, GetGlobalBoundsReturnsDefaultConstructedRect) { - jt::Rectf const expectedRect { 0.0f, 0.0f, std::numeric_limits::max(), - std::numeric_limits::max() }; + jt::Rectf const expectedRect { 0.0f, 0.0f, 1600.0f, 1600.0f }; ASSERT_EQ(tileLayer->getGlobalBounds(), expectedRect); } TEST_F(TilemapTileLayerTest, GetLocalBoundsReturnsDefaultConstructedRect) { - jt::Rectf const expectedRect { 0.0f, 0.0f, std::numeric_limits::max(), - std::numeric_limits::max() }; + jt::Rectf const expectedRect { 0.0f, 0.0f, 1600.0f, 1600.0f }; ASSERT_EQ(tileLayer->getLocalBounds(), expectedRect); }