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_
|
||||
#define MODEL_GAMESTATE_H_
|
||||
|
||||
#include <base/GameObject.h>
|
||||
#include <base/RenderContext.h>
|
||||
#include <model/Level.h>
|
||||
#include <model/Player.h>
|
||||
#include <graphics/SdlRenderer.h>
|
||||
#include <graphics/GameRenderer.h>
|
||||
#include <graphics/GuiRenderer.h>
|
||||
#include <model/Configuration.h>
|
||||
#include <resources/ResourceManager.h>
|
||||
|
||||
@ -20,32 +19,18 @@
|
||||
|
||||
namespace farmlands {
|
||||
|
||||
struct ViewportState
|
||||
{
|
||||
bool initialized;
|
||||
int width, height;
|
||||
};
|
||||
|
||||
struct Camera
|
||||
{
|
||||
float posX, posY;
|
||||
float scale;
|
||||
};
|
||||
|
||||
struct GuiState
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
struct GameState
|
||||
class GameState
|
||||
{
|
||||
// Resource layer
|
||||
resources::ResourceManager resManager;
|
||||
public:
|
||||
static GameState& current();
|
||||
static void setCurrent(GameState& state);
|
||||
|
||||
// Graphics layer
|
||||
graphics::SdlRenderer sdlRenderer;
|
||||
graphics::GuiRenderer guiRenderer;
|
||||
graphics::GameRenderer gameRenderer;
|
||||
// Render context
|
||||
base::RenderContext renderContext;
|
||||
|
||||
// Gui
|
||||
GuiState gui;
|
||||
@ -54,13 +39,14 @@ namespace farmlands {
|
||||
model::Configuration config;
|
||||
|
||||
// Current game
|
||||
ViewportState viewport;
|
||||
Camera camera;
|
||||
model::Player player;
|
||||
model::Level* currentLevel;
|
||||
base::GameObject root;
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
#include <model/Sprite.h>
|
||||
#include <base/Sprite.h>
|
||||
#include <utils/Assert.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace farmlands {
|
||||
namespace model {
|
||||
namespace base {
|
||||
|
||||
Sprite::Sprite()
|
||||
: anchorX(0), anchorY(0),
|
||||
name(),
|
||||
m_states(),
|
||||
m_currentState(0),
|
||||
m_currentFrame(0),
|
@ -14,7 +14,7 @@
|
||||
#include <unordered_map>
|
||||
|
||||
namespace farmlands {
|
||||
namespace model {
|
||||
namespace base {
|
||||
|
||||
/**
|
||||
* Defines an animation frame
|
||||
@ -72,6 +72,7 @@ namespace model {
|
||||
|
||||
// Public fields
|
||||
float anchorX, anchorY;
|
||||
std::string name;
|
||||
|
||||
private:
|
||||
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
|
||||
*/
|
||||
|
||||
#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 <SDL2/SDL.h>
|
||||
@ -14,65 +20,123 @@
|
||||
#include <unistd.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace farmlands::base;
|
||||
using namespace farmlands::graphics;
|
||||
using namespace farmlands::graphics::backend;
|
||||
using namespace farmlands::resources;
|
||||
|
||||
namespace farmlands {
|
||||
namespace controller {
|
||||
|
||||
FarmlandsGame::FarmlandsGame() :
|
||||
m_running(true),
|
||||
m_gameState(),
|
||||
m_time(0),
|
||||
m_guiController(),
|
||||
m_playerController()
|
||||
m_time(0)
|
||||
{
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
// Initialize game state
|
||||
m_gameState.viewport.initialized = false;
|
||||
m_gameState.camera.scale = 4;
|
||||
bool ok = true;
|
||||
|
||||
// Initialize render system
|
||||
if (!m_gameState.sdlRenderer.initialize(&m_gameState))
|
||||
ok &= SdlRenderer::instance().initialize(&GameState::current().renderContext);
|
||||
if (!ok)
|
||||
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
|
||||
m_gameState.resManager.initialize(&m_gameState);
|
||||
m_gameState.resManager.loadGameAssets();
|
||||
m_gameState.resManager.loadLevel(resources::R::Levels::Farm);
|
||||
m_gameState.currentLevel = m_gameState.resManager.level(resources::R::Levels::Farm);
|
||||
ResourceManager::instance().initialize();
|
||||
ResourceManager::instance().loadGameAssets();
|
||||
ResourceManager::instance().loadLevel(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;
|
||||
}
|
||||
|
||||
void FarmlandsGame::onUpdateLogic()
|
||||
{
|
||||
m_playerController.updateLogic();
|
||||
GameState::current().root.onUpdateLogic();
|
||||
}
|
||||
|
||||
void FarmlandsGame::onPreRender()
|
||||
{
|
||||
GameState::current().root.onPreRender();
|
||||
SdlRenderer::instance().renderBegin();
|
||||
}
|
||||
|
||||
void FarmlandsGame::onRender()
|
||||
{
|
||||
m_gameState.sdlRenderer.renderBegin();
|
||||
m_gameState.gameRenderer.render();
|
||||
// m_gameState.guiRenderer.render();
|
||||
m_guiController.render();
|
||||
m_gameState.sdlRenderer.renderEnd();
|
||||
GameState::current().root.onRender();
|
||||
}
|
||||
|
||||
void FarmlandsGame::onEvent(SDL_Event& event)
|
||||
{
|
||||
// Let controllers handle event
|
||||
if (m_guiController.processEvent(event))
|
||||
return;
|
||||
|
||||
if (m_playerController.processEvent(event))
|
||||
if (GameState::current().root.onEvent(event))
|
||||
return;
|
||||
|
||||
// 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()
|
||||
{
|
||||
m_running = false;
|
||||
GameState::current().root.onDestroy();
|
||||
}
|
||||
|
||||
int FarmlandsGame::run()
|
||||
@ -108,7 +179,7 @@ int FarmlandsGame::run()
|
||||
{
|
||||
// Update elapsed time
|
||||
Uint32 now = SDL_GetTicks();
|
||||
m_gameState.elapsedTime = (now - m_time) * 0.001f;
|
||||
GameState::current().elapsedTime = (now - m_time) * 0.001f;
|
||||
m_time = now;
|
||||
|
||||
SDL_Event event;
|
||||
@ -116,7 +187,9 @@ int FarmlandsGame::run()
|
||||
onEvent(event);
|
||||
|
||||
onUpdateLogic();
|
||||
onPreRender();
|
||||
onRender();
|
||||
onPostRender();
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
|
@ -11,8 +11,6 @@
|
||||
#include <GameState.h>
|
||||
#include <controller/GuiController.h>
|
||||
#include <controller/PlayerController.h>
|
||||
#include <graphics/GameRenderer.h>
|
||||
#include <graphics/SdlRenderer.h>
|
||||
#include <resources/ResourceManager.h>
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
@ -29,19 +27,19 @@ namespace controller {
|
||||
protected:
|
||||
bool initialize();
|
||||
|
||||
void onUpdateLogic();
|
||||
void onRender();
|
||||
void onEvent(SDL_Event& event);
|
||||
void onUpdateLogic();
|
||||
void onPreRender();
|
||||
void onRender();
|
||||
void onPostRender();
|
||||
|
||||
void stop();
|
||||
|
||||
private:
|
||||
bool m_running;
|
||||
GameState m_gameState;
|
||||
Uint32 m_time;
|
||||
void createScene();
|
||||
|
||||
GuiController m_guiController;
|
||||
PlayerController m_playerController;
|
||||
bool m_running;
|
||||
Uint32 m_time;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -7,18 +7,15 @@
|
||||
|
||||
#include <GameState.h>
|
||||
#include <controller/GuiController.h>
|
||||
#include <gui/RenderContext.h>
|
||||
#include <gui/widgets/TextArea.h>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace farmlands
|
||||
{
|
||||
namespace controller
|
||||
{
|
||||
|
||||
GuiController::GuiController()
|
||||
: m_gameState(nullptr)
|
||||
: m_canvas()
|
||||
{
|
||||
}
|
||||
|
||||
@ -26,15 +23,12 @@ GuiController::~GuiController()
|
||||
{
|
||||
}
|
||||
|
||||
void GuiController::initialize(GameState* gameState)
|
||||
void GuiController::onInitialize()
|
||||
{
|
||||
assert(gameState != nullptr);
|
||||
assert(gameState->viewport.initialized);
|
||||
|
||||
m_gameState = gameState;
|
||||
m_context = &GameState::current().renderContext;
|
||||
|
||||
// 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
|
||||
auto text = new gui::widgets::TextArea();
|
||||
@ -50,7 +44,7 @@ void GuiController::initialize(GameState* gameState)
|
||||
m_canvas.addChild(text);
|
||||
}
|
||||
|
||||
bool GuiController::processEvent(SDL_Event& event)
|
||||
bool GuiController::onEvent(SDL_Event& event)
|
||||
{
|
||||
bool handled = m_canvas.handleEvent(event);
|
||||
|
||||
@ -69,18 +63,11 @@ bool GuiController::processEvent(SDL_Event& event)
|
||||
return handled;
|
||||
}
|
||||
|
||||
void GuiController::render()
|
||||
void GuiController::onRender()
|
||||
{
|
||||
// Compute render context
|
||||
gui::RenderContext renderContext =
|
||||
{
|
||||
.sdlRenderer = &m_gameState->sdlRenderer,
|
||||
.resManager = &m_gameState->resManager,
|
||||
.uiScale = 1,
|
||||
};
|
||||
|
||||
// Render
|
||||
m_canvas.render(renderContext);
|
||||
m_canvas.render(m_context);
|
||||
}
|
||||
|
||||
} /* namespace controller */
|
||||
|
@ -8,18 +8,16 @@
|
||||
#ifndef CONTROLLER_GUICONTROLLER_H_
|
||||
#define CONTROLLER_GUICONTROLLER_H_
|
||||
|
||||
#include <base/Component.h>
|
||||
#include <base/RenderContext.h>
|
||||
#include <gui/layout/Canvas.h>
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
namespace farmlands {
|
||||
|
||||
// Forward declarations
|
||||
struct GameState;
|
||||
|
||||
namespace controller {
|
||||
|
||||
class GuiController
|
||||
class GuiController : public base::Component
|
||||
{
|
||||
public:
|
||||
GuiController();
|
||||
@ -28,21 +26,13 @@ namespace controller {
|
||||
/**
|
||||
* Initializes game renderer
|
||||
*/
|
||||
void initialize(GameState* gameState);
|
||||
|
||||
/**
|
||||
* Processes an UI event
|
||||
*/
|
||||
bool processEvent(SDL_Event& event);
|
||||
|
||||
/**
|
||||
* Renders the GUI
|
||||
*/
|
||||
void render();
|
||||
virtual void onInitialize() override;
|
||||
virtual bool onEvent(SDL_Event& event) override;
|
||||
virtual void onRender() override;
|
||||
|
||||
private:
|
||||
GameState* m_gameState;
|
||||
gui::layout::Canvas m_canvas;
|
||||
base::RenderContext* m_context;
|
||||
};
|
||||
|
||||
} /* namespace controller */
|
||||
|
@ -7,13 +7,48 @@
|
||||
|
||||
#include <GameState.h>
|
||||
#include <controller/PlayerController.h>
|
||||
#include <graphics/SpriteRenderer.h>
|
||||
#include <input/Input.h>
|
||||
#include <utils/Assert.h>
|
||||
|
||||
using namespace farmlands::input;
|
||||
using namespace farmlands::graphics;
|
||||
using namespace farmlands::model;
|
||||
|
||||
namespace farmlands {
|
||||
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()
|
||||
: 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_gameState = gameState;
|
||||
m_transform = gameObject->component<base::Transform>();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void PlayerController::updateLogic()
|
||||
void PlayerController::onUpdateLogic()
|
||||
{
|
||||
// Get keyboard status
|
||||
const Uint8* keys = SDL_GetKeyboardState(NULL);
|
||||
// Compute movement velocity
|
||||
float velMultiplier = PlayerWalkVelocity;
|
||||
|
||||
float deltaX = 0;
|
||||
float deltaY = 0;
|
||||
if (Input::instance().pressed(GameKey::Run))
|
||||
velMultiplier = PlayerRunVelocity;
|
||||
|
||||
// Compute movement delta multiplier
|
||||
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))
|
||||
if (m_attackTimeLeft)
|
||||
{
|
||||
m_gameState->player.posX = newX;
|
||||
m_gameState->player.posY = newY;
|
||||
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;
|
||||
velMultiplier = PlayerAttackVelocity;
|
||||
--m_attackTimeLeft;
|
||||
}
|
||||
|
||||
// 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)
|
||||
@ -84,20 +146,17 @@ bool PlayerController::canMove(float x, float y)
|
||||
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 },
|
||||
{ model::Direction::North, model::Direction::South, model::Direction::South },
|
||||
{ model::Direction::NorthEast, model::Direction::East, model::Direction::SouthEast },
|
||||
};
|
||||
int xx = (0 < vx) - (vx < 0);
|
||||
int yy = (0 < vy) - (vy < 0);
|
||||
|
||||
void PlayerController::setDirection(float dx, float dy)
|
||||
return VelocitySignDirections[xx + 1][yy + 1];
|
||||
}
|
||||
|
||||
void PlayerController::attack()
|
||||
{
|
||||
int xx = (0 < dx) - (dx < 0);
|
||||
int yy = (0 < dy) - (dy < 0);
|
||||
|
||||
if (xx != 0 || yy != 0)
|
||||
m_gameState->player.direction = directions[xx + 1][yy + 1];
|
||||
// For now - nothing
|
||||
}
|
||||
|
||||
} /* namespace controller */
|
||||
|
@ -8,6 +8,8 @@
|
||||
#ifndef CONTROLLER_PLAYERCONTROLLER_H_
|
||||
#define CONTROLLER_PLAYERCONTROLLER_H_
|
||||
|
||||
#include <base/Component.h>
|
||||
#include <base/Transform.h>
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
namespace farmlands {
|
||||
@ -17,34 +19,27 @@ struct GameState;
|
||||
|
||||
namespace controller {
|
||||
|
||||
class PlayerController
|
||||
class PlayerController : public base::Component
|
||||
{
|
||||
public:
|
||||
PlayerController();
|
||||
virtual ~PlayerController();
|
||||
|
||||
/**
|
||||
* Initializes game renderer
|
||||
*/
|
||||
void initialize(GameState* gameState);
|
||||
|
||||
/**
|
||||
* 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();
|
||||
virtual void onInitialize() override;
|
||||
virtual bool onEvent(SDL_Event& event) override;
|
||||
virtual void onUpdateLogic() override;
|
||||
virtual void onPreRender() override;
|
||||
|
||||
private:
|
||||
bool canMove(float x, float y);
|
||||
void setDirection(float dx, float dy);
|
||||
static model::Direction getDirection(float vx, float vy);
|
||||
|
||||
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 */
|
||||
|
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 <graphics/SdlRenderer.h>
|
||||
#include <graphics/backend/SdlRenderer.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
@ -15,15 +15,21 @@
|
||||
#include <SDL2/SDL_image.h>
|
||||
#include <SDL2/SDL_ttf.h>
|
||||
|
||||
namespace farmlands
|
||||
{
|
||||
namespace graphics
|
||||
namespace farmlands {
|
||||
namespace graphics {
|
||||
namespace backend {
|
||||
|
||||
// Singleton instance
|
||||
SdlRenderer SdlRenderer::s_instance;
|
||||
|
||||
SdlRenderer& SdlRenderer::instance()
|
||||
{
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
SdlRenderer::SdlRenderer()
|
||||
: m_sdlWindow(nullptr),
|
||||
m_sdlRenderer(nullptr),
|
||||
m_gameState(nullptr)
|
||||
m_sdlRenderer(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@ -38,10 +44,8 @@ SdlRenderer::~SdlRenderer()
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
bool SdlRenderer::initialize(GameState* gameState)
|
||||
bool SdlRenderer::initialize(base::RenderContext* renderContext)
|
||||
{
|
||||
m_gameState = gameState;
|
||||
|
||||
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
|
||||
std::cerr << "Failed to initialize SDL!\n";
|
||||
return false;
|
||||
@ -58,10 +62,10 @@ bool SdlRenderer::initialize(GameState* gameState)
|
||||
return false;
|
||||
}
|
||||
|
||||
m_gameState->viewport.initialized = true;
|
||||
m_gameState->viewport.width = 1024;
|
||||
m_gameState->viewport.height = 768;
|
||||
m_sdlWindow = SDL_CreateWindow("Farmlands", 0, 0, m_gameState->viewport.width, m_gameState->viewport.height, SDL_WINDOW_SHOWN);
|
||||
renderContext->viewport.initialized = true;
|
||||
renderContext->viewport.width = 1024;
|
||||
renderContext->viewport.height = 768;
|
||||
m_sdlWindow = SDL_CreateWindow("Farmlands", 0, 0, renderContext->viewport.width, renderContext->viewport.height, SDL_WINDOW_SHOWN);
|
||||
if (!m_sdlWindow) {
|
||||
std::cerr << "Failed to create main window!\n";
|
||||
return false;
|
||||
@ -88,6 +92,11 @@ void SdlRenderer::renderEnd()
|
||||
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)
|
||||
{
|
||||
assert(font != nullptr);
|
||||
@ -102,7 +111,12 @@ SDL_Texture* SdlRenderer::renderText(const std::string& text, TTF_Font* font, SD
|
||||
return texture;
|
||||
}
|
||||
|
||||
void SdlRenderer::getTextureSize(SDL_Texture* texture, int* width, int* height)
|
||||
{
|
||||
SDL_QueryTexture(texture, NULL, NULL, width, height);
|
||||
}
|
||||
|
||||
}
|
||||
} /* namespace graphics */
|
||||
} /* namespace farmlands */
|
||||
|
||||
|
@ -8,30 +8,30 @@
|
||||
#ifndef GRAPHICS_SDLRENDERER_H_
|
||||
#define GRAPHICS_SDLRENDERER_H_
|
||||
|
||||
#include <base/RenderContext.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_ttf.h>
|
||||
|
||||
namespace farmlands {
|
||||
|
||||
// Forward declarations
|
||||
struct GameState;
|
||||
|
||||
namespace graphics {
|
||||
namespace backend {
|
||||
|
||||
class SdlRenderer
|
||||
{
|
||||
public:
|
||||
SdlRenderer();
|
||||
virtual ~SdlRenderer();
|
||||
static SdlRenderer& instance();
|
||||
|
||||
~SdlRenderer();
|
||||
|
||||
/**
|
||||
* Initializes the game renderer.
|
||||
*
|
||||
* @returns true if successful, false otherwise.
|
||||
*/
|
||||
bool initialize(GameState* gameState);
|
||||
bool initialize(base::RenderContext* renderContext);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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
|
||||
/**
|
||||
* Gets the internal SDL renderer object;
|
||||
@ -56,12 +66,15 @@ namespace graphics {
|
||||
|
||||
private:
|
||||
|
||||
SdlRenderer();
|
||||
|
||||
SDL_Window* m_sdlWindow;
|
||||
SDL_Renderer* m_sdlRenderer;
|
||||
|
||||
GameState* m_gameState;
|
||||
static SdlRenderer s_instance;
|
||||
};
|
||||
|
||||
}
|
||||
} /* namespace graphics */
|
||||
} /* 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)
|
||||
child->render(context);
|
||||
|
@ -9,7 +9,6 @@
|
||||
#define GUI_PRIMITIVES_CANVAS_H_
|
||||
|
||||
#include <gui/primitives/UILayout.h>
|
||||
#include <gui/RenderContext.h>
|
||||
|
||||
namespace farmlands {
|
||||
namespace gui {
|
||||
@ -21,7 +20,7 @@ namespace layout {
|
||||
Canvas();
|
||||
virtual ~Canvas();
|
||||
|
||||
virtual void render(RenderContext& context) override;
|
||||
virtual void render(base::RenderContext* context) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -5,8 +5,11 @@
|
||||
* Author: tibi
|
||||
*/
|
||||
|
||||
#include <graphics/backend/SdlRenderer.h>
|
||||
#include <gui/primitives/UIElement.h>
|
||||
|
||||
using namespace farmlands::graphics::backend;
|
||||
|
||||
namespace farmlands
|
||||
{
|
||||
namespace gui
|
||||
@ -24,7 +27,7 @@ UIElement::~UIElement()
|
||||
{
|
||||
}
|
||||
|
||||
void UIElement::render(RenderContext& context)
|
||||
void UIElement::render(base::RenderContext* context)
|
||||
{
|
||||
if (m_backColor.a > 0)
|
||||
{
|
||||
@ -36,8 +39,8 @@ void UIElement::render(RenderContext& context)
|
||||
(int) m_h
|
||||
};
|
||||
|
||||
SDL_SetRenderDrawColor(context.sdlRenderer->internalRenderer(), m_backColor.r, m_backColor.g, m_backColor.b, m_backColor.a);
|
||||
SDL_RenderFillRect(context.sdlRenderer->internalRenderer(), &rect);
|
||||
SDL_SetRenderDrawColor(SdlRenderer::instance().internalRenderer(), m_backColor.r, m_backColor.g, m_backColor.b, m_backColor.a);
|
||||
SDL_RenderFillRect(SdlRenderer::instance().internalRenderer(), &rect);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
#include <gui/RenderContext.h>
|
||||
#include <base/RenderContext.h>
|
||||
|
||||
namespace farmlands {
|
||||
namespace gui {
|
||||
@ -22,7 +22,7 @@ namespace primitives {
|
||||
UIElement();
|
||||
virtual ~UIElement();
|
||||
|
||||
virtual void render(RenderContext& context);
|
||||
virtual void render(base::RenderContext* context);
|
||||
virtual bool handleEvent(SDL_Event& event);
|
||||
|
||||
// Getters & setters
|
||||
|
@ -5,8 +5,10 @@
|
||||
* Author: tibi
|
||||
*/
|
||||
|
||||
#include <graphics/backend/SdlRenderer.h>
|
||||
#include <gui/widgets/TextArea.h>
|
||||
#include <resources/Resources.h>
|
||||
#include <resources/ResourceManager.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
@ -14,12 +16,12 @@
|
||||
|
||||
#include <SDL2/SDL_ttf.h>
|
||||
|
||||
namespace farmlands
|
||||
{
|
||||
namespace gui
|
||||
{
|
||||
namespace widgets
|
||||
{
|
||||
using namespace farmlands::graphics::backend;
|
||||
using namespace farmlands::resources;
|
||||
|
||||
namespace farmlands {
|
||||
namespace gui {
|
||||
namespace widgets {
|
||||
|
||||
TextArea::TextArea()
|
||||
: m_text(),
|
||||
@ -39,12 +41,12 @@ TextArea::~TextArea()
|
||||
{
|
||||
}
|
||||
|
||||
void TextArea::render(RenderContext& context)
|
||||
void TextArea::render(base::RenderContext* context)
|
||||
{
|
||||
UIElement::render(context);
|
||||
|
||||
// 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)
|
||||
return; // TODO: handle error (maybe log it)
|
||||
|
||||
@ -94,7 +96,7 @@ void TextArea::render(RenderContext& context)
|
||||
dest.y = y() + totalH;
|
||||
|
||||
// Draw
|
||||
SDL_RenderCopy(context.sdlRenderer->internalRenderer(), lineTexture, NULL, &dest);
|
||||
SdlRenderer::instance().renderTexture(lineTexture, NULL, &dest);
|
||||
|
||||
totalH += lineH;
|
||||
}
|
||||
@ -256,7 +258,7 @@ void TextArea::wrapText(TTF_Font* font)
|
||||
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
|
||||
for (SDL_Texture* tex : m_renderedLines)
|
||||
@ -270,7 +272,7 @@ void TextArea::renderLines(RenderContext& context, TTF_Font* font)
|
||||
for (std::string line : lines)
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ namespace widgets {
|
||||
TextArea();
|
||||
virtual ~TextArea();
|
||||
|
||||
virtual void render(RenderContext& context) override;
|
||||
virtual void render(base::RenderContext* context) override;
|
||||
|
||||
// Getters and setters
|
||||
inline std::string text() const { return m_text; }
|
||||
@ -71,7 +71,7 @@ namespace widgets {
|
||||
|
||||
private:
|
||||
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_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
|
||||
{
|
||||
East = 0,
|
||||
NorthEast = 1,
|
||||
None = 0,
|
||||
East = 1,
|
||||
North = 2,
|
||||
NorthWest = 3,
|
||||
West = 4,
|
||||
SouthWest = 5,
|
||||
South = 6,
|
||||
SouthEast = 7
|
||||
South = 8,
|
||||
NorthEast = North | East,
|
||||
NorthWest = North | West,
|
||||
SouthWest = South | West,
|
||||
SouthEast = South | East
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -21,6 +21,8 @@ namespace model {
|
||||
float lastDeltaX, lastDeltaY;
|
||||
Direction direction;
|
||||
|
||||
bool attacking;
|
||||
uint32_t attackTimeLeft;
|
||||
|
||||
int inventorySelection = -1;
|
||||
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_
|
||||
#define STORAGE_RESOURCEMANAGER_H_
|
||||
|
||||
#include <base/Sprite.h>
|
||||
#include <model/Level.h>
|
||||
#include <model/Sprite.h>
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
@ -40,32 +40,37 @@ namespace resources {
|
||||
} texture;
|
||||
|
||||
model::Level* level;
|
||||
model::Sprite* sprite;
|
||||
base::Sprite* sprite;
|
||||
};
|
||||
};
|
||||
|
||||
typedef uint32_t ResourceId;
|
||||
|
||||
class ResourceManager
|
||||
{
|
||||
public:
|
||||
ResourceManager();
|
||||
virtual ~ResourceManager();
|
||||
void initialize(GameState* gameState);
|
||||
static ResourceManager& instance();
|
||||
~ResourceManager();
|
||||
|
||||
void initialize();
|
||||
|
||||
// Loading routines
|
||||
void loadMainMenu();
|
||||
void loadGameAssets();
|
||||
void loadLevel(int levelId);
|
||||
void loadLevel(ResourceId levelId);
|
||||
|
||||
TTF_Font* font(int id, int pointSize);
|
||||
SDL_Texture* texture(int id);
|
||||
model::Level* level(int id);
|
||||
model::Sprite* sprite(int id);
|
||||
TTF_Font* font(ResourceId id, int pointSize);
|
||||
SDL_Texture* texture(ResourceId id);
|
||||
model::Level* level(ResourceId id);
|
||||
base::Sprite* sprite(ResourceId id);
|
||||
|
||||
private:
|
||||
ResourceManager();
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@ -73,13 +78,12 @@ namespace resources {
|
||||
*/
|
||||
int getId(std::string resourcePath);
|
||||
|
||||
void loadFont(int fontId, int pointSize);
|
||||
void loadTexture(int textureId);
|
||||
void loadSprite(int spriteId);
|
||||
void loadLevelLayer(model::Level* level, size_t layerNumber, int resourceId);
|
||||
void loadFont(ResourceId fontId, int pointSize);
|
||||
void loadTexture(ResourceId textureId);
|
||||
void loadSprite(ResourceId spriteId);
|
||||
void loadLevelLayer(model::Level* level, size_t layerNumber, ResourceId resourceId);
|
||||
|
||||
// State
|
||||
GameState* m_gameState;
|
||||
static ResourceManager s_instance;
|
||||
|
||||
// Loaded resources
|
||||
LoadedResource* m_loadedResources;
|
||||
|
@ -14,9 +14,15 @@
|
||||
namespace farmlands {
|
||||
namespace resources {
|
||||
|
||||
ResourceManager ResourceManager::s_instance;
|
||||
|
||||
ResourceManager& ResourceManager::instance()
|
||||
{
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
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++)
|
||||
m_loadedResources[i].loaded = false;
|
||||
@ -53,9 +59,8 @@ ResourceManager::~ResourceManager()
|
||||
delete[] m_loadedResources;
|
||||
}
|
||||
|
||||
void ResourceManager::initialize(GameState* gameState)
|
||||
void ResourceManager::initialize()
|
||||
{
|
||||
m_gameState = gameState;
|
||||
}
|
||||
|
||||
void ResourceManager::loadMainMenu()
|
||||
@ -67,7 +72,7 @@ void ResourceManager::loadGameAssets()
|
||||
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.");
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
namespace farmlands {
|
||||
namespace resources {
|
||||
|
||||
TTF_Font* ResourceManager::font(int id, int pointSize)
|
||||
TTF_Font* ResourceManager::font(ResourceId id, int pointSize)
|
||||
{
|
||||
// Open from cache
|
||||
auto it = m_fontCache.find(FONTID(id, pointSize));
|
||||
|
@ -19,7 +19,7 @@ using namespace nlohmann;
|
||||
namespace farmlands {
|
||||
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.");
|
||||
|
||||
@ -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
|
||||
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;
|
||||
}
|
||||
|
||||
model::Level* ResourceManager::level(int id)
|
||||
model::Level* ResourceManager::level(ResourceId id)
|
||||
{
|
||||
Assert(RInfo[id].type == ResourceType::Level, "Resource must be a level!");
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* Created on: Nov 29, 2016
|
||||
* Author: tibi
|
||||
*/
|
||||
#include <model/Sprite.h>
|
||||
#include <base/Sprite.h>
|
||||
#include <resources/ResourceManager.h>
|
||||
#include <resources/Resources.h>
|
||||
#include <utils/Assert.h>
|
||||
@ -15,12 +15,13 @@
|
||||
#include <json.hpp>
|
||||
|
||||
using namespace nlohmann;
|
||||
using namespace farmlands::base;
|
||||
|
||||
namespace farmlands {
|
||||
namespace resources {
|
||||
|
||||
|
||||
void ResourceManager::loadSprite(int spriteId)
|
||||
void ResourceManager::loadSprite(ResourceId spriteId)
|
||||
{
|
||||
Assert(RInfo[spriteId].type == ResourceType::Sprite, "Resource must be a sprite!");
|
||||
if (m_loadedResources[spriteId].loaded)
|
||||
@ -36,7 +37,7 @@ void ResourceManager::loadSprite(int spriteId)
|
||||
json spriteJs;
|
||||
spriteIn >> spriteJs;
|
||||
|
||||
model::Sprite* sprite = new model::Sprite();
|
||||
Sprite* sprite = new Sprite();
|
||||
sprite->anchorX = spriteJs.value("anchorX", 0.0f);
|
||||
sprite->anchorY = spriteJs.value("anchorY", 0.0f);
|
||||
|
||||
@ -44,14 +45,14 @@ void ResourceManager::loadSprite(int spriteId)
|
||||
|
||||
for (auto state : statesJs)
|
||||
{
|
||||
model::SpriteState spriteState;
|
||||
SpriteState spriteState;
|
||||
spriteState.name = state.value("name", std::string());
|
||||
|
||||
// Obtain frames
|
||||
json framesJs = state.at("frames");
|
||||
for (auto frame : framesJs)
|
||||
{
|
||||
model::Frame spriteFrame;
|
||||
Frame spriteFrame;
|
||||
spriteFrame.tileSetCell = frame.value("cell", 0u);
|
||||
spriteFrame.width = frame.value("width", 0u);
|
||||
spriteFrame.height = frame.value("height", 0u);
|
||||
@ -74,7 +75,7 @@ void ResourceManager::loadSprite(int spriteId)
|
||||
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!");
|
||||
|
||||
|
@ -4,15 +4,18 @@
|
||||
* Created on: Nov 12, 2016
|
||||
* Author: tibi
|
||||
*/
|
||||
#include <GameState.h>
|
||||
|
||||
#include <graphics/backend/SdlRenderer.h>
|
||||
#include <resources/ResourceManager.h>
|
||||
#include <resources/Resources.h>
|
||||
#include <utils/Assert.h>
|
||||
|
||||
using namespace farmlands::graphics::backend;
|
||||
|
||||
namespace farmlands {
|
||||
namespace resources {
|
||||
|
||||
void ResourceManager::loadTexture(int resourceId)
|
||||
void ResourceManager::loadTexture(ResourceId resourceId)
|
||||
{
|
||||
Assert(RInfo[resourceId].type == ResourceType::Texture, "Resource must be a texture!");
|
||||
if (m_loadedResources[resourceId].loaded)
|
||||
@ -24,7 +27,7 @@ void ResourceManager::loadTexture(int resourceId)
|
||||
if (surface == NULL)
|
||||
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)
|
||||
THROW(utils::ResourceLoadException, "Failed to create texture " + texturePath);
|
||||
|
||||
@ -34,7 +37,7 @@ void ResourceManager::loadTexture(int resourceId)
|
||||
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!");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user