Refactored sprite & transform. Replaced distance with collider when picking objects up.
This commit is contained in:
@ -60,17 +60,14 @@ void Grid::onInitialize()
|
||||
GameObject* obj = *it;
|
||||
|
||||
// Compute grid position(s)
|
||||
Rect<int> bounds(obj->transform.x, obj->transform.y, roundf(obj->transform.w), roundf(obj->transform.h));
|
||||
if (!bounds.intersects(m_bounds))
|
||||
if (!m_bounds.contains(obj->transform.x, obj->transform.y))
|
||||
{
|
||||
std::cerr << "Grid: ignoring object " << obj->name << ": object outside allowed bounds.";
|
||||
continue;
|
||||
}
|
||||
|
||||
// Set
|
||||
for (int y = bounds.y; y < bounds.y + bounds.h; y++)
|
||||
for (int x = bounds.x; x < bounds.x + bounds.w; x++)
|
||||
set(obj, x, y, false);
|
||||
set(obj, (int)obj->transform.x, (int)obj->transform.y, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,12 +17,12 @@ namespace components {
|
||||
namespace basic {
|
||||
|
||||
Sprite::Sprite()
|
||||
: name(),
|
||||
: w(1), h(1),
|
||||
anchorX(0), anchorY(0),
|
||||
animationVelocity(1.0f),
|
||||
animationSpeed(1.0f),
|
||||
m_states(),
|
||||
m_stateNames(),
|
||||
m_currentState(0),
|
||||
m_currentState((size_t)-1),
|
||||
m_currentFrame(0),
|
||||
m_currentFrameTimeLeft(0)
|
||||
{
|
||||
@ -37,12 +37,13 @@ model::Component* Sprite::clone()
|
||||
Sprite* clone = new Sprite();
|
||||
|
||||
// Copy public fields
|
||||
clone->name = name;
|
||||
clone->w = w;
|
||||
clone->h = h;
|
||||
clone->anchorX = anchorX;
|
||||
clone->anchorY = anchorY;
|
||||
clone->animationVelocity = animationVelocity;
|
||||
clone->animationSpeed = animationSpeed;
|
||||
|
||||
// Copy private memberes
|
||||
// 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;
|
||||
@ -58,7 +59,7 @@ void Sprite::dump(unsigned level)
|
||||
std::cout<<" ";
|
||||
|
||||
std::cout << " .Component: Sprite ";
|
||||
std::cout << "name="<<name<<"\n";
|
||||
std::cout << "state="<<m_currentState<<"\n";
|
||||
}
|
||||
|
||||
void Sprite::onPreRender()
|
||||
@ -66,33 +67,69 @@ 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(state.frames.size() > 0, "State must have at least one frame!");
|
||||
#ifdef BUILD_DEBUG
|
||||
float totalDuration = 0;
|
||||
for (auto frame : state.frames)
|
||||
totalDuration += frame.duration;
|
||||
|
||||
Assert(totalDuration > 0, "State must have a frame which last at least one tick.");
|
||||
#endif
|
||||
Assert(m_stateNames.count(state.name) == 0, "A state with the same name already added!");
|
||||
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 resetting state
|
||||
if (stateId == m_currentState)
|
||||
return;
|
||||
|
||||
m_currentState = stateId;
|
||||
m_currentFrame = 0;
|
||||
m_currentFrameTimeLeft = currentFrame().duration;
|
||||
// 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)
|
||||
@ -103,21 +140,22 @@ void Sprite::setState(const std::string& 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(currentState().frames.size() > 0, "State must have at least one frame!");
|
||||
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_states.size() > 0, "Sprite must have at least one state!");
|
||||
Assert(m_currentState != (size_t)-1, "No states have been added!");
|
||||
|
||||
m_currentFrameTimeLeft -= fractions * animationVelocity;
|
||||
m_currentFrameTimeLeft -= fractions * animationSpeed;
|
||||
|
||||
while (m_currentFrameTimeLeft <= 0)
|
||||
{
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include <model/Component.h>
|
||||
#include <utils/Exceptions.h>
|
||||
#include <utils/Rect.h>
|
||||
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
@ -25,7 +26,6 @@ namespace basic {
|
||||
{
|
||||
uint32_t tileSetId;
|
||||
uint32_t tileSetCell;
|
||||
uint32_t width, height;
|
||||
float duration;
|
||||
};
|
||||
|
||||
@ -53,28 +53,31 @@ namespace basic {
|
||||
virtual void onPreRender() override;
|
||||
|
||||
/**
|
||||
* Adds a state to the sprite.
|
||||
* Computes the boundaries of the sprite, considering all the elements:
|
||||
* - global coordinates and scale
|
||||
* - width and height
|
||||
* - anchor point
|
||||
*/
|
||||
utils::RectF boundaries() const;
|
||||
|
||||
// State management
|
||||
void addState(const SpriteState& state);
|
||||
SpriteState& createState(const std::string& name);
|
||||
SpriteState& state(const std::string& name);
|
||||
SpriteState& state(size_t stateId);
|
||||
size_t stateCount() const;
|
||||
|
||||
/**
|
||||
* Sets the current state.
|
||||
*/
|
||||
// Current state & frame
|
||||
void setState(size_t stateId);
|
||||
|
||||
/**
|
||||
* Sets the current state.
|
||||
*/
|
||||
void setState(const std::string& name);
|
||||
|
||||
// Getters
|
||||
SpriteState& currentState();
|
||||
Frame& currentFrame();
|
||||
|
||||
// Public fields
|
||||
std::string name;
|
||||
float w, h;
|
||||
float anchorX, anchorY;
|
||||
float animationVelocity;
|
||||
|
||||
float animationSpeed;
|
||||
|
||||
private:
|
||||
void advanceTime(float fractions);
|
||||
|
Reference in New Issue
Block a user