173 lines
3.7 KiB
C++
173 lines
3.7 KiB
C++
/*
|
|
* Sprite.cpp
|
|
*
|
|
* Created on: Nov 29, 2016
|
|
* Author: tibi
|
|
*/
|
|
|
|
#include <GameState.h>
|
|
#include <components/basic/Sprite.h>
|
|
#include <utils/Assert.h>
|
|
|
|
#include <algorithm>
|
|
#include <iostream>
|
|
|
|
namespace farmlands {
|
|
namespace components {
|
|
namespace basic {
|
|
|
|
Sprite::Sprite()
|
|
: w(1), h(1),
|
|
anchorX(0), anchorY(0),
|
|
animationSpeed(1.0f),
|
|
m_states(),
|
|
m_stateNames(),
|
|
m_currentState((size_t)-1),
|
|
m_currentFrame(0),
|
|
m_currentFrameTimeLeft(0)
|
|
{
|
|
}
|
|
|
|
Sprite::~Sprite()
|
|
{
|
|
}
|
|
|
|
model::Component* Sprite::clone()
|
|
{
|
|
Sprite* clone = new Sprite();
|
|
|
|
// Copy public fields
|
|
clone->w = w;
|
|
clone->h = h;
|
|
clone->anchorX = anchorX;
|
|
clone->anchorY = anchorY;
|
|
clone->animationSpeed = animationSpeed;
|
|
|
|
// Copy private members
|
|
std::copy(m_states.begin(), m_states.end(), std::back_inserter(clone->m_states));
|
|
std::copy(m_stateNames.begin(), m_stateNames.end(), std::inserter(clone->m_stateNames, clone->m_stateNames.end()));
|
|
clone->m_currentState = m_currentState;
|
|
clone->m_currentFrame = m_currentFrame;
|
|
clone->m_currentFrameTimeLeft = m_currentFrameTimeLeft;
|
|
|
|
return clone;
|
|
}
|
|
|
|
void Sprite::dump(unsigned level)
|
|
{
|
|
for (unsigned i = 0; i < level; i++)
|
|
std::cout<<" ";
|
|
|
|
std::cout << " .Component: Sprite ";
|
|
std::cout << "state="<<m_currentState<<"\n";
|
|
}
|
|
|
|
void Sprite::onPreRender()
|
|
{
|
|
advanceTime(GameState::current().deltaTime);
|
|
}
|
|
|
|
utils::RectF Sprite::boundaries() const
|
|
{
|
|
const float sX = gameObject->transform.globalScaleX();
|
|
const float sY = gameObject->transform.globalScaleY();
|
|
|
|
return utils::RectF(
|
|
gameObject->transform.globalX() - sX * anchorX * w,
|
|
gameObject->transform.globalY() - sY * anchorY * h,
|
|
sX * w, sY * h);
|
|
}
|
|
|
|
void Sprite::addState(const SpriteState& state)
|
|
{
|
|
Assert(m_stateNames.count(state.name) == 0, "A state with the same name already exists!");
|
|
|
|
m_states.push_back(state);
|
|
m_stateNames.emplace(state.name, m_states.size() - 1);
|
|
|
|
// First added state?
|
|
if (m_states.size() == 1)
|
|
{
|
|
m_currentState = 0;
|
|
}
|
|
}
|
|
|
|
SpriteState& Sprite::createState(const std::string& name)
|
|
{
|
|
SpriteState state = { .name = name };
|
|
addState(state);
|
|
|
|
return m_states.back();
|
|
}
|
|
|
|
SpriteState& Sprite::state(const std::string& name)
|
|
{
|
|
Assert(m_stateNames.count(name) != 0, "State doesn't exist.");
|
|
|
|
size_t index = m_stateNames.at(name);
|
|
return m_states.at(index);
|
|
}
|
|
|
|
SpriteState& Sprite::state(size_t stateId)
|
|
{
|
|
Assert(stateId < m_states.size(), "State ID doesn't exist.");
|
|
return m_states.at(stateId);
|
|
}
|
|
|
|
size_t Sprite::stateCount() const
|
|
{
|
|
return m_states.size();
|
|
}
|
|
|
|
void Sprite::setState(size_t stateId)
|
|
{
|
|
Assert(stateId < m_states.size(), "Inexistent state.");
|
|
|
|
// Avoid restarting the animation at every function call
|
|
if (stateId != m_currentState)
|
|
{
|
|
m_currentState = stateId;
|
|
m_currentFrame = 0;
|
|
m_currentFrameTimeLeft = currentFrame().duration;
|
|
}
|
|
}
|
|
|
|
void Sprite::setState(const std::string& name)
|
|
{
|
|
Assert(m_stateNames.count(name) > 0, "Inexistent state.");
|
|
setState(m_stateNames.at(name));
|
|
}
|
|
|
|
SpriteState& Sprite::currentState()
|
|
{
|
|
Assert(m_currentState != (size_t)-1, "No states have been added!!!");
|
|
Assert(m_states.size() > 0, "Sprite must have at least one state!");
|
|
return m_states.at(m_currentState);
|
|
}
|
|
|
|
Frame& Sprite::currentFrame()
|
|
{
|
|
Assert(m_currentFrame < currentState().frames.size(), "State must have at least one frame!");
|
|
return currentState().frames.at(m_currentFrame);
|
|
}
|
|
|
|
void Sprite::advanceTime(float fractions)
|
|
{
|
|
Assert(m_currentState != (size_t)-1, "No states have been added!");
|
|
|
|
m_currentFrameTimeLeft -= fractions * animationSpeed;
|
|
|
|
while (m_currentFrameTimeLeft <= 0)
|
|
{
|
|
// Move to the next frame
|
|
if (++m_currentFrame >= currentState().frames.size())
|
|
m_currentFrame = 0;
|
|
|
|
m_currentFrameTimeLeft += currentFrame().duration;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
} /* namespace farmlands */
|