Easing and splines for cameras and UI
I am Oriol Capdevila Salinas, student of the Bachelor’s Degree in Video Games by UPC at CITM. This content is made for the second year’s subject Project 2, under supervision of lecturer Ricard Pillosu.
Click here to see the presentation.
Problem & Solution
We have some problems when we have to move the camera or some UI because we just had one way to do it:
App->render->camera.x -= 100*dt;
We had to put a condition in order to finish it when we wanted. This might be fine for simple games and simple camera movements, but how could we have done this movement with this system: (the speed decreases with time)
It is not a difficult movement, but with our old system, this must have been hardcoded. So, my objective is that to make this movement and far more with just calling a function once, let’s start.
Introduction to Splines
In mathematics, a spline is a piecewise function defined by polynomials. This functions are usually used in programming because of the simplicity of their construction, their ease and accuracy of evaluation.
Easing Functions
These functions as its name says, are simplified functions that help to resolve difficult functions and their result is really accurated. These will give us the chance to use splines with a really easy method. They depend on four parameters:
- Current Time (t): Time that has passed since the spline started.
- Initial Value (b): In our case, the initial position of the element that we want to move.
- Final Value (c): In our case, the final position we want to have our element at the end of the spline.
- Duration (d): The time we want to complete the spline.
In my code, these parameters have a different name because I think they are more readable:
- Current Time (t): time_passed
- Initial Value (b): initial_position
- Final Value (c): distance_to_travel
- Duration (d): time_to_travel
Easing Functions Types
Using a power that its range is from 1 to 6:
- Linear: Power of 1.
- Quad: Power of 2.
- Cubic: Power of 3.
- Quart: Power of 4.
- Quint: Power of 5.
- Circ: Power of 6.
Some others that use differents math methods:
- Back: The object bypass the objective and then returns.
- Expo: Increases/decreases exponentially the initial value.
Each ease function, less the linear, has three different functions:
- Ease In: Describe the positive acceleration of the element that is being moved.
- Ease Out: Describe the negative acceleration of the element that is being moved.
- Ease In Out: It is a combination of the two movements described above, first Ease In and the Ease Out.
Graphic Help of each Function
- EaseInQuad:
- EaseOutQuad:
- EaseInOutQuad:
- EaseInCubic:
- EaseOutCubic:
- EaseInOutCubic:
- EaseInQuart:
- EaseOutQuart:
- EaseInOutQuart:
- EaseInQuint:
- EaseOutQuint:
- EaseInOutQuint:
- EaseInCirc:
- EaseOutCirc:
- EaseInOutCirc:
- EaseInExpo:
- EaseOutExpo:
- EaseInOutExpo:
- EaseInBack:
- EaseOutBack:
- EaseInOutBack:
Introduction to the code
In order to achieve my goal, I create a new module called EasingSplines. This module will manage all splines created.
Let’s see its core code.
First of all, it has a struct called EaseSplineInfo, this struct contains all the variables that are needed to have a spline:
- int * position: A pointer to the position of the element we want to move, thanks to that, we can change that value because we have the adress.
- int initial_position: The initial value of the element.
- int distance_to_travel: The distance we want to travel.
- float time_to_travel: The time we want to do the spline requested.
- float time_started: The time when the spline started.
- TypeSpline type: The type of spline is it.
- EaseFunctions ease_function: A variable to a struct that contains all the spline functions.
- bool Update(float dt): Function in which the spline makes its update.
Then, we have a struct that has all the easing functions in order to have all them in the same site.
We have an enum of all the spline type that areable to be used:
Our module has a list with all the splines created that have not finished.
In the Update of the module, we use this list to call each Update of our splines. When a spline has finished, it returns false so we must delete it.
Finally, we have our main function to create and add a new spline. This function needs 4 parameters (pointer to the value, the target value, the time to achive target value and the type of spline we want to use).
TODOs
Click here to download the full code.
Click here to download the release.
TODO 1
Create the constructor of the struct:
Solution
TODO 2
Calculate the time that has passed since the spline started. Save this value in a float.
Solution
TODO 3
Think how can we know if a spline has finished or not using the time calculated before. If the splines has finished, Update must end with a false in order to delete it
Solution
TODO 4
If the spline has not finished, make a switch with the spline type and call its type function. Look what this function returns!
Solution
TODO 5
Look the function CreateSpline() from EasingSplines.cpp, then use it to create one.
Solution
Improvements
- With this system, if we wanted to move the camera in X and Y at the same time we must create 2 splines. So it would be a great improvement to make it allow two values.
- Splines work with float, so we lose precision because the system works with int.
Author
Oriol Capdevila Salinas
- GitHub Account
- oriolcapdevilas@hotmail.com