Implemented sprite & added player animation.
This commit is contained in:
@@ -8,6 +8,8 @@
|
||||
#ifndef MODEL_PLAYER_H_
|
||||
#define MODEL_PLAYER_H_
|
||||
|
||||
#include <model/Direction.h>
|
||||
|
||||
namespace farmlands {
|
||||
namespace model {
|
||||
|
||||
@@ -16,6 +18,9 @@ namespace model {
|
||||
struct Player
|
||||
{
|
||||
float posX, posY;
|
||||
float lastDeltaX, lastDeltaY;
|
||||
Direction direction;
|
||||
|
||||
|
||||
int inventorySelection = -1;
|
||||
int inventory[PLAYER_INVENTORY_SIZE];
|
||||
|
102
src/model/Sprite.cpp
Normal file
102
src/model/Sprite.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Sprite.cpp
|
||||
*
|
||||
* Created on: Nov 29, 2016
|
||||
* Author: tibi
|
||||
*/
|
||||
|
||||
#include <model/Sprite.h>
|
||||
#include <utils/Assert.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace farmlands {
|
||||
namespace model {
|
||||
|
||||
Sprite::Sprite()
|
||||
: anchorX(0), anchorY(0),
|
||||
m_states(),
|
||||
m_currentState(0),
|
||||
m_currentFrame(0),
|
||||
m_currentFrameTimeLeft(0)
|
||||
{
|
||||
}
|
||||
|
||||
Sprite::~Sprite()
|
||||
{
|
||||
}
|
||||
|
||||
void Sprite::addState(const SpriteState& state)
|
||||
{
|
||||
Assert(state.frames.size() > 0, "State must have at least one frame!");
|
||||
#ifdef BUILD_DEBUG
|
||||
uint32_t 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!");
|
||||
|
||||
m_states.push_back(state);
|
||||
m_stateNames.emplace(state.name, m_states.size() - 1);
|
||||
}
|
||||
|
||||
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 * 1;
|
||||
}
|
||||
|
||||
void Sprite::setState(const std::string& name)
|
||||
{
|
||||
Assert(m_stateNames.count(name) > 0, "Inexistent state.");
|
||||
setState(m_stateNames.at(name));
|
||||
}
|
||||
|
||||
void Sprite::advanceTime(uint32_t steps)
|
||||
{
|
||||
Assert(m_states.size() > 0, "Sprite must have at least one state!");
|
||||
|
||||
while (steps > 0)
|
||||
{
|
||||
// There is time left in the current frame?
|
||||
if (m_currentFrameTimeLeft > 0)
|
||||
{
|
||||
uint32_t sub = std::min(steps, m_currentFrameTimeLeft);
|
||||
m_currentFrameTimeLeft -= sub;
|
||||
steps -= sub;
|
||||
}
|
||||
|
||||
if (m_currentFrameTimeLeft == 0)
|
||||
{
|
||||
// Move to the next frame
|
||||
if (++m_currentFrame >= currentState().frames.size())
|
||||
m_currentFrame = 0;
|
||||
|
||||
m_currentFrameTimeLeft = currentFrame().duration * 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SpriteState& Sprite::currentState()
|
||||
{
|
||||
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!");
|
||||
return currentState().frames.at(m_currentFrame);
|
||||
}
|
||||
|
||||
} /* namespace model */
|
||||
} /* namespace farmlands */
|
88
src/model/Sprite.h
Normal file
88
src/model/Sprite.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Sprite.h
|
||||
*
|
||||
* Created on: Nov 29, 2016
|
||||
* Author: tibi
|
||||
*/
|
||||
|
||||
#ifndef MODEL_SPRITE_H_
|
||||
#define MODEL_SPRITE_H_
|
||||
|
||||
#include <utils/Exceptions.h>
|
||||
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace farmlands {
|
||||
namespace model {
|
||||
|
||||
/**
|
||||
* Defines an animation frame
|
||||
*/
|
||||
struct Frame
|
||||
{
|
||||
uint32_t tileSetId;
|
||||
uint32_t tileSetCell;
|
||||
uint32_t width, height;
|
||||
uint32_t duration;
|
||||
};
|
||||
|
||||
/**
|
||||
* Defines a sprite state (aka an animation).
|
||||
*/
|
||||
struct SpriteState
|
||||
{
|
||||
std::string name;
|
||||
std::vector<Frame> frames;
|
||||
};
|
||||
|
||||
/**
|
||||
* Defines a sprite
|
||||
*/
|
||||
class Sprite
|
||||
{
|
||||
public:
|
||||
Sprite();
|
||||
virtual ~Sprite();
|
||||
|
||||
/**
|
||||
* Adds a state to the sprite.
|
||||
*/
|
||||
void addState(const SpriteState& state);
|
||||
|
||||
/**
|
||||
* Sets the current state.
|
||||
*/
|
||||
void setState(size_t stateId);
|
||||
|
||||
/**
|
||||
* Sets the current state.
|
||||
*/
|
||||
void setState(const std::string& name);
|
||||
|
||||
/**
|
||||
* Advances the current frame
|
||||
*/
|
||||
void advanceTime(uint32_t steps);
|
||||
|
||||
|
||||
// Getters
|
||||
SpriteState& currentState();
|
||||
Frame& currentFrame();
|
||||
|
||||
// Public fields
|
||||
float anchorX, anchorY;
|
||||
|
||||
private:
|
||||
std::vector<SpriteState> m_states;
|
||||
std::unordered_map<std::string, size_t> m_stateNames;
|
||||
|
||||
size_t m_currentState;
|
||||
size_t m_currentFrame;
|
||||
uint32_t m_currentFrameTimeLeft;
|
||||
};
|
||||
|
||||
} /* namespace model */
|
||||
} /* namespace farmlands */
|
||||
|
||||
#endif /* MODEL_SPRITE_H_ */
|
Reference in New Issue
Block a user