Large refactoring, using the Entity-Component model.
This commit is contained in:
parent
bcd0a359fc
commit
9c8cbf8518
23
src/GameState.cpp
Normal file
23
src/GameState.cpp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* GameState.cpp
|
||||||
|
*
|
||||||
|
* Created on: Nov 30, 2016
|
||||||
|
* Author: tibi
|
||||||
|
*/
|
||||||
|
#include <GameState.h>
|
||||||
|
|
||||||
|
namespace farmlands {
|
||||||
|
|
||||||
|
GameState GameState::s_current;
|
||||||
|
|
||||||
|
GameState& farmlands::GameState::current()
|
||||||
|
{
|
||||||
|
return s_current;
|
||||||
|
}
|
||||||
|
|
||||||
|
void farmlands::GameState::setCurrent(GameState& state)
|
||||||
|
{
|
||||||
|
s_current = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -8,11 +8,10 @@
|
|||||||
#ifndef MODEL_GAMESTATE_H_
|
#ifndef MODEL_GAMESTATE_H_
|
||||||
#define MODEL_GAMESTATE_H_
|
#define MODEL_GAMESTATE_H_
|
||||||
|
|
||||||
|
#include <base/GameObject.h>
|
||||||
|
#include <base/RenderContext.h>
|
||||||
#include <model/Level.h>
|
#include <model/Level.h>
|
||||||
#include <model/Player.h>
|
#include <model/Player.h>
|
||||||
#include <graphics/SdlRenderer.h>
|
|
||||||
#include <graphics/GameRenderer.h>
|
|
||||||
#include <graphics/GuiRenderer.h>
|
|
||||||
#include <model/Configuration.h>
|
#include <model/Configuration.h>
|
||||||
#include <resources/ResourceManager.h>
|
#include <resources/ResourceManager.h>
|
||||||
|
|
||||||
@ -20,32 +19,18 @@
|
|||||||
|
|
||||||
namespace farmlands {
|
namespace farmlands {
|
||||||
|
|
||||||
struct ViewportState
|
|
||||||
{
|
|
||||||
bool initialized;
|
|
||||||
int width, height;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Camera
|
|
||||||
{
|
|
||||||
float posX, posY;
|
|
||||||
float scale;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct GuiState
|
struct GuiState
|
||||||
{
|
{
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GameState
|
class GameState
|
||||||
{
|
{
|
||||||
// Resource layer
|
public:
|
||||||
resources::ResourceManager resManager;
|
static GameState& current();
|
||||||
|
static void setCurrent(GameState& state);
|
||||||
|
|
||||||
// Graphics layer
|
// Render context
|
||||||
graphics::SdlRenderer sdlRenderer;
|
base::RenderContext renderContext;
|
||||||
graphics::GuiRenderer guiRenderer;
|
|
||||||
graphics::GameRenderer gameRenderer;
|
|
||||||
|
|
||||||
// Gui
|
// Gui
|
||||||
GuiState gui;
|
GuiState gui;
|
||||||
@ -54,13 +39,14 @@ namespace farmlands {
|
|||||||
model::Configuration config;
|
model::Configuration config;
|
||||||
|
|
||||||
// Current game
|
// Current game
|
||||||
ViewportState viewport;
|
|
||||||
Camera camera;
|
|
||||||
model::Player player;
|
model::Player player;
|
||||||
model::Level* currentLevel;
|
model::Level* currentLevel;
|
||||||
|
base::GameObject root;
|
||||||
|
|
||||||
float elapsedTime;
|
float elapsedTime;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static GameState s_current;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
44
src/assets/Ground.h
Normal file
44
src/assets/Ground.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Ground.h
|
||||||
|
*
|
||||||
|
* Created on: Nov 30, 2016
|
||||||
|
* Author: tibi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ASSETS_GROUND_H_
|
||||||
|
#define ASSETS_GROUND_H_
|
||||||
|
|
||||||
|
namespace farmlands {
|
||||||
|
namespace assets {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps tiles to ground name
|
||||||
|
*/
|
||||||
|
enum class Ground
|
||||||
|
{
|
||||||
|
Dirt = 0,
|
||||||
|
DirtVariation0 = 1,
|
||||||
|
DirtVariation1 = 2,
|
||||||
|
DirtVariation2 = 3,
|
||||||
|
DirtVariation3 = 4,
|
||||||
|
DirtVariation4 = 5,
|
||||||
|
DirtVariation5 = 6,
|
||||||
|
DirtVariation6 = 7,
|
||||||
|
DirtVariation7 = 8,
|
||||||
|
DirtVariation8 = 9,
|
||||||
|
|
||||||
|
SoilCenter = 30,
|
||||||
|
|
||||||
|
SoilWet = 36
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool groundIsDirt(int cell) { return cell >= Ground::Dirt && cell <= Ground::DirtVariation8; }
|
||||||
|
inline bool groundIsDrySoil(int cell) { return cell == Ground::SoilCenter; }
|
||||||
|
inline bool groundIsWetSoil(int cell) { return cell == Ground::SoilWet; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* ASSETS_GROUND_H_ */
|
24
src/base/Camera.h
Normal file
24
src/base/Camera.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* Camera.h
|
||||||
|
*
|
||||||
|
* Created on: Nov 30, 2016
|
||||||
|
* Author: tibi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MODEL_CAMERA_H_
|
||||||
|
#define MODEL_CAMERA_H_
|
||||||
|
|
||||||
|
#include <base/Component.h>
|
||||||
|
|
||||||
|
namespace farmlands {
|
||||||
|
namespace base {
|
||||||
|
|
||||||
|
struct Camera : public Component
|
||||||
|
{
|
||||||
|
float scale;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* MODEL_CAMERA_H_ */
|
59
src/base/Component.cpp
Normal file
59
src/base/Component.cpp
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Component.cpp
|
||||||
|
*
|
||||||
|
* Created on: Nov 30, 2016
|
||||||
|
* Author: tibi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <base/Component.h>
|
||||||
|
|
||||||
|
namespace farmlands {
|
||||||
|
namespace base {
|
||||||
|
|
||||||
|
Component::Component()
|
||||||
|
: gameObject(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Component::~Component()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Component::onCreate()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Component::onInitialize()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Component::onEvent(SDL_Event& event)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Component::onUpdateLogic()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Component::onPreRender()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Component::onRender()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Component::onPostRender()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Component::onDestroy()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
/* namespace base */
|
||||||
|
} /* namespace farmlands */
|
||||||
|
|
||||||
|
|
41
src/base/Component.h
Normal file
41
src/base/Component.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Component.h
|
||||||
|
*
|
||||||
|
* Created on: Nov 30, 2016
|
||||||
|
* Author: tibi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef COMPONENT_H_
|
||||||
|
#define COMPONENT_H_
|
||||||
|
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
|
namespace farmlands {
|
||||||
|
namespace base {
|
||||||
|
|
||||||
|
class GameObject;
|
||||||
|
|
||||||
|
class Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Component();
|
||||||
|
virtual ~Component();
|
||||||
|
|
||||||
|
// Game object methods
|
||||||
|
virtual void onCreate();
|
||||||
|
virtual void onInitialize();
|
||||||
|
virtual bool onEvent(SDL_Event& event);
|
||||||
|
virtual void onUpdateLogic();
|
||||||
|
virtual void onPreRender();
|
||||||
|
virtual void onRender();
|
||||||
|
virtual void onPostRender();
|
||||||
|
virtual void onDestroy();
|
||||||
|
|
||||||
|
GameObject* gameObject;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
/* namespace base */
|
||||||
|
} /* namespace farmlands */
|
||||||
|
|
||||||
|
#endif /* COMPONENT_H_ */
|
155
src/base/GameObject.cpp
Normal file
155
src/base/GameObject.cpp
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
/*
|
||||||
|
* GameObject.cpp
|
||||||
|
*
|
||||||
|
* Created on: Nov 30, 2016
|
||||||
|
* Author: tibi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <base/GameObject.h>
|
||||||
|
#include <base/Component.h>
|
||||||
|
|
||||||
|
namespace farmlands {
|
||||||
|
namespace base {
|
||||||
|
|
||||||
|
GameObject::GameObject()
|
||||||
|
: m_components(),
|
||||||
|
m_children(),
|
||||||
|
m_parent(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
GameObject::~GameObject()
|
||||||
|
{
|
||||||
|
// Delete children
|
||||||
|
for (auto child : m_children)
|
||||||
|
{
|
||||||
|
child->onDestroy();
|
||||||
|
delete child;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete components
|
||||||
|
for (auto pair : m_components)
|
||||||
|
{
|
||||||
|
pair.second->onDestroy();
|
||||||
|
delete pair.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameObject::addChild(GameObject* obj)
|
||||||
|
{
|
||||||
|
m_children.push_back(obj);
|
||||||
|
obj->m_parent = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
GameObject* GameObject::removeChild(size_t index)
|
||||||
|
{
|
||||||
|
GameObject* child = m_children.at(index);
|
||||||
|
child->m_parent = nullptr;
|
||||||
|
|
||||||
|
m_children.erase(m_children.begin() + index);
|
||||||
|
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GameObject::childrenCount() const
|
||||||
|
{
|
||||||
|
return m_children.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
GameObject* GameObject::child(size_t index)
|
||||||
|
{
|
||||||
|
return m_children.at(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
GameObject* GameObject::parent()
|
||||||
|
{
|
||||||
|
return m_parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameObject::onCreate()
|
||||||
|
{
|
||||||
|
// Call components
|
||||||
|
for (auto pair : m_components)
|
||||||
|
pair.second->onCreate();
|
||||||
|
|
||||||
|
// Call children
|
||||||
|
for (auto child : m_children)
|
||||||
|
child->onCreate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameObject::onInitialize()
|
||||||
|
{
|
||||||
|
// Call components
|
||||||
|
for (auto pair : m_components)
|
||||||
|
pair.second->onInitialize();
|
||||||
|
|
||||||
|
// Call children
|
||||||
|
for (auto child : m_children)
|
||||||
|
child->onInitialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GameObject::onEvent(SDL_Event& event)
|
||||||
|
{
|
||||||
|
bool handled = false;
|
||||||
|
|
||||||
|
// Call components
|
||||||
|
for (auto it = m_components.begin(); it != m_components.end() && !handled; it++)
|
||||||
|
handled = it->second->onEvent(event);
|
||||||
|
|
||||||
|
// Call children
|
||||||
|
for (auto it = m_children.begin(); it != m_children.end() && !handled; it++)
|
||||||
|
handled = (*it)->onEvent(event);
|
||||||
|
|
||||||
|
return handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameObject::onUpdateLogic()
|
||||||
|
{
|
||||||
|
// Call components
|
||||||
|
for (auto pair : m_components)
|
||||||
|
pair.second->onUpdateLogic();
|
||||||
|
|
||||||
|
// Call children
|
||||||
|
for (auto child : m_children)
|
||||||
|
child->onUpdateLogic();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameObject::onPreRender()
|
||||||
|
{
|
||||||
|
// Call components
|
||||||
|
for (auto pair : m_components)
|
||||||
|
pair.second->onPreRender();
|
||||||
|
|
||||||
|
// Call children
|
||||||
|
for (auto child : m_children)
|
||||||
|
child->onPreRender();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameObject::onRender()
|
||||||
|
{
|
||||||
|
// Call components
|
||||||
|
for (auto pair : m_components)
|
||||||
|
pair.second->onRender();
|
||||||
|
|
||||||
|
// Call children
|
||||||
|
for (auto child : m_children)
|
||||||
|
child->onRender();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameObject::onPostRender()
|
||||||
|
{
|
||||||
|
// Call components
|
||||||
|
for (auto pair : m_components)
|
||||||
|
pair.second->onPostRender();
|
||||||
|
|
||||||
|
// Call children
|
||||||
|
for (auto child : m_children)
|
||||||
|
child->onPostRender();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameObject::onDestroy()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace base */
|
||||||
|
} /* namespace farmlands */
|
97
src/base/GameObject.h
Normal file
97
src/base/GameObject.h
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* GameObject.h
|
||||||
|
*
|
||||||
|
* Created on: Nov 30, 2016
|
||||||
|
* Author: tibi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GAMEOBJECT_H_
|
||||||
|
#define GAMEOBJECT_H_
|
||||||
|
|
||||||
|
#include <utils/Assert.h>
|
||||||
|
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
|
#include <typeindex>
|
||||||
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
namespace farmlands {
|
||||||
|
namespace base {
|
||||||
|
|
||||||
|
class Component;
|
||||||
|
class RenderContext;
|
||||||
|
|
||||||
|
class GameObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Constructors
|
||||||
|
GameObject();
|
||||||
|
virtual ~GameObject();
|
||||||
|
|
||||||
|
// Components API
|
||||||
|
template <typename T> void addComponent(T* component);
|
||||||
|
template <typename T> T* component();
|
||||||
|
template <typename T> void removeComponent();
|
||||||
|
|
||||||
|
// Tree methods
|
||||||
|
void addChild(GameObject* obj);
|
||||||
|
GameObject* removeChild(size_t index);
|
||||||
|
void destroyChild(size_t index);
|
||||||
|
GameObject* child(size_t index);
|
||||||
|
size_t childrenCount() const;
|
||||||
|
GameObject* parent();
|
||||||
|
|
||||||
|
// Game object methods
|
||||||
|
void onCreate();
|
||||||
|
void onInitialize();
|
||||||
|
bool onEvent(SDL_Event& event);
|
||||||
|
void onUpdateLogic();
|
||||||
|
void onPreRender();
|
||||||
|
void onRender();
|
||||||
|
void onPostRender();
|
||||||
|
void onDestroy();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unordered_map<std::type_index, Component*> m_components;
|
||||||
|
|
||||||
|
std::vector<GameObject*> m_children;
|
||||||
|
GameObject* m_parent;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void GameObject::addComponent(T* component)
|
||||||
|
{
|
||||||
|
std::type_index typeIndex(typeid(T));
|
||||||
|
Assert(m_components.count(typeIndex) == 0, "A component of the same type already exists!");
|
||||||
|
|
||||||
|
m_components.emplace(typeIndex, component);
|
||||||
|
component->gameObject = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T* GameObject::component()
|
||||||
|
{
|
||||||
|
// Compute type index
|
||||||
|
std::type_index typeIndex(typeid(T));
|
||||||
|
Assert(m_components.count(typeIndex) != 0, "Component doesn't exist!");
|
||||||
|
|
||||||
|
// Get component
|
||||||
|
T* comp = dynamic_cast<T*> (m_components.at(typeIndex));
|
||||||
|
Assert(comp != nullptr, "This is bad!!! Type of component is really messed up!!!");
|
||||||
|
|
||||||
|
return comp;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void GameObject::removeComponent()
|
||||||
|
{
|
||||||
|
std::type_index typeIndex(typeid(T));
|
||||||
|
return m_components.erase(typeIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace base */
|
||||||
|
} /* namespace farmlands */
|
||||||
|
|
||||||
|
#endif /* GAMEOBJECT_H_ */
|
47
src/base/RenderContext.cpp
Normal file
47
src/base/RenderContext.cpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* RenderContext.cpp
|
||||||
|
*
|
||||||
|
* Created on: Nov 30, 2016
|
||||||
|
* Author: tibi
|
||||||
|
*/
|
||||||
|
#include <base/Camera.h>
|
||||||
|
#include <base/GameObject.h>
|
||||||
|
#include <base/RenderContext.h>
|
||||||
|
#include <base/Transform.h>
|
||||||
|
|
||||||
|
namespace farmlands {
|
||||||
|
namespace base {
|
||||||
|
|
||||||
|
float RenderContext::xToWorld(float x)
|
||||||
|
{
|
||||||
|
float cellW = viewport.pixelsPerUnitX * m_camera->scale;
|
||||||
|
return (x - viewport.width / 2) / cellW + m_cameraTransform->x;
|
||||||
|
}
|
||||||
|
|
||||||
|
float RenderContext::yToWorld(float y)
|
||||||
|
{
|
||||||
|
float cellH = viewport.pixelsPerUnitY * m_camera->scale;
|
||||||
|
return (y - viewport.height / 2) / cellH + m_cameraTransform->y;
|
||||||
|
}
|
||||||
|
|
||||||
|
float RenderContext::xToScreen(float x)
|
||||||
|
{
|
||||||
|
float cellW = viewport.pixelsPerUnitX * m_camera->scale;
|
||||||
|
return (x - m_cameraTransform->x) * cellW + viewport.width / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
float RenderContext::yToScreen(float y)
|
||||||
|
{
|
||||||
|
float cellH = viewport.pixelsPerUnitY * m_camera->scale;
|
||||||
|
return (y - m_cameraTransform->y) * cellH + viewport.height / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderContext::setCamera(GameObject* camera)
|
||||||
|
{
|
||||||
|
m_cameraObj = camera;
|
||||||
|
m_cameraTransform = camera->component<Transform>();
|
||||||
|
m_camera = camera->component<Camera>();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
49
src/base/RenderContext.h
Normal file
49
src/base/RenderContext.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* RenderContext.h
|
||||||
|
*
|
||||||
|
* Created on: Nov 30, 2016
|
||||||
|
* Author: tibi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GRAPHICS_RENDERCONTEXT_H_
|
||||||
|
#define GRAPHICS_RENDERCONTEXT_H_
|
||||||
|
|
||||||
|
#include <base/Viewport.h>
|
||||||
|
|
||||||
|
namespace farmlands {
|
||||||
|
namespace base {
|
||||||
|
|
||||||
|
class GameObject;
|
||||||
|
struct Transform;
|
||||||
|
struct Camera;
|
||||||
|
|
||||||
|
class RenderContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
float xToWorld(float x);
|
||||||
|
float yToWorld(float y);
|
||||||
|
float xToScreen(float x);
|
||||||
|
float yToScreen(float y);
|
||||||
|
|
||||||
|
inline GameObject* cameraObj() { return m_cameraObj; }
|
||||||
|
inline Camera* camera() { return m_camera; }
|
||||||
|
inline Transform* cameraTransform() { return m_cameraTransform; }
|
||||||
|
|
||||||
|
void setCamera(GameObject* camera);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Screen properties
|
||||||
|
*/
|
||||||
|
Viewport viewport;
|
||||||
|
float uiScale = 1.0f;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Transform* m_cameraTransform;
|
||||||
|
Camera* m_camera;
|
||||||
|
GameObject* m_cameraObj;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* GRAPHICS_RENDERCONTEXT_H_ */
|
@ -5,16 +5,17 @@
|
|||||||
* Author: tibi
|
* Author: tibi
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <model/Sprite.h>
|
#include <base/Sprite.h>
|
||||||
#include <utils/Assert.h>
|
#include <utils/Assert.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
namespace farmlands {
|
namespace farmlands {
|
||||||
namespace model {
|
namespace base {
|
||||||
|
|
||||||
Sprite::Sprite()
|
Sprite::Sprite()
|
||||||
: anchorX(0), anchorY(0),
|
: anchorX(0), anchorY(0),
|
||||||
|
name(),
|
||||||
m_states(),
|
m_states(),
|
||||||
m_currentState(0),
|
m_currentState(0),
|
||||||
m_currentFrame(0),
|
m_currentFrame(0),
|
@ -14,7 +14,7 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace farmlands {
|
namespace farmlands {
|
||||||
namespace model {
|
namespace base {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines an animation frame
|
* Defines an animation frame
|
||||||
@ -72,6 +72,7 @@ namespace model {
|
|||||||
|
|
||||||
// Public fields
|
// Public fields
|
||||||
float anchorX, anchorY;
|
float anchorX, anchorY;
|
||||||
|
std::string name;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<SpriteState> m_states;
|
std::vector<SpriteState> m_states;
|
24
src/base/Transform.h
Normal file
24
src/base/Transform.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* Transform.h
|
||||||
|
*
|
||||||
|
* Created on: Nov 30, 2016
|
||||||
|
* Author: tibi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BASE_TRANSFORM_H_
|
||||||
|
#define BASE_TRANSFORM_H_
|
||||||
|
|
||||||
|
#include <base/Component.h>
|
||||||
|
|
||||||
|
namespace farmlands {
|
||||||
|
namespace base {
|
||||||
|
|
||||||
|
struct Transform: public Component
|
||||||
|
{
|
||||||
|
float x, y;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace base */
|
||||||
|
} /* namespace farmlands */
|
||||||
|
|
||||||
|
#endif /* BASE_TRANSFORM_H_ */
|
24
src/base/Viewport.h
Normal file
24
src/base/Viewport.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* Viewport.h
|
||||||
|
*
|
||||||
|
* Created on: Nov 30, 2016
|
||||||
|
* Author: tibi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MODEL_VIEWPORT_H_
|
||||||
|
#define MODEL_VIEWPORT_H_
|
||||||
|
|
||||||
|
namespace farmlands {
|
||||||
|
namespace base {
|
||||||
|
|
||||||
|
struct Viewport
|
||||||
|
{
|
||||||
|
bool initialized = false;
|
||||||
|
int width, height;
|
||||||
|
float pixelsPerUnitX, pixelsPerUnitY;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* MODEL_VIEWPORT_H_ */
|
53
src/controller/DebugController.cpp
Normal file
53
src/controller/DebugController.cpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* DebugController.cpp
|
||||||
|
*
|
||||||
|
* Created on: Nov 30, 2016
|
||||||
|
* Author: tibi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <GameState.h>
|
||||||
|
#include <base/Camera.h>
|
||||||
|
#include <controller/DebugController.h>
|
||||||
|
#include <input/Input.h>
|
||||||
|
|
||||||
|
using namespace farmlands::input;
|
||||||
|
|
||||||
|
namespace farmlands {
|
||||||
|
namespace controller {
|
||||||
|
|
||||||
|
static const float ScaleVelocity = 0.5f;
|
||||||
|
static const float ScaleShiftVelocity = 2.0f;
|
||||||
|
|
||||||
|
DebugController::DebugController()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugController::~DebugController()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugController::onInitialize()
|
||||||
|
{
|
||||||
|
m_camera = GameState::current().renderContext.camera();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugController::onUpdateLogic()
|
||||||
|
{
|
||||||
|
// Compute velocity
|
||||||
|
float vel = ScaleVelocity;
|
||||||
|
|
||||||
|
if (Input::instance().pressed(GameKey::Run))
|
||||||
|
vel = ScaleShiftVelocity;
|
||||||
|
|
||||||
|
// Time independent
|
||||||
|
vel *= GameState::current().elapsedTime;
|
||||||
|
|
||||||
|
if (Input::instance().pressed(GameKey::Debug_ZoomIn))
|
||||||
|
m_camera->scale *= 1 + vel;
|
||||||
|
|
||||||
|
if (Input::instance().pressed(GameKey::Debug_ZoomOut))
|
||||||
|
m_camera->scale *= 1 - vel;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace controller */
|
||||||
|
} /* namespace farmlands */
|
33
src/controller/DebugController.h
Normal file
33
src/controller/DebugController.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* DebugController.h
|
||||||
|
*
|
||||||
|
* Created on: Nov 30, 2016
|
||||||
|
* Author: tibi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CONTROLLER_DEBUGCONTROLLER_H_
|
||||||
|
#define CONTROLLER_DEBUGCONTROLLER_H_
|
||||||
|
|
||||||
|
#include <base/Component.h>
|
||||||
|
#include <base/Camera.h>
|
||||||
|
|
||||||
|
namespace farmlands {
|
||||||
|
namespace controller {
|
||||||
|
|
||||||
|
class DebugController: public base::Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DebugController();
|
||||||
|
virtual ~DebugController();
|
||||||
|
|
||||||
|
virtual void onInitialize() override;
|
||||||
|
virtual void onUpdateLogic() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
base::Camera* m_camera;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace controller */
|
||||||
|
} /* namespace farmlands */
|
||||||
|
|
||||||
|
#endif /* CONTROLLER_DEBUGCONTROLLER_H_ */
|
@ -5,7 +5,13 @@
|
|||||||
* Author: tibi
|
* Author: tibi
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "FarmlandsGame.h"
|
#include <base/GameObject.h>
|
||||||
|
#include <base/Camera.h>
|
||||||
|
#include <controller/DebugController.h>
|
||||||
|
#include <controller/FarmlandsGame.h>
|
||||||
|
#include <graphics/backend/SdlRenderer.h>
|
||||||
|
#include <graphics/BackgroundRenderer.h>
|
||||||
|
#include <graphics/SpriteRenderer.h>
|
||||||
#include <resources/Resources.h>
|
#include <resources/Resources.h>
|
||||||
|
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
@ -14,65 +20,123 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace farmlands::base;
|
||||||
|
using namespace farmlands::graphics;
|
||||||
|
using namespace farmlands::graphics::backend;
|
||||||
|
using namespace farmlands::resources;
|
||||||
|
|
||||||
namespace farmlands {
|
namespace farmlands {
|
||||||
namespace controller {
|
namespace controller {
|
||||||
|
|
||||||
FarmlandsGame::FarmlandsGame() :
|
FarmlandsGame::FarmlandsGame() :
|
||||||
m_running(true),
|
m_running(true),
|
||||||
m_gameState(),
|
m_time(0)
|
||||||
m_time(0),
|
|
||||||
m_guiController(),
|
|
||||||
m_playerController()
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FarmlandsGame::createScene()
|
||||||
|
{
|
||||||
|
// Create camera
|
||||||
|
Transform* cameraTransform = new Transform();
|
||||||
|
cameraTransform->x = 120;
|
||||||
|
cameraTransform->y = 100 - 1;
|
||||||
|
|
||||||
|
Camera* camera = new Camera();
|
||||||
|
camera->scale = 4.0f;
|
||||||
|
|
||||||
|
GameObject* cameraObj = new GameObject();
|
||||||
|
cameraObj->addComponent(cameraTransform);
|
||||||
|
cameraObj->addComponent(camera);
|
||||||
|
|
||||||
|
GameState::current().root.addChild(cameraObj);
|
||||||
|
GameState::current().renderContext.setCamera(cameraObj);
|
||||||
|
cameraObj->onCreate();
|
||||||
|
|
||||||
|
// Create background
|
||||||
|
BackgroundRenderer* backRenderer = new BackgroundRenderer();
|
||||||
|
backRenderer->level = GameState::current().currentLevel;
|
||||||
|
|
||||||
|
GameObject* backObj = new GameObject();
|
||||||
|
backObj->addComponent(backRenderer);
|
||||||
|
|
||||||
|
GameState::current().root.addChild(backObj);
|
||||||
|
backObj->onCreate();
|
||||||
|
|
||||||
|
// Create player
|
||||||
|
Transform* playerTransform = new Transform();
|
||||||
|
playerTransform->x = 120;
|
||||||
|
playerTransform->y = 100;
|
||||||
|
|
||||||
|
SpriteRenderer* playerRender = new SpriteRenderer();
|
||||||
|
playerRender->sprite = ResourceManager::instance().sprite(R::Sprites::Player);
|
||||||
|
|
||||||
|
PlayerController* playerCtrl = new PlayerController();
|
||||||
|
|
||||||
|
GameObject* playerObj = new GameObject();
|
||||||
|
playerObj->addComponent(playerTransform);
|
||||||
|
playerObj->addComponent(playerRender);
|
||||||
|
playerObj->addComponent(playerCtrl);
|
||||||
|
|
||||||
|
GameState::current().root.addChild(playerObj);
|
||||||
|
playerObj->onCreate();
|
||||||
|
|
||||||
|
// Create debug object
|
||||||
|
DebugController* dbgController = new DebugController();
|
||||||
|
|
||||||
|
GameObject* dbgObj = new GameObject();
|
||||||
|
dbgObj->addComponent(dbgController);
|
||||||
|
|
||||||
|
GameState::current().root.addChild(dbgObj);
|
||||||
|
dbgObj->onCreate();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
bool FarmlandsGame::initialize()
|
bool FarmlandsGame::initialize()
|
||||||
{
|
{
|
||||||
// Initialize game state
|
bool ok = true;
|
||||||
m_gameState.viewport.initialized = false;
|
|
||||||
m_gameState.camera.scale = 4;
|
|
||||||
|
|
||||||
// Initialize render system
|
// Initialize render system
|
||||||
if (!m_gameState.sdlRenderer.initialize(&m_gameState))
|
ok &= SdlRenderer::instance().initialize(&GameState::current().renderContext);
|
||||||
|
if (!ok)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_gameState.gameRenderer.initialize(&m_gameState);
|
|
||||||
m_gameState.guiRenderer.initialize(&m_gameState);
|
|
||||||
|
|
||||||
// Initialize controllers
|
|
||||||
m_guiController.initialize(&m_gameState);
|
|
||||||
m_playerController.initialize(&m_gameState);
|
|
||||||
|
|
||||||
// Initialize & load resources
|
// Initialize & load resources
|
||||||
m_gameState.resManager.initialize(&m_gameState);
|
ResourceManager::instance().initialize();
|
||||||
m_gameState.resManager.loadGameAssets();
|
ResourceManager::instance().loadGameAssets();
|
||||||
m_gameState.resManager.loadLevel(resources::R::Levels::Farm);
|
ResourceManager::instance().loadLevel(resources::R::Levels::Farm);
|
||||||
m_gameState.currentLevel = m_gameState.resManager.level(resources::R::Levels::Farm);
|
GameState::current().currentLevel = ResourceManager::instance().level(resources::R::Levels::Farm);
|
||||||
|
GameState::current().renderContext.viewport.pixelsPerUnitX = GameState::current().currentLevel->m_cellWidth;
|
||||||
|
GameState::current().renderContext.viewport.pixelsPerUnitY = GameState::current().currentLevel->m_cellHeight;
|
||||||
|
|
||||||
|
// Set up scene
|
||||||
|
createScene();
|
||||||
|
|
||||||
|
// Finish initialization
|
||||||
|
GameState::current().root.onInitialize();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FarmlandsGame::onUpdateLogic()
|
void FarmlandsGame::onUpdateLogic()
|
||||||
{
|
{
|
||||||
m_playerController.updateLogic();
|
GameState::current().root.onUpdateLogic();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FarmlandsGame::onPreRender()
|
||||||
|
{
|
||||||
|
GameState::current().root.onPreRender();
|
||||||
|
SdlRenderer::instance().renderBegin();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FarmlandsGame::onRender()
|
void FarmlandsGame::onRender()
|
||||||
{
|
{
|
||||||
m_gameState.sdlRenderer.renderBegin();
|
GameState::current().root.onRender();
|
||||||
m_gameState.gameRenderer.render();
|
|
||||||
// m_gameState.guiRenderer.render();
|
|
||||||
m_guiController.render();
|
|
||||||
m_gameState.sdlRenderer.renderEnd();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FarmlandsGame::onEvent(SDL_Event& event)
|
void FarmlandsGame::onEvent(SDL_Event& event)
|
||||||
{
|
{
|
||||||
// Let controllers handle event
|
// Let controllers handle event
|
||||||
if (m_guiController.processEvent(event))
|
if (GameState::current().root.onEvent(event))
|
||||||
return;
|
|
||||||
|
|
||||||
if (m_playerController.processEvent(event))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Nobody? Handle global events
|
// Nobody? Handle global events
|
||||||
@ -92,9 +156,16 @@ void FarmlandsGame::onEvent(SDL_Event& event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FarmlandsGame::onPostRender()
|
||||||
|
{
|
||||||
|
SdlRenderer::instance().renderEnd();
|
||||||
|
GameState::current().root.onPostRender();
|
||||||
|
}
|
||||||
|
|
||||||
void FarmlandsGame::stop()
|
void FarmlandsGame::stop()
|
||||||
{
|
{
|
||||||
m_running = false;
|
m_running = false;
|
||||||
|
GameState::current().root.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
int FarmlandsGame::run()
|
int FarmlandsGame::run()
|
||||||
@ -108,7 +179,7 @@ int FarmlandsGame::run()
|
|||||||
{
|
{
|
||||||
// Update elapsed time
|
// Update elapsed time
|
||||||
Uint32 now = SDL_GetTicks();
|
Uint32 now = SDL_GetTicks();
|
||||||
m_gameState.elapsedTime = (now - m_time) * 0.001f;
|
GameState::current().elapsedTime = (now - m_time) * 0.001f;
|
||||||
m_time = now;
|
m_time = now;
|
||||||
|
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
@ -116,7 +187,9 @@ int FarmlandsGame::run()
|
|||||||
onEvent(event);
|
onEvent(event);
|
||||||
|
|
||||||
onUpdateLogic();
|
onUpdateLogic();
|
||||||
|
onPreRender();
|
||||||
onRender();
|
onRender();
|
||||||
|
onPostRender();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cleanup
|
// Cleanup
|
||||||
|
@ -11,8 +11,6 @@
|
|||||||
#include <GameState.h>
|
#include <GameState.h>
|
||||||
#include <controller/GuiController.h>
|
#include <controller/GuiController.h>
|
||||||
#include <controller/PlayerController.h>
|
#include <controller/PlayerController.h>
|
||||||
#include <graphics/GameRenderer.h>
|
|
||||||
#include <graphics/SdlRenderer.h>
|
|
||||||
#include <resources/ResourceManager.h>
|
#include <resources/ResourceManager.h>
|
||||||
|
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
@ -29,19 +27,19 @@ namespace controller {
|
|||||||
protected:
|
protected:
|
||||||
bool initialize();
|
bool initialize();
|
||||||
|
|
||||||
void onUpdateLogic();
|
|
||||||
void onRender();
|
|
||||||
void onEvent(SDL_Event& event);
|
void onEvent(SDL_Event& event);
|
||||||
|
void onUpdateLogic();
|
||||||
|
void onPreRender();
|
||||||
|
void onRender();
|
||||||
|
void onPostRender();
|
||||||
|
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_running;
|
void createScene();
|
||||||
GameState m_gameState;
|
|
||||||
Uint32 m_time;
|
|
||||||
|
|
||||||
GuiController m_guiController;
|
bool m_running;
|
||||||
PlayerController m_playerController;
|
Uint32 m_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,18 +7,15 @@
|
|||||||
|
|
||||||
#include <GameState.h>
|
#include <GameState.h>
|
||||||
#include <controller/GuiController.h>
|
#include <controller/GuiController.h>
|
||||||
#include <gui/RenderContext.h>
|
|
||||||
#include <gui/widgets/TextArea.h>
|
#include <gui/widgets/TextArea.h>
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
namespace farmlands
|
namespace farmlands
|
||||||
{
|
{
|
||||||
namespace controller
|
namespace controller
|
||||||
{
|
{
|
||||||
|
|
||||||
GuiController::GuiController()
|
GuiController::GuiController()
|
||||||
: m_gameState(nullptr)
|
: m_canvas()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,15 +23,12 @@ GuiController::~GuiController()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiController::initialize(GameState* gameState)
|
void GuiController::onInitialize()
|
||||||
{
|
{
|
||||||
assert(gameState != nullptr);
|
m_context = &GameState::current().renderContext;
|
||||||
assert(gameState->viewport.initialized);
|
|
||||||
|
|
||||||
m_gameState = gameState;
|
|
||||||
|
|
||||||
// Set up canvas
|
// Set up canvas
|
||||||
m_canvas.setSize(m_gameState->viewport.width, m_gameState->viewport.height);
|
m_canvas.setSize(m_context->viewport.width, m_context->viewport.height);
|
||||||
|
|
||||||
// Add a text element
|
// Add a text element
|
||||||
auto text = new gui::widgets::TextArea();
|
auto text = new gui::widgets::TextArea();
|
||||||
@ -50,7 +44,7 @@ void GuiController::initialize(GameState* gameState)
|
|||||||
m_canvas.addChild(text);
|
m_canvas.addChild(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GuiController::processEvent(SDL_Event& event)
|
bool GuiController::onEvent(SDL_Event& event)
|
||||||
{
|
{
|
||||||
bool handled = m_canvas.handleEvent(event);
|
bool handled = m_canvas.handleEvent(event);
|
||||||
|
|
||||||
@ -69,18 +63,11 @@ bool GuiController::processEvent(SDL_Event& event)
|
|||||||
return handled;
|
return handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiController::render()
|
void GuiController::onRender()
|
||||||
{
|
{
|
||||||
// Compute render context
|
// Compute render context
|
||||||
gui::RenderContext renderContext =
|
|
||||||
{
|
|
||||||
.sdlRenderer = &m_gameState->sdlRenderer,
|
|
||||||
.resManager = &m_gameState->resManager,
|
|
||||||
.uiScale = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Render
|
// Render
|
||||||
m_canvas.render(renderContext);
|
m_canvas.render(m_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace controller */
|
} /* namespace controller */
|
||||||
|
@ -8,18 +8,16 @@
|
|||||||
#ifndef CONTROLLER_GUICONTROLLER_H_
|
#ifndef CONTROLLER_GUICONTROLLER_H_
|
||||||
#define CONTROLLER_GUICONTROLLER_H_
|
#define CONTROLLER_GUICONTROLLER_H_
|
||||||
|
|
||||||
|
#include <base/Component.h>
|
||||||
|
#include <base/RenderContext.h>
|
||||||
#include <gui/layout/Canvas.h>
|
#include <gui/layout/Canvas.h>
|
||||||
|
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
namespace farmlands {
|
namespace farmlands {
|
||||||
|
|
||||||
// Forward declarations
|
|
||||||
struct GameState;
|
|
||||||
|
|
||||||
namespace controller {
|
namespace controller {
|
||||||
|
|
||||||
class GuiController
|
class GuiController : public base::Component
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GuiController();
|
GuiController();
|
||||||
@ -28,21 +26,13 @@ namespace controller {
|
|||||||
/**
|
/**
|
||||||
* Initializes game renderer
|
* Initializes game renderer
|
||||||
*/
|
*/
|
||||||
void initialize(GameState* gameState);
|
virtual void onInitialize() override;
|
||||||
|
virtual bool onEvent(SDL_Event& event) override;
|
||||||
/**
|
virtual void onRender() override;
|
||||||
* Processes an UI event
|
|
||||||
*/
|
|
||||||
bool processEvent(SDL_Event& event);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders the GUI
|
|
||||||
*/
|
|
||||||
void render();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GameState* m_gameState;
|
|
||||||
gui::layout::Canvas m_canvas;
|
gui::layout::Canvas m_canvas;
|
||||||
|
base::RenderContext* m_context;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace controller */
|
} /* namespace controller */
|
||||||
|
@ -7,13 +7,48 @@
|
|||||||
|
|
||||||
#include <GameState.h>
|
#include <GameState.h>
|
||||||
#include <controller/PlayerController.h>
|
#include <controller/PlayerController.h>
|
||||||
|
#include <graphics/SpriteRenderer.h>
|
||||||
|
#include <input/Input.h>
|
||||||
#include <utils/Assert.h>
|
#include <utils/Assert.h>
|
||||||
|
|
||||||
|
using namespace farmlands::input;
|
||||||
|
using namespace farmlands::graphics;
|
||||||
|
using namespace farmlands::model;
|
||||||
|
|
||||||
namespace farmlands {
|
namespace farmlands {
|
||||||
namespace controller {
|
namespace controller {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default velocity of the player when walking (units/sec).
|
||||||
|
*/
|
||||||
|
static const float PlayerWalkVelocity = 2.0f;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default velocity of the player when running (units/sec).
|
||||||
|
*/
|
||||||
|
static const float PlayerRunVelocity = 4.0f;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Movement speed when attacking.
|
||||||
|
*/
|
||||||
|
static const float PlayerAttackVelocity = 0.1f;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Direction enum based on sign of velocity on x and y
|
||||||
|
*/
|
||||||
|
static const Direction VelocitySignDirections[3][3] =
|
||||||
|
{
|
||||||
|
{ Direction::NorthWest, Direction::West, Direction::SouthWest },
|
||||||
|
{ Direction::North, Direction::None, Direction::South },
|
||||||
|
{ Direction::NorthEast, Direction::East, Direction::SouthEast },
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
PlayerController::PlayerController()
|
PlayerController::PlayerController()
|
||||||
: m_gameState(nullptr)
|
: m_transform(nullptr),
|
||||||
|
m_attackTimeLeft(0),
|
||||||
|
m_vx(0), m_vy(0),
|
||||||
|
m_facingDirection(Direction::South)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,61 +56,88 @@ PlayerController::~PlayerController()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerController::initialize(GameState* gameState)
|
void PlayerController::onInitialize()
|
||||||
{
|
{
|
||||||
Assert(gameState != nullptr, "Game state must not be NULL!");
|
m_transform = gameObject->component<base::Transform>();
|
||||||
|
|
||||||
m_gameState = gameState;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PlayerController::processEvent(SDL_Event& event)
|
bool PlayerController::onEvent(SDL_Event& event)
|
||||||
{
|
{
|
||||||
|
bool attack1 = (Input::instance().down(GameKey::Action, event));
|
||||||
|
bool attack2 = (Input::instance().down(GameKey::Action2, event));
|
||||||
|
|
||||||
|
if (m_attackTimeLeft == 0 && (attack1 || attack2))
|
||||||
|
{
|
||||||
|
attack();
|
||||||
|
m_attackTimeLeft = 20 + attack2 * 20;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerController::updateLogic()
|
void PlayerController::onUpdateLogic()
|
||||||
{
|
{
|
||||||
// Get keyboard status
|
// Compute movement velocity
|
||||||
const Uint8* keys = SDL_GetKeyboardState(NULL);
|
float velMultiplier = PlayerWalkVelocity;
|
||||||
|
|
||||||
float deltaX = 0;
|
if (Input::instance().pressed(GameKey::Run))
|
||||||
float deltaY = 0;
|
velMultiplier = PlayerRunVelocity;
|
||||||
|
|
||||||
// Compute movement delta multiplier
|
if (m_attackTimeLeft)
|
||||||
float deltaMultiplier = 5.0f * m_gameState->elapsedTime; // Equivalent to units per second
|
|
||||||
if (keys[m_gameState->config.keys.Run])
|
|
||||||
deltaMultiplier *= 5;
|
|
||||||
|
|
||||||
// Handle scale changes (debugging only)
|
|
||||||
if (keys[m_gameState->config.keys.Debug_ZoomOut])
|
|
||||||
m_gameState->camera.scale *= 1.0f - 0.05f * deltaMultiplier;
|
|
||||||
if (keys[m_gameState->config.keys.Debug_ZoomIn])
|
|
||||||
m_gameState->camera.scale *= 1.0f + 0.05f * deltaMultiplier;
|
|
||||||
|
|
||||||
// Handle movement
|
|
||||||
if (keys[m_gameState->config.keys.Right] || keys[m_gameState->config.keys.AltRight])
|
|
||||||
deltaX += 1;
|
|
||||||
if (keys[m_gameState->config.keys.Up] || keys[m_gameState->config.keys.AltUp])
|
|
||||||
deltaY -= 1;
|
|
||||||
if (keys[m_gameState->config.keys.Left] || keys[m_gameState->config.keys.AltLeft])
|
|
||||||
deltaX -= 1;
|
|
||||||
if (keys[m_gameState->config.keys.Down] || keys[m_gameState->config.keys.AltDown])
|
|
||||||
deltaY += 1;
|
|
||||||
|
|
||||||
float newX = m_gameState->player.posX + deltaX * deltaMultiplier;
|
|
||||||
float newY = m_gameState->player.posY + deltaY * deltaMultiplier;
|
|
||||||
|
|
||||||
if (canMove(newX, newY))
|
|
||||||
{
|
{
|
||||||
m_gameState->player.posX = newX;
|
velMultiplier = PlayerAttackVelocity;
|
||||||
m_gameState->player.posY = newY;
|
--m_attackTimeLeft;
|
||||||
m_gameState->player.lastDeltaX = deltaX * deltaMultiplier;
|
|
||||||
m_gameState->player.lastDeltaY = deltaY * deltaMultiplier;
|
|
||||||
setDirection(deltaX, deltaY);
|
|
||||||
|
|
||||||
m_gameState->camera.posX = m_gameState->player.posX;
|
|
||||||
m_gameState->camera.posY = m_gameState->player.posY - 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make movement time independent
|
||||||
|
velMultiplier *= GameState::current().elapsedTime;
|
||||||
|
|
||||||
|
// Get velocity of axes
|
||||||
|
float vx = Input::instance().getX() * velMultiplier;
|
||||||
|
float vy = Input::instance().getY() * velMultiplier;
|
||||||
|
|
||||||
|
// Check if we can move to the new position
|
||||||
|
float newX = m_transform->x + m_vx;
|
||||||
|
float newY = m_transform->y + m_vy;
|
||||||
|
if ((vx || vy) && canMove(newX, newY))
|
||||||
|
{
|
||||||
|
m_vx = vx;
|
||||||
|
m_vy = vy;
|
||||||
|
m_transform->x = newX;
|
||||||
|
m_transform->y = newY;
|
||||||
|
|
||||||
|
m_facingDirection = getDirection(vx, vy);
|
||||||
|
|
||||||
|
base::Transform* cam = GameState::current().renderContext.cameraTransform();
|
||||||
|
cam->x = newX;
|
||||||
|
cam->y = newY - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_vx = 0;
|
||||||
|
m_vy = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerController::onPreRender()
|
||||||
|
{
|
||||||
|
// Get sprite
|
||||||
|
SpriteRenderer* spriteRenderer = gameObject->component<SpriteRenderer>();
|
||||||
|
|
||||||
|
// Compute current state
|
||||||
|
bool idle = (m_vx == 0 && m_vy == 0);
|
||||||
|
std::string stateName = (idle) ? "Idle " : "Walking ";
|
||||||
|
|
||||||
|
if (m_facingDirection & Direction::East)
|
||||||
|
stateName += "right";
|
||||||
|
else if (m_facingDirection & Direction::West)
|
||||||
|
stateName += "left";
|
||||||
|
else if (m_facingDirection & Direction::North)
|
||||||
|
stateName += "up";
|
||||||
|
else
|
||||||
|
stateName += "down";
|
||||||
|
|
||||||
|
spriteRenderer->sprite->setState(stateName);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PlayerController::canMove(float x, float y)
|
bool PlayerController::canMove(float x, float y)
|
||||||
@ -84,20 +146,17 @@ bool PlayerController::canMove(float x, float y)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const model::Direction directions[3][3] =
|
Direction PlayerController::getDirection(float vx, float vy)
|
||||||
{
|
{
|
||||||
{ model::Direction::NorthWest, model::Direction::West, model::Direction::SouthWest },
|
int xx = (0 < vx) - (vx < 0);
|
||||||
{ model::Direction::North, model::Direction::South, model::Direction::South },
|
int yy = (0 < vy) - (vy < 0);
|
||||||
{ model::Direction::NorthEast, model::Direction::East, model::Direction::SouthEast },
|
|
||||||
};
|
|
||||||
|
|
||||||
void PlayerController::setDirection(float dx, float dy)
|
return VelocitySignDirections[xx + 1][yy + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerController::attack()
|
||||||
{
|
{
|
||||||
int xx = (0 < dx) - (dx < 0);
|
// For now - nothing
|
||||||
int yy = (0 < dy) - (dy < 0);
|
|
||||||
|
|
||||||
if (xx != 0 || yy != 0)
|
|
||||||
m_gameState->player.direction = directions[xx + 1][yy + 1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace controller */
|
} /* namespace controller */
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
#ifndef CONTROLLER_PLAYERCONTROLLER_H_
|
#ifndef CONTROLLER_PLAYERCONTROLLER_H_
|
||||||
#define CONTROLLER_PLAYERCONTROLLER_H_
|
#define CONTROLLER_PLAYERCONTROLLER_H_
|
||||||
|
|
||||||
|
#include <base/Component.h>
|
||||||
|
#include <base/Transform.h>
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
namespace farmlands {
|
namespace farmlands {
|
||||||
@ -17,34 +19,27 @@ struct GameState;
|
|||||||
|
|
||||||
namespace controller {
|
namespace controller {
|
||||||
|
|
||||||
class PlayerController
|
class PlayerController : public base::Component
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PlayerController();
|
PlayerController();
|
||||||
virtual ~PlayerController();
|
virtual ~PlayerController();
|
||||||
|
|
||||||
/**
|
virtual void onInitialize() override;
|
||||||
* Initializes game renderer
|
virtual bool onEvent(SDL_Event& event) override;
|
||||||
*/
|
virtual void onUpdateLogic() override;
|
||||||
void initialize(GameState* gameState);
|
virtual void onPreRender() override;
|
||||||
|
|
||||||
/**
|
|
||||||
* Processes an event.
|
|
||||||
*
|
|
||||||
* @returns true if the event was handled, or false otherwise.
|
|
||||||
*/
|
|
||||||
bool processEvent(SDL_Event& event);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called at the update logic step for every frame
|
|
||||||
*/
|
|
||||||
void updateLogic();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool canMove(float x, float y);
|
static model::Direction getDirection(float vx, float vy);
|
||||||
void setDirection(float dx, float dy);
|
|
||||||
|
|
||||||
GameState* m_gameState;
|
bool canMove(float x, float y);
|
||||||
|
void attack();
|
||||||
|
|
||||||
|
base::Transform* m_transform;
|
||||||
|
uint32_t m_attackTimeLeft;
|
||||||
|
float m_vx, m_vy;
|
||||||
|
model::Direction m_facingDirection;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace controller */
|
} /* namespace controller */
|
||||||
|
108
src/graphics/BackgroundRenderer.cpp
Normal file
108
src/graphics/BackgroundRenderer.cpp
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
* BackgroundRenderer.cpp
|
||||||
|
*
|
||||||
|
* Created on: Nov 30, 2016
|
||||||
|
* Author: tibi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <GameState.h>
|
||||||
|
#include <base/GameObject.h>
|
||||||
|
#include <graphics/backend/SdlRenderer.h>
|
||||||
|
#include <graphics/BackgroundRenderer.h>
|
||||||
|
#include <resources/ResourceManager.h>
|
||||||
|
#include <math/GameMath.h>
|
||||||
|
#include <utils/Assert.h>
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
using namespace farmlands::graphics::backend;
|
||||||
|
using namespace farmlands::resources;
|
||||||
|
|
||||||
|
namespace farmlands {
|
||||||
|
namespace graphics {
|
||||||
|
|
||||||
|
BackgroundRenderer::BackgroundRenderer()
|
||||||
|
: level(nullptr),
|
||||||
|
m_context(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
BackgroundRenderer::~BackgroundRenderer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackgroundRenderer::onInitialize()
|
||||||
|
{
|
||||||
|
Assert(gameObject != nullptr, "Component not properly initialized!");
|
||||||
|
|
||||||
|
m_context = &GameState::current().renderContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackgroundRenderer::onRender()
|
||||||
|
{
|
||||||
|
float cellW = m_context->viewport.pixelsPerUnitX * m_context->camera()->scale;
|
||||||
|
float cellH = m_context->viewport.pixelsPerUnitY * m_context->camera()->scale;
|
||||||
|
|
||||||
|
// Compute how many cells fit on the screen
|
||||||
|
float cellsOnScreenX = m_context->viewport.width / cellW;
|
||||||
|
float cellsOnScreenY = m_context->viewport.height / cellH;
|
||||||
|
|
||||||
|
int minCellX = floorf(m_context->cameraTransform()->x - cellsOnScreenX / 2);
|
||||||
|
int maxCellX = ceilf(m_context->cameraTransform()->x + cellsOnScreenX / 2);
|
||||||
|
int minCellY = floorf(m_context->cameraTransform()->y - cellsOnScreenY / 2);
|
||||||
|
int maxCellY = ceilf(m_context->cameraTransform()->y + cellsOnScreenY / 2);
|
||||||
|
|
||||||
|
// Clamp cell positions
|
||||||
|
minCellX = clamp(minCellX, 0, (int)level->columnCount() - 1);
|
||||||
|
maxCellX = clamp(maxCellX, 0, (int)level->columnCount() - 1);
|
||||||
|
minCellY = clamp(minCellY, 0, (int)level->rowCount() - 1);
|
||||||
|
maxCellY = clamp(maxCellY, 0, (int)level->rowCount() - 1);
|
||||||
|
|
||||||
|
// Draw each layer
|
||||||
|
for (size_t i = 0; i < level->layerCount(); i++)
|
||||||
|
{
|
||||||
|
int textureId = level->texture(i);
|
||||||
|
|
||||||
|
// Render only visible tiles
|
||||||
|
for (int y = minCellY; y <= maxCellY; y++)
|
||||||
|
for (int x = minCellX; x <= maxCellX; x++)
|
||||||
|
{
|
||||||
|
int cellId = level->cell(i, y, x);
|
||||||
|
|
||||||
|
// Obtain texture
|
||||||
|
SDL_Texture* texture = ResourceManager::instance().texture(textureId);
|
||||||
|
|
||||||
|
// Calculate source rect
|
||||||
|
SDL_Rect src;
|
||||||
|
getCell(texture, cellId, &src.x, &src.y);
|
||||||
|
src.w = m_context->viewport.pixelsPerUnitX;
|
||||||
|
src.h = m_context->viewport.pixelsPerUnitY;
|
||||||
|
|
||||||
|
// Compute destination rect
|
||||||
|
SDL_Rect dest;
|
||||||
|
dest.x = floorf(m_context->xToScreen(x));
|
||||||
|
dest.y = floorf(m_context->yToScreen(y));
|
||||||
|
dest.w = ceilf(cellW);
|
||||||
|
dest.h = ceilf(cellH);
|
||||||
|
|
||||||
|
// Blit
|
||||||
|
SdlRenderer::instance().renderTexture(texture, &src, &dest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackgroundRenderer::getCell(SDL_Texture* texture, uint32_t cell, int* outX, int* outY)
|
||||||
|
{
|
||||||
|
int texWidth, texHeight;
|
||||||
|
SdlRenderer::instance().getTextureSize(texture, &texWidth, &texHeight);
|
||||||
|
|
||||||
|
int ppuX = m_context->viewport.pixelsPerUnitX;
|
||||||
|
int ppuY = m_context->viewport.pixelsPerUnitY;
|
||||||
|
|
||||||
|
// Compute texture coordinates
|
||||||
|
*outX = (cell * ppuX) % texWidth;
|
||||||
|
*outY = ((cell * ppuX) / texWidth) * ppuY;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace graphics */
|
||||||
|
} /* namespace farmlands */
|
41
src/graphics/BackgroundRenderer.h
Normal file
41
src/graphics/BackgroundRenderer.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* BackgroundRenderer.h
|
||||||
|
*
|
||||||
|
* Created on: Nov 30, 2016
|
||||||
|
* Author: tibi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GRAPHICS_BACKGROUNDRENDERER_H_
|
||||||
|
#define GRAPHICS_BACKGROUNDRENDERER_H_
|
||||||
|
|
||||||
|
#include <base/Component.h>
|
||||||
|
#include <base/Camera.h>
|
||||||
|
#include <base/Transform.h>
|
||||||
|
#include <model/Level.h>
|
||||||
|
|
||||||
|
namespace farmlands {
|
||||||
|
namespace graphics {
|
||||||
|
|
||||||
|
class BackgroundRenderer: public base::Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BackgroundRenderer();
|
||||||
|
virtual ~BackgroundRenderer();
|
||||||
|
|
||||||
|
virtual void onInitialize() override;
|
||||||
|
virtual void onRender() override;
|
||||||
|
|
||||||
|
// Public fields
|
||||||
|
model::Level* level;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void getCell(SDL_Texture* texture, uint32_t cell, int* outX, int* outY);
|
||||||
|
|
||||||
|
// Private fields
|
||||||
|
base::RenderContext* m_context;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace graphics */
|
||||||
|
} /* namespace farmlands */
|
||||||
|
|
||||||
|
#endif /* GRAPHICS_BACKGROUNDRENDERER_H_ */
|
@ -1,199 +0,0 @@
|
|||||||
/*
|
|
||||||
* GameRenderer.cpp
|
|
||||||
*
|
|
||||||
* Created on: Nov 13, 2016
|
|
||||||
* Author: tibi
|
|
||||||
*/
|
|
||||||
#include <GameState.h>
|
|
||||||
#include <graphics/GameRenderer.h>
|
|
||||||
#include <math/GameMath.h>
|
|
||||||
#include <resources/Resources.h>
|
|
||||||
|
|
||||||
namespace farmlands {
|
|
||||||
namespace graphics {
|
|
||||||
|
|
||||||
GameRenderer::GameRenderer()
|
|
||||||
: m_gameState(nullptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
GameRenderer::~GameRenderer()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void GameRenderer::initialize(GameState* gameState)
|
|
||||||
{
|
|
||||||
m_gameState = gameState;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GameRenderer::render()
|
|
||||||
{
|
|
||||||
prepareRender();
|
|
||||||
renderTileLayers();
|
|
||||||
renderPlayer();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GameRenderer::prepareRender()
|
|
||||||
{
|
|
||||||
m_cellW = m_gameState->currentLevel->m_cellWidth * m_gameState->camera.scale;
|
|
||||||
m_cellH = m_gameState->currentLevel->m_cellHeight * m_gameState->camera.scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GameRenderer::renderTileLayers()
|
|
||||||
{
|
|
||||||
// Compute how many cells fit on the screen
|
|
||||||
float cellsOnScreenX = m_gameState->viewport.width / m_cellW;
|
|
||||||
float cellsOnScreenY = m_gameState->viewport.height / m_cellH;
|
|
||||||
|
|
||||||
int minCellX = floorf(m_gameState->camera.posX - cellsOnScreenX / 2);
|
|
||||||
int minCellY = floorf(m_gameState->camera.posY - cellsOnScreenY / 2);
|
|
||||||
int maxCellX = ceilf(m_gameState->camera.posX + cellsOnScreenX / 2);
|
|
||||||
int maxCellY = ceilf(m_gameState->camera.posY + cellsOnScreenY / 2);
|
|
||||||
|
|
||||||
// Clamp cell positions
|
|
||||||
minCellX = clamp(minCellX, 0, (int)m_gameState->currentLevel->columnCount() - 1);
|
|
||||||
minCellY = clamp(minCellY, 0, (int)m_gameState->currentLevel->rowCount() - 1);
|
|
||||||
maxCellX = clamp(maxCellX, 0, (int)m_gameState->currentLevel->columnCount() - 1);
|
|
||||||
maxCellY = clamp(maxCellY, 0, (int)m_gameState->currentLevel->rowCount() - 1);
|
|
||||||
|
|
||||||
// Draw each layer
|
|
||||||
for (size_t i = 0; i < m_gameState->currentLevel->layerCount(); i++)
|
|
||||||
{
|
|
||||||
int textureId = m_gameState->currentLevel->texture(i);
|
|
||||||
|
|
||||||
// Render only visible tiles
|
|
||||||
for (int y = minCellY; y <= maxCellY; y++)
|
|
||||||
for (int x = minCellX; x <= maxCellX; x++)
|
|
||||||
{
|
|
||||||
int cellId = m_gameState->currentLevel->cell(i, y, x);
|
|
||||||
|
|
||||||
// Obtain texture
|
|
||||||
int texWidth, texHeight;
|
|
||||||
SDL_Texture* texture = m_gameState->resManager.texture(textureId);
|
|
||||||
SDL_QueryTexture(texture, NULL, NULL, &texWidth, &texHeight);
|
|
||||||
|
|
||||||
// Compute texture coordinates
|
|
||||||
int cellCol = (cellId * m_gameState->currentLevel->m_cellWidth) % texWidth;
|
|
||||||
int cellRow = ((cellId * m_gameState->currentLevel->m_cellWidth) / texWidth) * m_gameState->currentLevel->m_cellHeight;
|
|
||||||
|
|
||||||
// Calculate source position
|
|
||||||
SDL_Rect src =
|
|
||||||
{
|
|
||||||
cellCol,
|
|
||||||
cellRow,
|
|
||||||
(int) m_gameState->currentLevel->m_cellWidth,
|
|
||||||
(int) m_gameState->currentLevel->m_cellHeight
|
|
||||||
};
|
|
||||||
|
|
||||||
// Calculate destination position
|
|
||||||
SDL_Rect dest =
|
|
||||||
{
|
|
||||||
(int) xToScreen(x),
|
|
||||||
(int) yToScreen(y),
|
|
||||||
(int) ceilf(m_cellW),
|
|
||||||
(int) ceilf(m_cellH)
|
|
||||||
};
|
|
||||||
|
|
||||||
// Blit
|
|
||||||
SDL_RenderCopy(m_gameState->sdlRenderer.internalRenderer(), texture, &src, &dest);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GameRenderer::renderSprite(model::Sprite* sprite, float destX, float destY)
|
|
||||||
{
|
|
||||||
float posX = xToScreen(destX);
|
|
||||||
float posY = yToScreen(destY);
|
|
||||||
|
|
||||||
// Obtain texture
|
|
||||||
int texId = sprite->currentFrame().tileSetId;
|
|
||||||
SDL_Texture* texture = m_gameState->resManager.texture(texId);
|
|
||||||
|
|
||||||
// Compute src rectangle
|
|
||||||
SDL_Rect src;
|
|
||||||
getCell(texture, sprite->currentFrame().tileSetCell, &src.x, &src.y);
|
|
||||||
src.w = sprite->currentFrame().width * m_gameState->currentLevel->m_cellWidth;
|
|
||||||
src.h = sprite->currentFrame().height * m_gameState->currentLevel->m_cellHeight;
|
|
||||||
|
|
||||||
// Compute destination rectangle
|
|
||||||
SDL_Rect dest;
|
|
||||||
dest.x = posX - sprite->anchorX * src.w * m_gameState->camera.scale;
|
|
||||||
dest.y = posY - sprite->anchorY * src.h * m_gameState->camera.scale;
|
|
||||||
dest.w = src.w * m_gameState->camera.scale;
|
|
||||||
dest.h = src.h * m_gameState->camera.scale;
|
|
||||||
|
|
||||||
// Draw
|
|
||||||
SDL_RenderCopy(m_gameState->sdlRenderer.internalRenderer(), texture, &src, &dest);
|
|
||||||
|
|
||||||
// Advance animation frame
|
|
||||||
sprite->advanceTime(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GameRenderer::renderPlayer()
|
|
||||||
{
|
|
||||||
// Compute current state
|
|
||||||
model::Sprite* sprite = m_gameState->resManager.sprite(resources::R::Sprites::Player);
|
|
||||||
|
|
||||||
bool walking = (m_gameState->player.lastDeltaX != 0 || m_gameState->player.lastDeltaY != 0);
|
|
||||||
std::string stateName = (walking) ? "Walking " : "Idle ";
|
|
||||||
|
|
||||||
switch(m_gameState->player.direction)
|
|
||||||
{
|
|
||||||
case model::Direction::SouthEast:
|
|
||||||
case model::Direction::East:
|
|
||||||
case model::Direction::NorthEast:
|
|
||||||
stateName += "right";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case model::Direction::North:
|
|
||||||
stateName += "up";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case model::Direction::NorthWest:
|
|
||||||
case model::Direction::West:
|
|
||||||
case model::Direction::SouthWest:
|
|
||||||
stateName += "left";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case model::Direction::South:
|
|
||||||
stateName += "down";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
sprite->setState(stateName);
|
|
||||||
|
|
||||||
// Draw
|
|
||||||
renderSprite(sprite, m_gameState->player.posX, m_gameState->player.posY);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GameRenderer::getCell(SDL_Texture* texture, int cell, int* outX, int* outY)
|
|
||||||
{
|
|
||||||
int texWidth, texHeight;
|
|
||||||
SDL_QueryTexture(texture, NULL, NULL, &texWidth, &texHeight);
|
|
||||||
|
|
||||||
// Compute texture coordinates
|
|
||||||
*outX = (cell * m_gameState->currentLevel->m_cellWidth) % texWidth;
|
|
||||||
*outY = ((cell * m_gameState->currentLevel->m_cellWidth) / texWidth) * m_gameState->currentLevel->m_cellHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
float GameRenderer::xToWorld(float x)
|
|
||||||
{
|
|
||||||
return (x - m_gameState->viewport.width / 2) / m_cellW + m_gameState->camera.posX;
|
|
||||||
}
|
|
||||||
|
|
||||||
float GameRenderer::yToWorld(float y)
|
|
||||||
{
|
|
||||||
return (y - m_gameState->viewport.height / 2) / m_cellH + m_gameState->camera.posY;
|
|
||||||
}
|
|
||||||
|
|
||||||
float GameRenderer::xToScreen(float x)
|
|
||||||
{
|
|
||||||
return (x - m_gameState->camera.posX) * m_cellW + m_gameState->viewport.width / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
float GameRenderer::yToScreen(float y)
|
|
||||||
{
|
|
||||||
return (y - m_gameState->camera.posY) * m_cellH + m_gameState->viewport.height / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* namespace graphics */
|
|
||||||
} /* namespace farmlands */
|
|
@ -1,64 +0,0 @@
|
|||||||
/*
|
|
||||||
* GameRenderer.h
|
|
||||||
*
|
|
||||||
* Created on: Nov 13, 2016
|
|
||||||
* Author: tibi
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef GRAPHICS_GAMERENDERER_H_
|
|
||||||
#define GRAPHICS_GAMERENDERER_H_
|
|
||||||
|
|
||||||
#include <model/Sprite.h>
|
|
||||||
#include <graphics/SdlRenderer.h>
|
|
||||||
#include <resources/ResourceManager.h>
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include <SDL2/SDL.h>
|
|
||||||
|
|
||||||
namespace farmlands {
|
|
||||||
|
|
||||||
// Forward declarations
|
|
||||||
struct GameState;
|
|
||||||
|
|
||||||
namespace graphics {
|
|
||||||
|
|
||||||
class GameRenderer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
GameRenderer();
|
|
||||||
virtual ~GameRenderer();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes game renderer
|
|
||||||
*/
|
|
||||||
void initialize(GameState* gameState);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders everything
|
|
||||||
*/
|
|
||||||
void render();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void prepareRender();
|
|
||||||
void renderTileLayers();
|
|
||||||
void renderPlayer();
|
|
||||||
void renderSprite(model::Sprite* sprite, float destX, float destY);
|
|
||||||
|
|
||||||
float xToWorld(float x);
|
|
||||||
float yToWorld(float y);
|
|
||||||
float xToScreen(float x);
|
|
||||||
float yToScreen(float y);
|
|
||||||
|
|
||||||
void getCell(SDL_Texture* texture, int cell, int* outX, int* outY);
|
|
||||||
|
|
||||||
GameState* m_gameState;
|
|
||||||
|
|
||||||
// Size of a cell (scaled)
|
|
||||||
float m_cellW, m_cellH;
|
|
||||||
};
|
|
||||||
|
|
||||||
} /* namespace graphics */
|
|
||||||
} /* namespace farmlands */
|
|
||||||
|
|
||||||
#endif /* GRAPHICS_GAMERENDERER_H_ */
|
|
@ -1,72 +0,0 @@
|
|||||||
/*
|
|
||||||
* GuiRenderer.cpp
|
|
||||||
*
|
|
||||||
* Created on: Nov 13, 2016
|
|
||||||
* Author: tibi
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <GameState.h>
|
|
||||||
#include <graphics/GuiRenderer.h>
|
|
||||||
#include <resources/Resources.h>
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
#include <SDL2/SDL.h>
|
|
||||||
|
|
||||||
namespace farmlands
|
|
||||||
{
|
|
||||||
namespace graphics
|
|
||||||
{
|
|
||||||
|
|
||||||
GuiRenderer::GuiRenderer()
|
|
||||||
: m_gameState(nullptr),
|
|
||||||
m_fps(0),
|
|
||||||
m_fpsIndex(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
GuiRenderer::~GuiRenderer()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void GuiRenderer::initialize(GameState* gameState)
|
|
||||||
{
|
|
||||||
m_gameState = gameState;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GuiRenderer::render()
|
|
||||||
{
|
|
||||||
computeFps();
|
|
||||||
|
|
||||||
// Prepare stuff
|
|
||||||
TTF_Font* font = m_gameState->resManager.font(resources::R::Fonts::DejaVuSans, 10);
|
|
||||||
SDL_Color white = { 255, 255, 255, 255 };
|
|
||||||
SDL_Rect dest = { 10, 10, 0, 0 };
|
|
||||||
|
|
||||||
// Figure out what text to print
|
|
||||||
std::stringstream textStream;
|
|
||||||
textStream << "FPS: " << m_fps;
|
|
||||||
|
|
||||||
// Render text
|
|
||||||
SDL_Texture* fpsText = m_gameState->sdlRenderer.renderText(textStream.str(), font, white);
|
|
||||||
SDL_QueryTexture(fpsText, NULL, NULL, &dest.w, &dest.h);
|
|
||||||
SDL_RenderCopy(m_gameState->sdlRenderer.internalRenderer(), fpsText, NULL, &dest);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GuiRenderer::computeFps()
|
|
||||||
{
|
|
||||||
// Compute FPS
|
|
||||||
m_fpsVals[m_fpsIndex++] = 1.0f / m_gameState->elapsedTime;
|
|
||||||
if (m_fpsIndex >= GUIRENDERER_FPS_VALS)
|
|
||||||
{
|
|
||||||
m_fpsIndex = 0;
|
|
||||||
|
|
||||||
m_fps = 0;
|
|
||||||
for (int i = 0; i < GUIRENDERER_FPS_VALS; i++)
|
|
||||||
m_fps += m_fpsVals[i];
|
|
||||||
m_fps /= GUIRENDERER_FPS_VALS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* namespace graphics */
|
|
||||||
} /* namespace farmlands */
|
|
@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
* GuiRenderer.h
|
|
||||||
*
|
|
||||||
* Created on: Nov 13, 2016
|
|
||||||
* Author: tibi
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef GRAPHICS_GUIRENDERER_H_
|
|
||||||
#define GRAPHICS_GUIRENDERER_H_
|
|
||||||
|
|
||||||
#define GUIRENDERER_FPS_VALS 30
|
|
||||||
|
|
||||||
namespace farmlands {
|
|
||||||
|
|
||||||
// Forward declarations
|
|
||||||
struct GameState;
|
|
||||||
|
|
||||||
namespace graphics {
|
|
||||||
|
|
||||||
class GuiRenderer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
GuiRenderer();
|
|
||||||
virtual ~GuiRenderer();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes game renderer
|
|
||||||
*/
|
|
||||||
void initialize(GameState* gameState);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders the GUI
|
|
||||||
*/
|
|
||||||
void render();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void computeFps();
|
|
||||||
|
|
||||||
GameState* m_gameState;
|
|
||||||
float m_fpsVals[GUIRENDERER_FPS_VALS];
|
|
||||||
float m_fps;
|
|
||||||
int m_fpsIndex;
|
|
||||||
};
|
|
||||||
|
|
||||||
} /* namespace graphics */
|
|
||||||
} /* namespace farmlands */
|
|
||||||
|
|
||||||
#endif /* GRAPHICS_GUIRENDERER_H_ */
|
|
86
src/graphics/SpriteRenderer.cpp
Normal file
86
src/graphics/SpriteRenderer.cpp
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* SpriteRenderer.cpp
|
||||||
|
*
|
||||||
|
* Created on: Nov 30, 2016
|
||||||
|
* Author: tibi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <GameState.h>
|
||||||
|
#include <base/GameObject.h>
|
||||||
|
#include <base/Camera.h>
|
||||||
|
#include <graphics/backend/SdlRenderer.h>
|
||||||
|
#include <graphics/SpriteRenderer.h>
|
||||||
|
#include <utils/Assert.h>
|
||||||
|
|
||||||
|
using namespace farmlands::graphics::backend;
|
||||||
|
|
||||||
|
namespace farmlands {
|
||||||
|
namespace graphics {
|
||||||
|
|
||||||
|
SpriteRenderer::SpriteRenderer()
|
||||||
|
: sprite(nullptr),
|
||||||
|
m_transform(nullptr),
|
||||||
|
m_context(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SpriteRenderer::~SpriteRenderer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpriteRenderer::onInitialize()
|
||||||
|
{
|
||||||
|
Assert(gameObject != nullptr, "Component not properly initialized!");
|
||||||
|
|
||||||
|
m_transform = gameObject->component<base::Transform>();
|
||||||
|
m_context = &GameState::current().renderContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpriteRenderer::onRender()
|
||||||
|
{
|
||||||
|
float posX = m_context->xToScreen(m_transform->x);
|
||||||
|
float posY = m_context->yToScreen(m_transform->y);
|
||||||
|
|
||||||
|
// Obtain texture
|
||||||
|
int texId = sprite->currentFrame().tileSetId;
|
||||||
|
SDL_Texture* texture = resources::ResourceManager::instance().texture(texId);
|
||||||
|
|
||||||
|
// Compute src rectangle
|
||||||
|
SDL_Rect src;
|
||||||
|
getCell(texture, sprite->currentFrame().tileSetCell, &src.x, &src.y);
|
||||||
|
src.w = sprite->currentFrame().width * m_context->viewport.pixelsPerUnitX;
|
||||||
|
src.h = sprite->currentFrame().height * m_context->viewport.pixelsPerUnitY;
|
||||||
|
|
||||||
|
// Compute destination rectangle
|
||||||
|
float scale = m_context->camera()->scale;
|
||||||
|
|
||||||
|
SDL_Rect dest;
|
||||||
|
dest.x = posX - sprite->anchorX * src.w * scale;
|
||||||
|
dest.y = posY - sprite->anchorY * src.h * scale;
|
||||||
|
dest.w = src.w * scale;
|
||||||
|
dest.h = src.h * scale;
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
SdlRenderer::instance().renderTexture(texture, &src, &dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpriteRenderer::onPostRender()
|
||||||
|
{
|
||||||
|
sprite->advanceTime(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpriteRenderer::getCell(SDL_Texture* texture, uint32_t cell, int* outX, int* outY)
|
||||||
|
{
|
||||||
|
int texWidth, texHeight;
|
||||||
|
SdlRenderer::instance().getTextureSize(texture, &texWidth, &texHeight);
|
||||||
|
|
||||||
|
int ppuX = m_context->viewport.pixelsPerUnitX;
|
||||||
|
int ppuY = m_context->viewport.pixelsPerUnitY;
|
||||||
|
|
||||||
|
// Compute texture coordinates
|
||||||
|
*outX = (cell * ppuX) % texWidth;
|
||||||
|
*outY = ((cell * ppuX) / texWidth) * ppuY;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace graphics */
|
||||||
|
} /* namespace farmlands */
|
45
src/graphics/SpriteRenderer.h
Normal file
45
src/graphics/SpriteRenderer.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* SpriteRenderer.h
|
||||||
|
*
|
||||||
|
* Created on: Nov 30, 2016
|
||||||
|
* Author: tibi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GRAPHICS_SPRITERENDERER_H_
|
||||||
|
#define GRAPHICS_SPRITERENDERER_H_
|
||||||
|
|
||||||
|
#include <base/Component.h>
|
||||||
|
#include <base/RenderContext.h>
|
||||||
|
#include <base/Sprite.h>
|
||||||
|
#include <base/Transform.h>
|
||||||
|
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
|
namespace farmlands {
|
||||||
|
namespace graphics {
|
||||||
|
|
||||||
|
class SpriteRenderer: public base::Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SpriteRenderer();
|
||||||
|
virtual ~SpriteRenderer();
|
||||||
|
|
||||||
|
virtual void onInitialize() override;
|
||||||
|
virtual void onRender() override;
|
||||||
|
virtual void onPostRender() override;
|
||||||
|
|
||||||
|
// Public fields
|
||||||
|
base::Sprite* sprite;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void getCell(SDL_Texture* texture, uint32_t cell, int* outX, int* outY);
|
||||||
|
|
||||||
|
// Private fields
|
||||||
|
base::Transform* m_transform;
|
||||||
|
base::RenderContext* m_context;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace graphics */
|
||||||
|
} /* namespace farmlands */
|
||||||
|
|
||||||
|
#endif /* GRAPHICS_SPRITERENDERER_H_ */
|
@ -6,7 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <GameState.h>
|
#include <GameState.h>
|
||||||
#include <graphics/SdlRenderer.h>
|
#include <graphics/backend/SdlRenderer.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
@ -15,15 +15,21 @@
|
|||||||
#include <SDL2/SDL_image.h>
|
#include <SDL2/SDL_image.h>
|
||||||
#include <SDL2/SDL_ttf.h>
|
#include <SDL2/SDL_ttf.h>
|
||||||
|
|
||||||
namespace farmlands
|
namespace farmlands {
|
||||||
{
|
namespace graphics {
|
||||||
namespace graphics
|
namespace backend {
|
||||||
|
|
||||||
|
// Singleton instance
|
||||||
|
SdlRenderer SdlRenderer::s_instance;
|
||||||
|
|
||||||
|
SdlRenderer& SdlRenderer::instance()
|
||||||
{
|
{
|
||||||
|
return s_instance;
|
||||||
|
}
|
||||||
|
|
||||||
SdlRenderer::SdlRenderer()
|
SdlRenderer::SdlRenderer()
|
||||||
: m_sdlWindow(nullptr),
|
: m_sdlWindow(nullptr),
|
||||||
m_sdlRenderer(nullptr),
|
m_sdlRenderer(nullptr)
|
||||||
m_gameState(nullptr)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,10 +44,8 @@ SdlRenderer::~SdlRenderer()
|
|||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SdlRenderer::initialize(GameState* gameState)
|
bool SdlRenderer::initialize(base::RenderContext* renderContext)
|
||||||
{
|
{
|
||||||
m_gameState = gameState;
|
|
||||||
|
|
||||||
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
|
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
|
||||||
std::cerr << "Failed to initialize SDL!\n";
|
std::cerr << "Failed to initialize SDL!\n";
|
||||||
return false;
|
return false;
|
||||||
@ -58,10 +62,10 @@ bool SdlRenderer::initialize(GameState* gameState)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_gameState->viewport.initialized = true;
|
renderContext->viewport.initialized = true;
|
||||||
m_gameState->viewport.width = 1024;
|
renderContext->viewport.width = 1024;
|
||||||
m_gameState->viewport.height = 768;
|
renderContext->viewport.height = 768;
|
||||||
m_sdlWindow = SDL_CreateWindow("Farmlands", 0, 0, m_gameState->viewport.width, m_gameState->viewport.height, SDL_WINDOW_SHOWN);
|
m_sdlWindow = SDL_CreateWindow("Farmlands", 0, 0, renderContext->viewport.width, renderContext->viewport.height, SDL_WINDOW_SHOWN);
|
||||||
if (!m_sdlWindow) {
|
if (!m_sdlWindow) {
|
||||||
std::cerr << "Failed to create main window!\n";
|
std::cerr << "Failed to create main window!\n";
|
||||||
return false;
|
return false;
|
||||||
@ -88,6 +92,11 @@ void SdlRenderer::renderEnd()
|
|||||||
SDL_RenderPresent(m_sdlRenderer);
|
SDL_RenderPresent(m_sdlRenderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SdlRenderer::renderTexture(SDL_Texture* texture, SDL_Rect* src, SDL_Rect* dest)
|
||||||
|
{
|
||||||
|
SDL_RenderCopy(m_sdlRenderer, texture, src, dest);
|
||||||
|
}
|
||||||
|
|
||||||
SDL_Texture* SdlRenderer::renderText(const std::string& text, TTF_Font* font, SDL_Color color)
|
SDL_Texture* SdlRenderer::renderText(const std::string& text, TTF_Font* font, SDL_Color color)
|
||||||
{
|
{
|
||||||
assert(font != nullptr);
|
assert(font != nullptr);
|
||||||
@ -102,7 +111,12 @@ SDL_Texture* SdlRenderer::renderText(const std::string& text, TTF_Font* font, SD
|
|||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SdlRenderer::getTextureSize(SDL_Texture* texture, int* width, int* height)
|
||||||
|
{
|
||||||
|
SDL_QueryTexture(texture, NULL, NULL, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
} /* namespace graphics */
|
} /* namespace graphics */
|
||||||
} /* namespace farmlands */
|
} /* namespace farmlands */
|
||||||
|
|
||||||
|
|
@ -8,30 +8,30 @@
|
|||||||
#ifndef GRAPHICS_SDLRENDERER_H_
|
#ifndef GRAPHICS_SDLRENDERER_H_
|
||||||
#define GRAPHICS_SDLRENDERER_H_
|
#define GRAPHICS_SDLRENDERER_H_
|
||||||
|
|
||||||
|
#include <base/RenderContext.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#include <SDL2/SDL_ttf.h>
|
#include <SDL2/SDL_ttf.h>
|
||||||
|
|
||||||
namespace farmlands {
|
namespace farmlands {
|
||||||
|
|
||||||
// Forward declarations
|
|
||||||
struct GameState;
|
|
||||||
|
|
||||||
namespace graphics {
|
namespace graphics {
|
||||||
|
namespace backend {
|
||||||
|
|
||||||
class SdlRenderer
|
class SdlRenderer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SdlRenderer();
|
static SdlRenderer& instance();
|
||||||
virtual ~SdlRenderer();
|
|
||||||
|
~SdlRenderer();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the game renderer.
|
* Initializes the game renderer.
|
||||||
*
|
*
|
||||||
* @returns true if successful, false otherwise.
|
* @returns true if successful, false otherwise.
|
||||||
*/
|
*/
|
||||||
bool initialize(GameState* gameState);
|
bool initialize(base::RenderContext* renderContext);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs steps for beginning to render.
|
* Performs steps for beginning to render.
|
||||||
@ -48,6 +48,16 @@ namespace graphics {
|
|||||||
*/
|
*/
|
||||||
SDL_Texture* renderText(const std::string& text, TTF_Font* font, SDL_Color color);
|
SDL_Texture* renderText(const std::string& text, TTF_Font* font, SDL_Color color);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders a textue
|
||||||
|
*/
|
||||||
|
void renderTexture(SDL_Texture* texture, SDL_Rect* src, SDL_Rect* dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the size of a texture
|
||||||
|
*/
|
||||||
|
void getTextureSize(SDL_Texture* texture, int* width, int* height);
|
||||||
|
|
||||||
// Getters
|
// Getters
|
||||||
/**
|
/**
|
||||||
* Gets the internal SDL renderer object;
|
* Gets the internal SDL renderer object;
|
||||||
@ -56,12 +66,15 @@ namespace graphics {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
SdlRenderer();
|
||||||
|
|
||||||
SDL_Window* m_sdlWindow;
|
SDL_Window* m_sdlWindow;
|
||||||
SDL_Renderer* m_sdlRenderer;
|
SDL_Renderer* m_sdlRenderer;
|
||||||
|
|
||||||
GameState* m_gameState;
|
static SdlRenderer s_instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
} /* namespace graphics */
|
} /* namespace graphics */
|
||||||
} /* namespace farmlands */
|
} /* namespace farmlands */
|
||||||
|
|
@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
* RenderContext.h
|
|
||||||
*
|
|
||||||
* Created on: Nov 27, 2016
|
|
||||||
* Author: tibi
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef GUI_PRIMITIVES_RENDERCONTEXT_H_
|
|
||||||
#define GUI_PRIMITIVES_RENDERCONTEXT_H_
|
|
||||||
|
|
||||||
#include <graphics/SdlRenderer.h>
|
|
||||||
#include <resources/ResourceManager.h>
|
|
||||||
|
|
||||||
namespace farmlands {
|
|
||||||
namespace gui {
|
|
||||||
|
|
||||||
struct RenderContext
|
|
||||||
{
|
|
||||||
graphics::SdlRenderer* sdlRenderer;
|
|
||||||
resources::ResourceManager* resManager;
|
|
||||||
float uiScale;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* GUI_PRIMITIVES_RENDERCONTEXT_H_ */
|
|
@ -19,7 +19,7 @@ Canvas::~Canvas()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::render(RenderContext& context)
|
void Canvas::render(base::RenderContext* context)
|
||||||
{
|
{
|
||||||
for (auto child : m_children)
|
for (auto child : m_children)
|
||||||
child->render(context);
|
child->render(context);
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
#define GUI_PRIMITIVES_CANVAS_H_
|
#define GUI_PRIMITIVES_CANVAS_H_
|
||||||
|
|
||||||
#include <gui/primitives/UILayout.h>
|
#include <gui/primitives/UILayout.h>
|
||||||
#include <gui/RenderContext.h>
|
|
||||||
|
|
||||||
namespace farmlands {
|
namespace farmlands {
|
||||||
namespace gui {
|
namespace gui {
|
||||||
@ -21,7 +20,7 @@ namespace layout {
|
|||||||
Canvas();
|
Canvas();
|
||||||
virtual ~Canvas();
|
virtual ~Canvas();
|
||||||
|
|
||||||
virtual void render(RenderContext& context) override;
|
virtual void render(base::RenderContext* context) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,11 @@
|
|||||||
* Author: tibi
|
* Author: tibi
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <graphics/backend/SdlRenderer.h>
|
||||||
#include <gui/primitives/UIElement.h>
|
#include <gui/primitives/UIElement.h>
|
||||||
|
|
||||||
|
using namespace farmlands::graphics::backend;
|
||||||
|
|
||||||
namespace farmlands
|
namespace farmlands
|
||||||
{
|
{
|
||||||
namespace gui
|
namespace gui
|
||||||
@ -24,7 +27,7 @@ UIElement::~UIElement()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIElement::render(RenderContext& context)
|
void UIElement::render(base::RenderContext* context)
|
||||||
{
|
{
|
||||||
if (m_backColor.a > 0)
|
if (m_backColor.a > 0)
|
||||||
{
|
{
|
||||||
@ -36,8 +39,8 @@ void UIElement::render(RenderContext& context)
|
|||||||
(int) m_h
|
(int) m_h
|
||||||
};
|
};
|
||||||
|
|
||||||
SDL_SetRenderDrawColor(context.sdlRenderer->internalRenderer(), m_backColor.r, m_backColor.g, m_backColor.b, m_backColor.a);
|
SDL_SetRenderDrawColor(SdlRenderer::instance().internalRenderer(), m_backColor.r, m_backColor.g, m_backColor.b, m_backColor.a);
|
||||||
SDL_RenderFillRect(context.sdlRenderer->internalRenderer(), &rect);
|
SDL_RenderFillRect(SdlRenderer::instance().internalRenderer(), &rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
#include <gui/RenderContext.h>
|
#include <base/RenderContext.h>
|
||||||
|
|
||||||
namespace farmlands {
|
namespace farmlands {
|
||||||
namespace gui {
|
namespace gui {
|
||||||
@ -22,7 +22,7 @@ namespace primitives {
|
|||||||
UIElement();
|
UIElement();
|
||||||
virtual ~UIElement();
|
virtual ~UIElement();
|
||||||
|
|
||||||
virtual void render(RenderContext& context);
|
virtual void render(base::RenderContext* context);
|
||||||
virtual bool handleEvent(SDL_Event& event);
|
virtual bool handleEvent(SDL_Event& event);
|
||||||
|
|
||||||
// Getters & setters
|
// Getters & setters
|
||||||
|
@ -5,8 +5,10 @@
|
|||||||
* Author: tibi
|
* Author: tibi
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <graphics/backend/SdlRenderer.h>
|
||||||
#include <gui/widgets/TextArea.h>
|
#include <gui/widgets/TextArea.h>
|
||||||
#include <resources/Resources.h>
|
#include <resources/Resources.h>
|
||||||
|
#include <resources/ResourceManager.h>
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -14,12 +16,12 @@
|
|||||||
|
|
||||||
#include <SDL2/SDL_ttf.h>
|
#include <SDL2/SDL_ttf.h>
|
||||||
|
|
||||||
namespace farmlands
|
using namespace farmlands::graphics::backend;
|
||||||
{
|
using namespace farmlands::resources;
|
||||||
namespace gui
|
|
||||||
{
|
namespace farmlands {
|
||||||
namespace widgets
|
namespace gui {
|
||||||
{
|
namespace widgets {
|
||||||
|
|
||||||
TextArea::TextArea()
|
TextArea::TextArea()
|
||||||
: m_text(),
|
: m_text(),
|
||||||
@ -39,12 +41,12 @@ TextArea::~TextArea()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextArea::render(RenderContext& context)
|
void TextArea::render(base::RenderContext* context)
|
||||||
{
|
{
|
||||||
UIElement::render(context);
|
UIElement::render(context);
|
||||||
|
|
||||||
// Obtain font
|
// Obtain font
|
||||||
TTF_Font* font = context.resManager->font(m_fontId, m_fontSize * context.uiScale);
|
TTF_Font* font = ResourceManager::instance().font(m_fontId, m_fontSize * context->uiScale);
|
||||||
if (font == nullptr)
|
if (font == nullptr)
|
||||||
return; // TODO: handle error (maybe log it)
|
return; // TODO: handle error (maybe log it)
|
||||||
|
|
||||||
@ -94,7 +96,7 @@ void TextArea::render(RenderContext& context)
|
|||||||
dest.y = y() + totalH;
|
dest.y = y() + totalH;
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
SDL_RenderCopy(context.sdlRenderer->internalRenderer(), lineTexture, NULL, &dest);
|
SdlRenderer::instance().renderTexture(lineTexture, NULL, &dest);
|
||||||
|
|
||||||
totalH += lineH;
|
totalH += lineH;
|
||||||
}
|
}
|
||||||
@ -256,7 +258,7 @@ void TextArea::wrapText(TTF_Font* font)
|
|||||||
m_wrappedText.erase(m_wrappedText.size() - 1);
|
m_wrappedText.erase(m_wrappedText.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextArea::renderLines(RenderContext& context, TTF_Font* font)
|
void TextArea::renderLines(base::RenderContext* context, TTF_Font* font)
|
||||||
{
|
{
|
||||||
// Clean up old textures
|
// Clean up old textures
|
||||||
for (SDL_Texture* tex : m_renderedLines)
|
for (SDL_Texture* tex : m_renderedLines)
|
||||||
@ -270,7 +272,7 @@ void TextArea::renderLines(RenderContext& context, TTF_Font* font)
|
|||||||
for (std::string line : lines)
|
for (std::string line : lines)
|
||||||
{
|
{
|
||||||
// Render line
|
// Render line
|
||||||
SDL_Texture* tex = context.sdlRenderer->renderText(line, font, m_color);
|
SDL_Texture* tex = SdlRenderer::instance().renderText(line, font, m_color);
|
||||||
m_renderedLines.push_back(tex);
|
m_renderedLines.push_back(tex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ namespace widgets {
|
|||||||
TextArea();
|
TextArea();
|
||||||
virtual ~TextArea();
|
virtual ~TextArea();
|
||||||
|
|
||||||
virtual void render(RenderContext& context) override;
|
virtual void render(base::RenderContext* context) override;
|
||||||
|
|
||||||
// Getters and setters
|
// Getters and setters
|
||||||
inline std::string text() const { return m_text; }
|
inline std::string text() const { return m_text; }
|
||||||
@ -71,7 +71,7 @@ namespace widgets {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void wrapText(TTF_Font* font);
|
void wrapText(TTF_Font* font);
|
||||||
void renderLines(RenderContext& context, TTF_Font* font);
|
void renderLines(base::RenderContext* context, TTF_Font* font);
|
||||||
|
|
||||||
std::string m_text;
|
std::string m_text;
|
||||||
std::string m_wrappedText;
|
std::string m_wrappedText;
|
||||||
|
40
src/input/GameKey.h
Normal file
40
src/input/GameKey.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* GameKeys.h
|
||||||
|
*
|
||||||
|
* Created on: Nov 30, 2016
|
||||||
|
* Author: tibi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INPUT_GAMEKEY_H_
|
||||||
|
#define INPUT_GAMEKEY_H_
|
||||||
|
|
||||||
|
namespace farmlands {
|
||||||
|
namespace input {
|
||||||
|
|
||||||
|
enum GameKey
|
||||||
|
{
|
||||||
|
Right,
|
||||||
|
Up,
|
||||||
|
Left,
|
||||||
|
Down,
|
||||||
|
|
||||||
|
Action,
|
||||||
|
Action2,
|
||||||
|
Run,
|
||||||
|
|
||||||
|
AltRight,
|
||||||
|
AltUp,
|
||||||
|
AltLeft,
|
||||||
|
AltDown,
|
||||||
|
|
||||||
|
Debug_ZoomIn,
|
||||||
|
Debug_ZoomOut,
|
||||||
|
|
||||||
|
_Count
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* INPUT_GAMEKEY_H_ */
|
40
src/input/GameKeyConfiguration.cpp
Normal file
40
src/input/GameKeyConfiguration.cpp
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* GameKeyConfiguration.cpp
|
||||||
|
*
|
||||||
|
* Created on: Nov 30, 2016
|
||||||
|
* Author: tibi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <input/GameKeyConfiguration.h>
|
||||||
|
|
||||||
|
namespace farmlands {
|
||||||
|
namespace input {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default keyboard configuration
|
||||||
|
*/
|
||||||
|
const GameKeyConfiguration GameKeyConfiguration::defaultConfig =
|
||||||
|
{
|
||||||
|
.keys =
|
||||||
|
{
|
||||||
|
SDL_SCANCODE_RIGHT, // Right
|
||||||
|
SDL_SCANCODE_UP, // Up
|
||||||
|
SDL_SCANCODE_LEFT, // Left
|
||||||
|
SDL_SCANCODE_DOWN, // Down
|
||||||
|
|
||||||
|
SDL_SCANCODE_SPACE, // Action
|
||||||
|
SDL_SCANCODE_LCTRL, // Action2
|
||||||
|
SDL_SCANCODE_LSHIFT, // Run
|
||||||
|
|
||||||
|
SDL_SCANCODE_D, // AltRight
|
||||||
|
SDL_SCANCODE_W, // AltUp
|
||||||
|
SDL_SCANCODE_A, // AltLeft
|
||||||
|
SDL_SCANCODE_S, // AltRight
|
||||||
|
|
||||||
|
SDL_SCANCODE_KP_PLUS, // Debug_ZoomIn,
|
||||||
|
SDL_SCANCODE_KP_MINUS, // Debug_ZoomOut,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
30
src/input/GameKeyConfiguration.h
Normal file
30
src/input/GameKeyConfiguration.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* GameKeyConfiguration.h
|
||||||
|
*
|
||||||
|
* Created on: Nov 30, 2016
|
||||||
|
* Author: tibi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INPUT_GAMEKEYCONFIGURATION_H_
|
||||||
|
#define INPUT_GAMEKEYCONFIGURATION_H_
|
||||||
|
|
||||||
|
#include <input/GameKey.h>
|
||||||
|
#include <SDL2/SDL_scancode.h>
|
||||||
|
|
||||||
|
namespace farmlands {
|
||||||
|
namespace input {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines a keyboard configuration
|
||||||
|
*/
|
||||||
|
struct GameKeyConfiguration
|
||||||
|
{
|
||||||
|
SDL_Scancode keys[GameKey::_Count];
|
||||||
|
|
||||||
|
static const GameKeyConfiguration defaultConfig;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace input */
|
||||||
|
} /* namespace farmlands */
|
||||||
|
|
||||||
|
#endif /* INPUT_GAMEKEYCONFIGURATION_H_ */
|
81
src/input/Input.cpp
Normal file
81
src/input/Input.cpp
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* Input.cpp
|
||||||
|
*
|
||||||
|
* Created on: Nov 30, 2016
|
||||||
|
* Author: tibi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <input/Input.h>
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
|
namespace farmlands {
|
||||||
|
namespace input {
|
||||||
|
|
||||||
|
Input Input::s_instance;
|
||||||
|
|
||||||
|
Input& Input::instance()
|
||||||
|
{
|
||||||
|
return s_instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
Input::Input()
|
||||||
|
: m_config(GameKeyConfiguration::defaultConfig)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Input::~Input()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Input::initialize()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Input::pressed(GameKey key)
|
||||||
|
{
|
||||||
|
const Uint8* keys = SDL_GetKeyboardState(NULL);
|
||||||
|
SDL_Scancode code = m_config.keys[key];
|
||||||
|
|
||||||
|
return keys[code];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Input::down(GameKey key, SDL_Event& event)
|
||||||
|
{
|
||||||
|
if (event.type == SDL_KEYDOWN)
|
||||||
|
{
|
||||||
|
SDL_Scancode code = m_config.keys[key];
|
||||||
|
return event.key.keysym.scancode == code;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Input::getX()
|
||||||
|
{
|
||||||
|
// Keyboard
|
||||||
|
if (pressed(GameKey::Right) || pressed(GameKey::AltRight))
|
||||||
|
return 1.0f;
|
||||||
|
else if (pressed(GameKey::Left) || pressed(GameKey::AltLeft))
|
||||||
|
return -1.0f;
|
||||||
|
|
||||||
|
// TODO: controller
|
||||||
|
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Input::getY()
|
||||||
|
{
|
||||||
|
// Keyboard
|
||||||
|
if (pressed(GameKey::Down) || pressed(GameKey::AltDown))
|
||||||
|
return 1.0f;
|
||||||
|
else if (pressed(GameKey::Up) || pressed(GameKey::AltUp))
|
||||||
|
return -1.0f;
|
||||||
|
|
||||||
|
// TODO: controller
|
||||||
|
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace input */
|
||||||
|
} /* namespace farmlands */
|
42
src/input/Input.h
Normal file
42
src/input/Input.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Input.h
|
||||||
|
*
|
||||||
|
* Created on: Nov 30, 2016
|
||||||
|
* Author: tibi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INPUT_INPUT_H_
|
||||||
|
#define INPUT_INPUT_H_
|
||||||
|
|
||||||
|
#include <input/GameKey.h>
|
||||||
|
#include <input/GameKeyConfiguration.h>
|
||||||
|
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
|
namespace farmlands {
|
||||||
|
namespace input {
|
||||||
|
|
||||||
|
class Input
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static Input& instance();
|
||||||
|
virtual ~Input();
|
||||||
|
|
||||||
|
void initialize();
|
||||||
|
bool pressed(GameKey key);
|
||||||
|
bool down(GameKey key, SDL_Event& event);
|
||||||
|
float getX();
|
||||||
|
float getY();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Input();
|
||||||
|
|
||||||
|
static Input s_instance;
|
||||||
|
|
||||||
|
GameKeyConfiguration m_config;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace input */
|
||||||
|
} /* namespace farmlands */
|
||||||
|
|
||||||
|
#endif /* INPUT_INPUT_H_ */
|
@ -13,14 +13,15 @@ namespace model {
|
|||||||
|
|
||||||
enum Direction
|
enum Direction
|
||||||
{
|
{
|
||||||
East = 0,
|
None = 0,
|
||||||
NorthEast = 1,
|
East = 1,
|
||||||
North = 2,
|
North = 2,
|
||||||
NorthWest = 3,
|
|
||||||
West = 4,
|
West = 4,
|
||||||
SouthWest = 5,
|
South = 8,
|
||||||
South = 6,
|
NorthEast = North | East,
|
||||||
SouthEast = 7
|
NorthWest = North | West,
|
||||||
|
SouthWest = South | West,
|
||||||
|
SouthEast = South | East
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,8 @@ namespace model {
|
|||||||
float lastDeltaX, lastDeltaY;
|
float lastDeltaX, lastDeltaY;
|
||||||
Direction direction;
|
Direction direction;
|
||||||
|
|
||||||
|
bool attacking;
|
||||||
|
uint32_t attackTimeLeft;
|
||||||
|
|
||||||
int inventorySelection = -1;
|
int inventorySelection = -1;
|
||||||
int inventory[PLAYER_INVENTORY_SIZE];
|
int inventory[PLAYER_INVENTORY_SIZE];
|
||||||
|
28
src/model/TileMask.h
Normal file
28
src/model/TileMask.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* TileMask.h
|
||||||
|
*
|
||||||
|
* Created on: Nov 30, 2016
|
||||||
|
* Author: tibi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MODEL_TILEMASK_H_
|
||||||
|
#define MODEL_TILEMASK_H_
|
||||||
|
|
||||||
|
namespace farmlands {
|
||||||
|
namespace model {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tile mask used to determine what tile to use depending on neighboring tiles.
|
||||||
|
*/
|
||||||
|
enum class TileMask
|
||||||
|
{
|
||||||
|
Right = 1,
|
||||||
|
Top = 2,
|
||||||
|
Left = 4,
|
||||||
|
Bottom = 8
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* MODEL_TILEMASK_H_ */
|
@ -8,8 +8,8 @@
|
|||||||
#ifndef STORAGE_RESOURCEMANAGER_H_
|
#ifndef STORAGE_RESOURCEMANAGER_H_
|
||||||
#define STORAGE_RESOURCEMANAGER_H_
|
#define STORAGE_RESOURCEMANAGER_H_
|
||||||
|
|
||||||
|
#include <base/Sprite.h>
|
||||||
#include <model/Level.h>
|
#include <model/Level.h>
|
||||||
#include <model/Sprite.h>
|
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
@ -40,32 +40,37 @@ namespace resources {
|
|||||||
} texture;
|
} texture;
|
||||||
|
|
||||||
model::Level* level;
|
model::Level* level;
|
||||||
model::Sprite* sprite;
|
base::Sprite* sprite;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef uint32_t ResourceId;
|
||||||
|
|
||||||
class ResourceManager
|
class ResourceManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ResourceManager();
|
static ResourceManager& instance();
|
||||||
virtual ~ResourceManager();
|
~ResourceManager();
|
||||||
void initialize(GameState* gameState);
|
|
||||||
|
void initialize();
|
||||||
|
|
||||||
// Loading routines
|
// Loading routines
|
||||||
void loadMainMenu();
|
void loadMainMenu();
|
||||||
void loadGameAssets();
|
void loadGameAssets();
|
||||||
void loadLevel(int levelId);
|
void loadLevel(ResourceId levelId);
|
||||||
|
|
||||||
TTF_Font* font(int id, int pointSize);
|
TTF_Font* font(ResourceId id, int pointSize);
|
||||||
SDL_Texture* texture(int id);
|
SDL_Texture* texture(ResourceId id);
|
||||||
model::Level* level(int id);
|
model::Level* level(ResourceId id);
|
||||||
model::Sprite* sprite(int id);
|
base::Sprite* sprite(ResourceId id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ResourceManager();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains the path of the resource in native format.
|
* Obtains the path of the resource in native format.
|
||||||
*/
|
*/
|
||||||
std::string getPath(int resourceId);
|
std::string getPath(ResourceId resourceId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains the id of a resource based on its path.
|
* Obtains the id of a resource based on its path.
|
||||||
@ -73,13 +78,12 @@ namespace resources {
|
|||||||
*/
|
*/
|
||||||
int getId(std::string resourcePath);
|
int getId(std::string resourcePath);
|
||||||
|
|
||||||
void loadFont(int fontId, int pointSize);
|
void loadFont(ResourceId fontId, int pointSize);
|
||||||
void loadTexture(int textureId);
|
void loadTexture(ResourceId textureId);
|
||||||
void loadSprite(int spriteId);
|
void loadSprite(ResourceId spriteId);
|
||||||
void loadLevelLayer(model::Level* level, size_t layerNumber, int resourceId);
|
void loadLevelLayer(model::Level* level, size_t layerNumber, ResourceId resourceId);
|
||||||
|
|
||||||
// State
|
static ResourceManager s_instance;
|
||||||
GameState* m_gameState;
|
|
||||||
|
|
||||||
// Loaded resources
|
// Loaded resources
|
||||||
LoadedResource* m_loadedResources;
|
LoadedResource* m_loadedResources;
|
||||||
|
@ -14,9 +14,15 @@
|
|||||||
namespace farmlands {
|
namespace farmlands {
|
||||||
namespace resources {
|
namespace resources {
|
||||||
|
|
||||||
|
ResourceManager ResourceManager::s_instance;
|
||||||
|
|
||||||
|
ResourceManager& ResourceManager::instance()
|
||||||
|
{
|
||||||
|
return s_instance;
|
||||||
|
}
|
||||||
|
|
||||||
ResourceManager::ResourceManager()
|
ResourceManager::ResourceManager()
|
||||||
: m_gameState(nullptr),
|
: m_loadedResources(new LoadedResource[sizeof(RInfo) / sizeof(RInfo[0])])
|
||||||
m_loadedResources(new LoadedResource[sizeof(RInfo) / sizeof(RInfo[0])])
|
|
||||||
{
|
{
|
||||||
for(size_t i = 0; i < sizeof(RInfo) / sizeof(RInfo[0]); i++)
|
for(size_t i = 0; i < sizeof(RInfo) / sizeof(RInfo[0]); i++)
|
||||||
m_loadedResources[i].loaded = false;
|
m_loadedResources[i].loaded = false;
|
||||||
@ -53,9 +59,8 @@ ResourceManager::~ResourceManager()
|
|||||||
delete[] m_loadedResources;
|
delete[] m_loadedResources;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceManager::initialize(GameState* gameState)
|
void ResourceManager::initialize()
|
||||||
{
|
{
|
||||||
m_gameState = gameState;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceManager::loadMainMenu()
|
void ResourceManager::loadMainMenu()
|
||||||
@ -67,7 +72,7 @@ void ResourceManager::loadGameAssets()
|
|||||||
loadSprite(R::Sprites::Player);
|
loadSprite(R::Sprites::Player);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ResourceManager::getPath(int resourceId)
|
std::string ResourceManager::getPath(ResourceId resourceId)
|
||||||
{
|
{
|
||||||
Assert(resourceId >= 0 && resourceId < sizeof(RInfo) / sizeof(RInfo[0]), "Resource id out of bounds.");
|
Assert(resourceId >= 0 && resourceId < sizeof(RInfo) / sizeof(RInfo[0]), "Resource id out of bounds.");
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
namespace farmlands {
|
namespace farmlands {
|
||||||
namespace resources {
|
namespace resources {
|
||||||
|
|
||||||
TTF_Font* ResourceManager::font(int id, int pointSize)
|
TTF_Font* ResourceManager::font(ResourceId id, int pointSize)
|
||||||
{
|
{
|
||||||
// Open from cache
|
// Open from cache
|
||||||
auto it = m_fontCache.find(FONTID(id, pointSize));
|
auto it = m_fontCache.find(FONTID(id, pointSize));
|
||||||
|
@ -19,7 +19,7 @@ using namespace nlohmann;
|
|||||||
namespace farmlands {
|
namespace farmlands {
|
||||||
namespace resources {
|
namespace resources {
|
||||||
|
|
||||||
void ResourceManager::loadLevelLayer(model::Level* level, size_t layer, int resourceId)
|
void ResourceManager::loadLevelLayer(model::Level* level, size_t layer, ResourceId resourceId)
|
||||||
{
|
{
|
||||||
Assert(RInfo[resourceId].type == ResourceType::LevelLayer, "Resource must be a level layer.");
|
Assert(RInfo[resourceId].type == ResourceType::LevelLayer, "Resource must be a level layer.");
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ void ResourceManager::loadLevelLayer(model::Level* level, size_t layer, int reso
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ResourceManager::loadLevel(int levelId)
|
void ResourceManager::loadLevel(ResourceId levelId)
|
||||||
{
|
{
|
||||||
// Sanity checks
|
// Sanity checks
|
||||||
Assert(RInfo[levelId].type == ResourceType::Level, "Resource must be a level!");
|
Assert(RInfo[levelId].type == ResourceType::Level, "Resource must be a level!");
|
||||||
@ -100,7 +100,7 @@ void ResourceManager::loadLevel(int levelId)
|
|||||||
m_loadedResources[levelId].level = level;
|
m_loadedResources[levelId].level = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
model::Level* ResourceManager::level(int id)
|
model::Level* ResourceManager::level(ResourceId id)
|
||||||
{
|
{
|
||||||
Assert(RInfo[id].type == ResourceType::Level, "Resource must be a level!");
|
Assert(RInfo[id].type == ResourceType::Level, "Resource must be a level!");
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* Created on: Nov 29, 2016
|
* Created on: Nov 29, 2016
|
||||||
* Author: tibi
|
* Author: tibi
|
||||||
*/
|
*/
|
||||||
#include <model/Sprite.h>
|
#include <base/Sprite.h>
|
||||||
#include <resources/ResourceManager.h>
|
#include <resources/ResourceManager.h>
|
||||||
#include <resources/Resources.h>
|
#include <resources/Resources.h>
|
||||||
#include <utils/Assert.h>
|
#include <utils/Assert.h>
|
||||||
@ -15,12 +15,13 @@
|
|||||||
#include <json.hpp>
|
#include <json.hpp>
|
||||||
|
|
||||||
using namespace nlohmann;
|
using namespace nlohmann;
|
||||||
|
using namespace farmlands::base;
|
||||||
|
|
||||||
namespace farmlands {
|
namespace farmlands {
|
||||||
namespace resources {
|
namespace resources {
|
||||||
|
|
||||||
|
|
||||||
void ResourceManager::loadSprite(int spriteId)
|
void ResourceManager::loadSprite(ResourceId spriteId)
|
||||||
{
|
{
|
||||||
Assert(RInfo[spriteId].type == ResourceType::Sprite, "Resource must be a sprite!");
|
Assert(RInfo[spriteId].type == ResourceType::Sprite, "Resource must be a sprite!");
|
||||||
if (m_loadedResources[spriteId].loaded)
|
if (m_loadedResources[spriteId].loaded)
|
||||||
@ -36,7 +37,7 @@ void ResourceManager::loadSprite(int spriteId)
|
|||||||
json spriteJs;
|
json spriteJs;
|
||||||
spriteIn >> spriteJs;
|
spriteIn >> spriteJs;
|
||||||
|
|
||||||
model::Sprite* sprite = new model::Sprite();
|
Sprite* sprite = new Sprite();
|
||||||
sprite->anchorX = spriteJs.value("anchorX", 0.0f);
|
sprite->anchorX = spriteJs.value("anchorX", 0.0f);
|
||||||
sprite->anchorY = spriteJs.value("anchorY", 0.0f);
|
sprite->anchorY = spriteJs.value("anchorY", 0.0f);
|
||||||
|
|
||||||
@ -44,14 +45,14 @@ void ResourceManager::loadSprite(int spriteId)
|
|||||||
|
|
||||||
for (auto state : statesJs)
|
for (auto state : statesJs)
|
||||||
{
|
{
|
||||||
model::SpriteState spriteState;
|
SpriteState spriteState;
|
||||||
spriteState.name = state.value("name", std::string());
|
spriteState.name = state.value("name", std::string());
|
||||||
|
|
||||||
// Obtain frames
|
// Obtain frames
|
||||||
json framesJs = state.at("frames");
|
json framesJs = state.at("frames");
|
||||||
for (auto frame : framesJs)
|
for (auto frame : framesJs)
|
||||||
{
|
{
|
||||||
model::Frame spriteFrame;
|
Frame spriteFrame;
|
||||||
spriteFrame.tileSetCell = frame.value("cell", 0u);
|
spriteFrame.tileSetCell = frame.value("cell", 0u);
|
||||||
spriteFrame.width = frame.value("width", 0u);
|
spriteFrame.width = frame.value("width", 0u);
|
||||||
spriteFrame.height = frame.value("height", 0u);
|
spriteFrame.height = frame.value("height", 0u);
|
||||||
@ -74,7 +75,7 @@ void ResourceManager::loadSprite(int spriteId)
|
|||||||
m_loadedResources[spriteId].sprite = sprite;
|
m_loadedResources[spriteId].sprite = sprite;
|
||||||
}
|
}
|
||||||
|
|
||||||
model::Sprite* ResourceManager::sprite(int id)
|
Sprite* ResourceManager::sprite(ResourceId id)
|
||||||
{
|
{
|
||||||
Assert(RInfo[id].type == ResourceType::Sprite, "Resource must be a sprite!");
|
Assert(RInfo[id].type == ResourceType::Sprite, "Resource must be a sprite!");
|
||||||
|
|
||||||
|
@ -4,15 +4,18 @@
|
|||||||
* Created on: Nov 12, 2016
|
* Created on: Nov 12, 2016
|
||||||
* Author: tibi
|
* Author: tibi
|
||||||
*/
|
*/
|
||||||
#include <GameState.h>
|
|
||||||
|
#include <graphics/backend/SdlRenderer.h>
|
||||||
#include <resources/ResourceManager.h>
|
#include <resources/ResourceManager.h>
|
||||||
#include <resources/Resources.h>
|
#include <resources/Resources.h>
|
||||||
#include <utils/Assert.h>
|
#include <utils/Assert.h>
|
||||||
|
|
||||||
|
using namespace farmlands::graphics::backend;
|
||||||
|
|
||||||
namespace farmlands {
|
namespace farmlands {
|
||||||
namespace resources {
|
namespace resources {
|
||||||
|
|
||||||
void ResourceManager::loadTexture(int resourceId)
|
void ResourceManager::loadTexture(ResourceId resourceId)
|
||||||
{
|
{
|
||||||
Assert(RInfo[resourceId].type == ResourceType::Texture, "Resource must be a texture!");
|
Assert(RInfo[resourceId].type == ResourceType::Texture, "Resource must be a texture!");
|
||||||
if (m_loadedResources[resourceId].loaded)
|
if (m_loadedResources[resourceId].loaded)
|
||||||
@ -24,7 +27,7 @@ void ResourceManager::loadTexture(int resourceId)
|
|||||||
if (surface == NULL)
|
if (surface == NULL)
|
||||||
THROW(utils::ResourceLoadException, "Failed to load texture " + texturePath);
|
THROW(utils::ResourceLoadException, "Failed to load texture " + texturePath);
|
||||||
|
|
||||||
SDL_Texture* texture = SDL_CreateTextureFromSurface(m_gameState->sdlRenderer.internalRenderer(), surface);
|
SDL_Texture* texture = SDL_CreateTextureFromSurface(SdlRenderer::instance().internalRenderer(), surface);
|
||||||
if (texture == NULL)
|
if (texture == NULL)
|
||||||
THROW(utils::ResourceLoadException, "Failed to create texture " + texturePath);
|
THROW(utils::ResourceLoadException, "Failed to create texture " + texturePath);
|
||||||
|
|
||||||
@ -34,7 +37,7 @@ void ResourceManager::loadTexture(int resourceId)
|
|||||||
m_loadedResources[resourceId].texture.texture = texture;
|
m_loadedResources[resourceId].texture.texture = texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Texture* ResourceManager::texture(int id)
|
SDL_Texture* ResourceManager::texture(ResourceId id)
|
||||||
{
|
{
|
||||||
Assert(RInfo[id].type == ResourceType::Texture, "Resource must be a texture!");
|
Assert(RInfo[id].type == ResourceType::Texture, "Resource must be a texture!");
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user