Tweener类似于unity中的doTweener
比如我想达下面的效果
auto x = [this](float p)
{
Log("当前时间" + to_string(p));
};
Tween::DoTween<float>(0.0f, 2.0f, 2.0f, x);
auto y = [this](glm::vec3 p)
{
Log("当前x值" + to_string(p.x) + "---当前y值" + to_string(p.y) + "---当前z值" + to_string(p.z));
};
Tween::DoTween<glm::vec3>(glm::vec3(0.0,1.0,2.0), glm::vec3(10.0, 2.0, -2.0), 1.0f, y ,Ease::InOutSine);
Tween类
#ifndef Tween_H
#define Tween_H
#include <functional>
#include "ScheduleCommand.h"
#include "Time.h"
#include "Tweener.h"
#include <glm/glm.hpp>
using namespace std;
enum class Ease
{
Linear,
InSine,
OutSine,
InOutSine,
InQuad,
OutQuad,
InOutQuad
};
class Tween
{
public:
template<typename T>
static Tweener<T>* DoTween(T start, T end, float duration, std::function<void(T)> fun, Ease ease = Ease::Linear)
{
std::function<T(T, T, float)> easeFun;
switch (ease)
{
case Ease::Linear:
easeFun = std::bind((T(*)(T ,T, float))Linear, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
break;
case Ease::InSine:
easeFun = std::bind((T(*)(T, T, float))InSine, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
break;
case Ease::OutSine:
easeFun = std::bind((T(*)(T, T, float))OutSine, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
break;
case Ease::InOutSine:
easeFun = std::bind((T(*)(T, T, float))InOutSine, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
break;
case Ease::InQuad:
easeFun = std::bind((T(*)(T, T, float))InQuad, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
break;
case Ease::OutQuad:
easeFun = std::bind((T(*)(T, T, float))OutQuad, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
break;
case Ease::InOutQuad:
easeFun = std::bind((T(*)(T, T, float))InOutQuad, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
break;
default:
break;
}
return new Tweener<T>(start, end, duration, fun, easeFun);
}
private:
static glm::vec2 Linear(glm::vec2 start, glm::vec2 end, float percent)
{
glm::vec2 a;
a.x = Linear(start.x, end.x, percent);
a.y = Linear(start.y, end.y, percent);
return a;
//return glm::vec2(Linear(start.x, end.x, percent), Linear(start.y, end.y, percent));
}
static glm::vec2 InSine(glm::vec2 start, glm::vec2 end, float percent)
{
glm::vec2 a;
a.x = InSine(start.x, end.x, percent);
a.y = InSine(start.y, end.y, percent);
return a;
}
static glm::vec2 OutSine(glm::vec2 start, glm::vec2 end, float percent)
{
glm::vec2 a;
a.x = OutSine(start.x, end.x, percent);
a.y = OutSine(start.y, end.y, percent);
return a;
}
static glm::vec2 InOutSine(glm::vec2 start, glm::vec2 end, float percent)
{
glm::vec2 a;
a.x = InOutSine(start.x, end.x, percent);
a.y = InOutSine(start.y, end.y, percent);
return a;
}
static glm::vec2 InQuad(glm::vec2 start, glm::vec2 end, float percent)
{
glm::vec2 a;
a.x = InQuad(start.x, end.x, percent);
a.y = InQuad(start.y, end.y, percent);
return a;
}
static glm::vec2 OutQuad(glm::vec2 start, glm::vec2 end, float percent)
{
glm::vec2 a;
a.x = OutQuad(start.x, end.x, percent);
a.y = OutQuad(start.y, end.y, percent);
return a;
}
static glm::vec2 InOutQuad(glm::vec2 start, glm::vec2 end, float percent)
{
glm::vec2 a;
a.x = InOutQuad(start.x, end.x, percent);
a.y = InOutQuad(start.y, end.y, percent);
return a;
}
static glm::vec3 Linear(glm::vec3 start, glm::vec3 end, float percent)
{
glm::vec3 a;
a.x = Linear(start.x, end.x, percent);
a.y = Linear(start.y, end.y, percent);
a.z = Linear(start.z, end.z, percent);
return a;
}
static glm::vec3 InSine(glm::vec3 start, glm::vec3 end, float percent)
{
glm::vec3 a;
a.x = InSine(start.x, end.x, percent);
a.y = InSine(start.y, end.y, percent);
a.z = InSine(start.z, end.z, percent);
return a;
}
static glm::vec3 OutSine(glm::vec3 start, glm::vec3 end, float percent)
{
glm::vec3 a;
a.x = OutSine(start.x, end.x, percent);
a.y = OutSine(start.y, end.y, percent);
a.z = OutSine(start.z, end.z, percent);
return a;
}
static glm::vec3 InOutSine(glm::vec3 start, glm::vec3 end, float percent)
{
glm::vec3 a;
a.x = InOutSine(start.x, end.x, percent);
a.y = InOutSine(start.y, end.y, percent);
a.z = InOutSine(start.z, end.z, percent);
return a;
}
static glm::vec3 InQuad(glm::vec3 start, glm::vec3 end, float percent)
{
glm::vec3 a;
a.x = InQuad(start.x, end.x, percent);
a.y = InQuad(start.y, end.y, percent);
a.z = InQuad(start.z, end.z, percent);
return a;
}
static glm::vec3 OutQuad(glm::vec3 start, glm::vec3 end, float percent)
{
glm::vec3 a;
a.x = OutQuad(start.x, end.x, percent);
a.y = OutQuad(start.y, end.y, percent);
a.z = OutQuad(start.z, end.z, percent);
return a;
}
static glm::vec3 InOutQuad(glm::vec3 start, glm::vec3 end, float percent)
{
glm::vec3 a;
a.x = InOutQuad(start.x, end.x, percent);
a.y = InOutQuad(start.y, end.y, percent);
a.z = InOutQuad(start.z, end.z, percent);
return a;
}
static float Linear(float start, float end, float percent);
static float InSine(float start, float end, float percent);
static float OutSine(float start, float end, float percent);
static float InOutSine(float start, float end, float percent);
static float InQuad(float start, float end, float percent);
static float OutQuad(float start, float end, float percent);
static float InOutQuad(float start, float end, float percent);
};
#endif
--------------------------------------
#include "Tween.h"
#include <math.h>
#define PI 3.14159265
float Tween::Linear(float start, float end, float percent)
{
return start + (end - start)* percent;
}
float Tween::InSine(float start, float end, float percent)
{
return end - (end - start) * cos ( percent * PI / 2);
}
float Tween::OutSine(float start, float end, float percent)
{
return start + (end - start) * sin (percent * PI / 2);
}
float Tween::InOutSine(float start, float end, float percent)
{
return start + (end - start) / 2 * (1 - cos(percent * PI));
}
float Tween::InQuad(float start, float end, float percent)
{
return start + (end - start) * percent * percent;
}
float Tween::OutQuad(float start, float end, float percent)
{
return start + (end - start)*(2.0f* percent - percent* percent);
}
float Tween::InOutQuad(float start, float end, float percent)
{
if (percent < 0.5f)
return start + (end - start) * 2.0f * percent * percent;
return start + (end - start) * (1.5f * percent - 0.5f - percent * percent);
}
Tweener类
#ifndef Tweener_H
#define Tweener_H
#include <functional>
#include "ScheduleCommand.h"
#include "Time.h"
template <typename T>
class Tweener
{
private:
PerFrameScheduleCommand* _command;
std::function<void(void)> _complete;
std::function<void(T)> _fun;
std::function<T(T, T, float)> _easeFun;
T _start;
T _end;
float _time;
float _duration;
public:
bool isRunning;
Tweener(T start, T end, float duration, std::function<void(T)> fun, std::function<T(T, T, float)> ease)
{
_start = start;
_end = end;
_fun = fun;
_time = 0;
_duration = duration;
_easeFun = ease;
isRunning = true;
auto perFrameScheduleCommand = [this]()
{
_time += Time::GetDeltaTime();
T value = _easeFun(_start, _end, _time / _duration);
_fun(value);
};
auto complete = [this]()
{
if (_complete)
_complete();
isRunning = false;
};
_command = new PerFrameScheduleCommand(perFrameScheduleCommand, duration);
_command->onComplete = complete;
Time::PushCommand(_command);
}
void OnComplete(std::function<void(void)> complete)
{
_complete = complete;
}
void DoKill(bool finish)
{
if (!isRunning)
return;
if (!finish)
{
_command->isDispose = true;
delete this;
return;
}
_fun(_end);
if (_command->onComplete)
_command->onComplete();
_command->isDispose = true;
delete this;
}
};
#endif
--------------------------------
#include "Tweener.h"