从零开始的openGL--cs游戏(17) Tweener

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"

猜你喜欢

转载自blog.csdn.net/qq_41041725/article/details/122200352
今日推荐