OpenSiv3D
OpenSiv3D copied to clipboard
SmoothDamp を簡単に扱える Smooth<Type> クラス
案
# include <Siv3D.hpp> // OpenSiv3D v0.6.6
template <class Type>
struct Smooth
{
public:
using value_type = Type;
SIV3D_NODISCARD_CXX20
Smooth() = default;
SIV3D_NODISCARD_CXX20
constexpr Smooth(const value_type& value) noexcept
: m_value{ value }
, m_target{ value } {}
template <class... Args, std::enable_if_t<std::is_constructible_v<Type, Args...>>* = nullptr>
SIV3D_NODISCARD_CXX20
constexpr Smooth(Args&&... args) noexcept(std::is_nothrow_constructible_v<Type, Args...>)
: m_value{ std::forward<Args>(args)... }
, m_target{ m_value } {}
Smooth& operator= (const Smooth&) = default;
constexpr Smooth& operator= (const value_type& value) noexcept
{
return set(value);
}
constexpr Smooth& set(const value_type& value, const value_type& velocity = value_type{}) noexcept
{
m_value = value;
m_target = value;
m_velocity = velocity;
return *this;
}
constexpr Smooth& setTarget(const value_type& target) noexcept
{
m_target = target;
return *this;
}
const Type& update(const Duration& smoothTime, const Optional<double>& maxSpeed = unspecified, double deltaTime = Scene::DeltaTime()) noexcept
{
return (m_value = Math::SmoothDamp(m_value, m_target, m_velocity, smoothTime.count(), maxSpeed, deltaTime));
}
const Type& update(double smoothTime, const Optional<double>& maxSpeed = unspecified, double deltaTime = Scene::DeltaTime()) noexcept
{
return (m_value = Math::SmoothDamp(m_value, m_target, m_velocity, smoothTime, maxSpeed, deltaTime));
}
[[nodiscard]]
constexpr const value_type& value() const noexcept
{
return m_value;
}
[[nodiscard]]
constexpr const value_type& target() const noexcept
{
return m_target;
}
[[nodiscard]]
constexpr const value_type& velocity() const noexcept
{
return m_velocity;
}
private:
value_type m_value{};
value_type m_target{};
value_type m_velocity{};
};
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
Smooth<Vec2> pos = Scene::Center();
Smooth<double> value = 0.0;
while (System::Update())
{
pos.update(0.2s);
value.update(0.1s);
Circle{ pos.value(), 40 }.draw(ColorF{ 1, 0, 0, 0.5 });
Circle{ value.value(), 0, 15 }.draw(ColorF{ 0.5 });
PutText(U"{:.2f}"_fmt(value.value()), Vec2{ value.value(), 30 });
if (MouseL.down())
{
pos.setTarget(Cursor::Pos());
value.setTarget(Random(0, 800));
}
}
}
ToDo
- [ ]
ColorF
対応