Implemented many things. Refactored parsers. Added some behaviors and items. Added weapons.

This commit is contained in:
Tiberiu Chibici 2016-12-02 20:29:40 +02:00
parent 0b6a988184
commit f255905c73
70 changed files with 1614 additions and 908 deletions

View File

@ -16,7 +16,7 @@
<folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1767279125." name="/" resourcePath=""> <folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1767279125." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.263074825" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug"> <toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.263074825" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug">
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.361182110" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/> <targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.361182110" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/>
<builder buildPath="${workspace_loc:/Farmlands}/Debug" id="org.eclipse.cdt.build.core.internal.builder.1184678368" keepEnvironmentInBuildfile="false" name="CDT Internal Builder" superClass="org.eclipse.cdt.build.core.internal.builder"/> <builder autoBuildTarget="" buildPath="${workspace_loc:/Farmlands}/Debug" cleanBuildTarget="" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="org.eclipse.cdt.build.core.internal.builder.1184678368" incrementalBuildTarget="" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="CDT Internal Builder" parallelBuildOn="true" parallelizationNumber="optimal" stopOnErr="false" superClass="org.eclipse.cdt.build.core.internal.builder"/>
<tool id="cdt.managedbuild.tool.gnu.archiver.base.1607221000" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/> <tool id="cdt.managedbuild.tool.gnu.archiver.base.1607221000" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
<tool command="g++" commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}" id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.1808198807" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug"> <tool command="g++" commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}" id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.1808198807" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug">
<option id="gnu.cpp.compiler.exe.debug.option.optimization.level.593370343" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/> <option id="gnu.cpp.compiler.exe.debug.option.optimization.level.593370343" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
@ -81,18 +81,16 @@
<extensions> <extensions>
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/> <extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions> </extensions>
</storageModule> </storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0"> <storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.1609929883" name="Release" parent="cdt.managedbuild.config.gnu.exe.release" preannouncebuildStep="" prebuildStep=""> <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.1609929883" name="Release" parent="cdt.managedbuild.config.gnu.exe.release" preannouncebuildStep="" prebuildStep="">
<folderInfo id="cdt.managedbuild.config.gnu.exe.release.1609929883." name="/" resourcePath=""> <folderInfo id="cdt.managedbuild.config.gnu.exe.release.1609929883." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.2003855563" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release"> <toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.2003855563" name="Linux GCC" nonInternalBuilderId="cdt.managedbuild.target.gnu.builder.exe.release" superClass="cdt.managedbuild.toolchain.gnu.exe.release">
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.release.2010013881" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/> <targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.release.2010013881" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/>
<builder buildPath="${workspace_loc:/Farmlands}/Release" id="cdt.managedbuild.target.gnu.builder.exe.release.1908151018" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.release"/> <builder autoBuildTarget="all" buildPath="${workspace_loc:/Farmlands}/Release" cleanBuildTarget="clean" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="org.eclipse.cdt.build.core.internal.builder.2098680958" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="CDT Internal Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="org.eclipse.cdt.build.core.internal.builder"/>
<tool id="cdt.managedbuild.tool.gnu.archiver.base.1727165317" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/> <tool id="cdt.managedbuild.tool.gnu.archiver.base.1727165317" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1249722811" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release"> <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1249722811" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release">
<option id="gnu.cpp.compiler.exe.release.option.optimization.level.1342166702" name="Optimization Level" superClass="gnu.cpp.compiler.exe.release.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/> <option id="gnu.cpp.compiler.exe.release.option.optimization.level.1342166702" name="Optimization Level" superClass="gnu.cpp.compiler.exe.release.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>

17
assets/items/Tools.items Normal file
View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8" ?>Player
<ItemCollection>
<GameObject name="Stone pickaxe">
<Transform />
<SpriteRenderer sprite="sprites/items/StonePickaxe.sprite" />
<Item name="Stone pickaxe"
description="The most basic type of pickaxe. It can break small stones."
level="1" />
<Weapon damage="1"
critProbability="0"
critDamage="0"
attackDuration="0.5" />
<PickaxeItem />
</GameObject>
</ItemCollection>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8" ?>
<ItemCollection>
<GameObject name="Level 1 Sword">
<Transform />
<SpriteRenderer sprite="sprites/items/Lvl1Sword.sprite" />
<Item name="Level 1 Sword"
description="Better than nothing."
level="1" />
<Weapon damage="3"
critProbability="0.01"
critDamage="9"
attackDuration="0.4" />
</GameObject>
<GameObject name="Level 2 Sword">
<Transform />
<SpriteRenderer sprite="sprites/items/Lvl2Sword.sprite" />
<Item name="Level 2 Sword"
description="Better than basic sword."
level="2" />
<Weapon damage="6"
critProbability="0.01"
critDamage="18"
attackDuration="0.4" />
</GameObject>
</ItemCollection>

View File

@ -1,15 +0,0 @@
{
"name" : "Level 1 Sword",
"description" : "Most basic sword.",
"enemyDamage" : 3,
"attackDuration" : 10,
"criticalProbability" : 0.01,
"level" : 1,
"tool" : true,
"giftable" : false,
"sellable" : false,
"sprite" : "sprites/items/lvl1_sword.sprite"
}

View File

@ -1,16 +0,0 @@
{
"name" : "Stone pickaxe",
"description" : "The most basic type of pickaxe. It can break small stones.",
"enemyDamage" : 1,
"criticalProbability" : 0,
"level" : 1,
"tool" : true,
"giftable" : false,
"sellable" : false,
"sprite" : "sprites/items/stone_pickaxe.sprite",
"controller" : "PickaxeItem"
}

View File

@ -1,29 +1,29 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<Scene cellWidth="16" <Scene cellWidth="16"
cellHeight="16"> cellHeight="16">
<!-- Main camera --> <!-- Main camera -->
<GameObject name="Main Camera"> <GameObject name="Main Camera">
<Transform /> <Transform />
<Camera scale="4" mainCamera="true" /> <Camera scale="4" mainCamera="true" />
</GameObject> </GameObject>
<!-- Background object --> <!-- Background object -->
<GameObject name="Background"> <GameObject name="Background">
<Background src="levels/Farm.back" /> <Background src="levels/Farm.back" />
<BackgroundRenderer /> <BackgroundRenderer />
</GameObject> </GameObject>
<!-- Player object --> <!-- Player object -->
<GameObject name="Player"> <GameObject name="Player">
<Transform x="120" y="100" /> <Transform x="120" y="100" />
<SpriteRenderer sprite="sprites/Player.sprite" /> <SpriteRenderer sprite="sprites/Player.sprite" />
<PlayerController /> <PlayerController />
</GameObject> </GameObject>
<!-- Debug object --> <!-- Debug object -->
<GameObject name="Debug"> <GameObject name="Debug">
<DebugController /> <DebugController />
</GameObject> </GameObject>
</Scene> </Scene>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8" ?>
<Sprite name="Lvl1Sword"
anchorX="0" anchorY="1">
<State name="Normal">
<Frame tileSet="sprites/items/sword.png" cell="0" w="1" h="1" duration="1" />
</State>
<State name="Attack">
<Frame tileSet="sprites/items/sword.png" cell="1" w="1" h="1" duration="1" />
</State>
</Sprite>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" ?>
<Sprite name="Lvl2Sword"
anchorX="0" anchorY="1">
<State name="Normal">
<Frame tileSet="sprites/items/sword.png" cell="0" w="1" h="1" duration="1" />
</State>
<State name="Attack">
<Frame tileSet="sprites/items/sword.png" cell="0" w="1" h="1" duration="10" />
<Frame tileSet="sprites/items/sword.png" cell="1" w="1" h="1" duration="10" />
</State>
</Sprite>

View File

@ -1,36 +0,0 @@
{
"name" : "Level 1 sword",
"anchorX" : 0,
"anchorY" : 1,
"states" :
[
{
"name" : "Normal",
"frames" :
[
{
"tileSet" : "tilesets/PlayerTiles.png",
"cell" : 0,
"width" : 1,
"height" : 2,
"duration" : 1
}
]
},
{
"name" : " Attack",
"frames" :
[
{
"tileSet" : "tilesets/PlayerTiles.png",
"cell" : 2,
"width" : 1,
"height" : 2,
"duration" : 1
}
]
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 B

BIN
assets_original/sword.xcf Normal file

Binary file not shown.

View File

@ -52,6 +52,7 @@ FILE_TYPES = [
([".back"], "Background"), ([".back"], "Background"),
([".csv"], "BackgroundLayer"), ([".csv"], "BackgroundLayer"),
([".item"], "Item"), ([".item"], "Item"),
([".items"], "ItemCollection"),
] ]

View File

@ -14,7 +14,8 @@ GameState::GameState()
: renderContext(), : renderContext(),
scene(nullptr), scene(nullptr),
config(nullptr), config(nullptr),
elapsedTime(0) elapsedTime(0),
gameInitialized(false)
{ {
} }

View File

@ -10,7 +10,7 @@
#include <base/GameObject.h> #include <base/GameObject.h>
#include <base/RenderContext.h> #include <base/RenderContext.h>
#include <base/Scene.h> #include <model/Scene.h>
#include <model/Configuration.h> #include <model/Configuration.h>
#include <resources/ResourceManager.h> #include <resources/ResourceManager.h>
@ -26,13 +26,19 @@ namespace farmlands {
static GameState& current(); static GameState& current();
static void setCurrent(GameState& state); static void setCurrent(GameState& state);
// Game settings
model::Configuration* config;
// Render context // Render context
base::RenderContext renderContext; base::RenderContext renderContext;
base::Scene* scene;
model::Configuration* config; // Scene
model::Scene* scene;
std::vector<base::GameObject*> itemPrefabs;
// Misc // Misc
float elapsedTime; float elapsedTime;
bool gameInitialized;
private: private:
static GameState s_current; static GameState s_current;

View File

@ -6,8 +6,10 @@
*/ */
#include <GameState.h> #include <GameState.h>
#include <base/Camera.h>
#include <base/Component.h> #include <base/Component.h>
#include <base/Camera.h>
#include <iostream>
namespace farmlands { namespace farmlands {
namespace base { namespace base {
@ -22,6 +24,15 @@ Camera::~Camera()
{ {
} }
Component* Camera::clone()
{
Camera* clone = new Camera();
clone->mainCamera = mainCamera;
clone->scale = scale;
return clone;
}
void Camera::onCreate() void Camera::onCreate()
{ {
if (mainCamera) if (mainCamera)
@ -30,6 +41,16 @@ void Camera::onCreate()
} }
} }
void Camera::dump(unsigned level)
{
for (unsigned i = 0; i < level; i++)
std::cout<<" ";
std::cout << " .Component: Camera ";
std::cout << "main="<<mainCamera<<" ";
std::cout << "scale="<<scale<<"\n";
}
} }
} }

View File

@ -13,17 +13,19 @@
namespace farmlands { namespace farmlands {
namespace base { namespace base {
class Camera : public Component class Camera : public base::Component
{ {
public: public:
Camera(); Camera();
virtual ~Camera(); virtual ~Camera();
virtual base::Component* clone() override;
virtual void dump(unsigned level) override;
virtual void onCreate(); virtual void onCreate();
float scale; float scale;
bool mainCamera; bool mainCamera;
}; };
} }

View File

@ -52,6 +52,14 @@ void Component::onDestroy()
{ {
} }
void Component::onEnable()
{
}
void Component::onDisable()
{
}
} }
/* namespace base */ /* namespace base */
} /* namespace farmlands */ } /* namespace farmlands */

View File

@ -8,6 +8,9 @@
#ifndef COMPONENT_H_ #ifndef COMPONENT_H_
#define COMPONENT_H_ #define COMPONENT_H_
#include <base/ICloneable.h>
#include <base/INonAssignable.h>
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
namespace farmlands { namespace farmlands {
@ -15,7 +18,7 @@ namespace base {
class GameObject; class GameObject;
class Component class Component : public INonAssignable, public ICloneable<Component>
{ {
public: public:
Component(); Component();
@ -31,6 +34,12 @@ namespace base {
virtual void onPostRender(); virtual void onPostRender();
virtual void onDestroy(); virtual void onDestroy();
virtual void onEnable();
virtual void onDisable();
// Print info to screen
virtual void dump(unsigned level) = 0;
GameObject* gameObject; GameObject* gameObject;
}; };

View File

@ -5,19 +5,46 @@
* Author: tibi * Author: tibi
*/ */
#include <GameState.h>
#include <base/GameObject.h> #include <base/GameObject.h>
#include <base/Component.h> #include <base/Component.h>
#include <iostream>
namespace farmlands { namespace farmlands {
namespace base { namespace base {
GameObject::GameObject() GameObject::GameObject()
: m_components(), : name("unnamed"),
visible(true),
m_components(),
m_children(), m_children(),
m_parent(nullptr) m_parent(nullptr),
m_enabled(false)
{ {
} }
GameObject* GameObject::clone()
{
GameObject* clone = new GameObject();
clone->visible = visible;
// Clone components
for (auto pair : m_components)
{
Component* compClone = pair.second->clone();
compClone->gameObject = clone;
clone->m_components.emplace(pair.first, compClone);
}
// Clone components
for (auto child : m_children)
clone->addChild(child->clone());
return clone;
}
GameObject::~GameObject() GameObject::~GameObject()
{ {
// Delete children // Delete children
@ -35,6 +62,25 @@ GameObject::~GameObject()
} }
} }
GameObject* GameObject::instantiate(GameObject* gameObject, std::string name, GameObject* parent)
{
Assert(gameObject != nullptr, "Can't instantiate a null object!");
Assert(parent != nullptr, "Parent cannot be null!");
// Clone object
GameObject* instance = gameObject->clone();
instance->name = name;
parent->addChild(instance);
// Call methods
instance->onCreate();
if (GameState::current().gameInitialized)
instance->onInitialize();
return instance;
}
void GameObject::addChild(GameObject* obj) void GameObject::addChild(GameObject* obj)
{ {
m_children.push_back(obj); m_children.push_back(obj);
@ -51,6 +97,25 @@ GameObject* GameObject::removeChild(size_t index)
return child; return child;
} }
void GameObject::destroyChild(size_t index)
{
delete m_children.at(index);
m_children.erase(m_children.begin() + index);
}
void GameObject::destroyChild(GameObject* obj)
{
for (auto it = m_children.begin(); it != m_children.end(); it++)
{
if (*it == obj)
{
delete *it;
m_children.erase(it);
return;
}
}
}
size_t GameObject::childrenCount() const size_t GameObject::childrenCount() const
{ {
return m_children.size(); return m_children.size();
@ -68,6 +133,9 @@ GameObject* GameObject::parent()
void GameObject::onCreate() void GameObject::onCreate()
{ {
// Enable self
setEnabled(true);
// Call components // Call components
for (auto pair : m_components) for (auto pair : m_components)
pair.second->onCreate(); pair.second->onCreate();
@ -98,7 +166,8 @@ bool GameObject::onEvent(SDL_Event& event)
// Call children // Call children
for (auto it = m_children.begin(); it != m_children.end() && !handled; it++) for (auto it = m_children.begin(); it != m_children.end() && !handled; it++)
handled = (*it)->onEvent(event); if ((*it)->m_enabled)
handled = (*it)->onEvent(event);
return handled; return handled;
} }
@ -111,7 +180,8 @@ void GameObject::onUpdateLogic()
// Call children // Call children
for (auto child : m_children) for (auto child : m_children)
child->onUpdateLogic(); if (child->m_enabled)
child->onUpdateLogic();
} }
void GameObject::onPreRender() void GameObject::onPreRender()
@ -122,7 +192,8 @@ void GameObject::onPreRender()
// Call children // Call children
for (auto child : m_children) for (auto child : m_children)
child->onPreRender(); if (child->m_enabled && child->visible)
child->onPreRender();
} }
void GameObject::onRender() void GameObject::onRender()
@ -133,7 +204,8 @@ void GameObject::onRender()
// Call children // Call children
for (auto child : m_children) for (auto child : m_children)
child->onRender(); if (child->m_enabled && child->visible)
child->onRender();
} }
void GameObject::onPostRender() void GameObject::onPostRender()
@ -144,12 +216,81 @@ void GameObject::onPostRender()
// Call children // Call children
for (auto child : m_children) for (auto child : m_children)
child->onPostRender(); if (child->m_enabled && child->visible)
child->onPostRender();
}
void GameObject::onEnable()
{
// Call components
for (auto pair : m_components)
pair.second->onEnable();
// Call children
for (auto child : m_children)
if (child->enabled())
child->onEnable();
}
void GameObject::onDisable()
{
// Call components
for (auto pair : m_components)
pair.second->onDisable();
// Call children
for (auto child : m_children)
if (child->enabled())
child->onDisable();
} }
void GameObject::onDestroy() void GameObject::onDestroy()
{ {
// Don't call onDestroy on children/components
// because it will be called in the destructor
}
void GameObject::setEnabled(bool enabled)
{
// Don't set again
if (m_enabled == enabled)
return;
m_enabled = enabled;
// If parent is disabled, we are disabled
if (m_parent == nullptr || m_parent->enabled())
{
// Call onEnable/onDisable
if (enabled) onEnable();
else onDisable();
}
}
void GameObject::dumpTree(unsigned level)
{
// Print spaces
for (unsigned i = 0; i < level; i++)
std::cout<<" ";
// Game object info
std::cout << "* GameObject: " << name << "[";
std::cout << ((m_enabled) ? "e" : " ") << "][";
std::cout << ((visible) ? "v" : " ") << "]\n";
// Components
for (auto component : m_components)
component.second->dump(level);
for (auto child : m_children)
child->dumpTree(level + 1);
} }
} /* namespace base */ } /* namespace base */
} /* namespace farmlands */ } /* namespace farmlands */

View File

@ -8,6 +8,8 @@
#ifndef GAMEOBJECT_H_ #ifndef GAMEOBJECT_H_
#define GAMEOBJECT_H_ #define GAMEOBJECT_H_
#include <base/ICloneable.h>
#include <base/INonAssignable.h>
#include <utils/Assert.h> #include <utils/Assert.h>
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
@ -22,22 +24,28 @@ namespace base {
class Component; class Component;
class RenderContext; class RenderContext;
class GameObject class GameObject : public INonAssignable, public ICloneable<GameObject>
{ {
public: public:
// Constructors // Constructors
GameObject(); GameObject();
virtual ~GameObject(); virtual ~GameObject();
virtual GameObject* clone() override;
static GameObject* instantiate(GameObject* gameObject, std::string name, GameObject* parent);
// Components API // Components API
template <typename T> void addComponent(T* component);
template <typename T> T* component(); template <typename T> T* component();
template <typename T> bool haveComponent();
template <typename T> void addComponent(T* component);
template <typename T> void removeComponent(); template <typename T> void removeComponent();
// Tree methods // Tree methods
void addChild(GameObject* obj); void addChild(GameObject* obj);
GameObject* removeChild(size_t index); GameObject* removeChild(size_t index);
void destroyChild(size_t index); void destroyChild(size_t index);
void destroyChild(GameObject* obj);
GameObject* child(size_t index); GameObject* child(size_t index);
size_t childrenCount() const; size_t childrenCount() const;
GameObject* parent(); GameObject* parent();
@ -52,16 +60,61 @@ namespace base {
void onPostRender(); void onPostRender();
void onDestroy(); void onDestroy();
void onEnable();
void onDisable();
// Getters, setters
inline bool enabled() const { return m_enabled; }
void setEnabled(bool enabled);
// Debugging
void dumpTree(unsigned level = 0);
// Other properties // Other properties
std::string name; std::string name;
bool visible;
private: private:
// Components
std::unordered_map<std::type_index, Component*> m_components; std::unordered_map<std::type_index, Component*> m_components;
// Tree
std::vector<GameObject*> m_children; std::vector<GameObject*> m_children;
GameObject* m_parent; GameObject* m_parent;
// Properties
bool m_enabled;
}; };
template <typename T>
T* GameObject::component()
{
// Compute type index
std::type_index typeIndex(typeid(T));
// Get component
auto it = m_components.find(typeIndex);
if (it == m_components.end())
return nullptr;
T* comp = dynamic_cast<T*> (it->second);
// Done
Assert(comp != nullptr, "This is bad!!! Type of component is really messed up!!!");
return comp;
}
template <typename T>
bool GameObject::haveComponent()
{
// Compute type index
std::type_index typeIndex(typeid(T));
// Get component
auto it = m_components.find(typeIndex);
return it != m_components.end();
}
template <typename T> template <typename T>
void GameObject::addComponent(T* component) void GameObject::addComponent(T* component)
{ {
@ -72,21 +125,6 @@ namespace base {
component->gameObject = this; 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> template <typename T>
void GameObject::removeComponent() void GameObject::removeComponent()
{ {

27
src/base/ICloneable.h Normal file
View File

@ -0,0 +1,27 @@
/*
* ICloneable.h
*
* Created on: Dec 2, 2016
* Author: tibi
*/
#ifndef BASE_ICLONEABLE_H_
#define BASE_ICLONEABLE_H_
namespace farmlands {
namespace base {
template <typename T>
class ICloneable
{
public:
virtual ~ICloneable() { };
virtual T* clone() = 0;
};
}
}
#endif /* BASE_ICLONEABLE_H_ */

28
src/base/INonAssignable.h Normal file
View File

@ -0,0 +1,28 @@
/*
* INonAssignable.h
*
* Created on: Dec 2, 2016
* Author: tibi
*/
#ifndef BASE_INONASSIGNABLE_H_
#define BASE_INONASSIGNABLE_H_
namespace farmlands {
namespace base {
class INonAssignable
{
public:
virtual ~INonAssignable() { };
INonAssignable() { }
INonAssignable(const INonAssignable&) = delete;
INonAssignable& operator=(const INonAssignable&) = delete;
};
}
}
#endif /* BASE_INONASSIGNABLE_H_ */

View File

@ -36,6 +36,12 @@ float RenderContext::yToScreen(float y)
return (y - m_cameraTransform->y) * cellH + viewport.height / 2; return (y - m_cameraTransform->y) * cellH + viewport.height / 2;
} }
bool farmlands::base::RenderContext::visible(SDL_Rect& rect)
{
SDL_Rect screen = { 0, 0, viewport.width, viewport.height };
return SDL_HasIntersection(&screen, &rect);
}
void RenderContext::setCamera(GameObject* camera) void RenderContext::setCamera(GameObject* camera)
{ {
m_cameraObj = camera; m_cameraObj = camera;
@ -45,3 +51,4 @@ void RenderContext::setCamera(GameObject* camera)
} }
} }

View File

@ -9,6 +9,7 @@
#define GRAPHICS_RENDERCONTEXT_H_ #define GRAPHICS_RENDERCONTEXT_H_
#include <base/Viewport.h> #include <base/Viewport.h>
#include <SDL2/SDL.h>
namespace farmlands { namespace farmlands {
namespace base { namespace base {
@ -25,6 +26,8 @@ namespace base {
float xToScreen(float x); float xToScreen(float x);
float yToScreen(float y); float yToScreen(float y);
bool visible(SDL_Rect& rect);
inline GameObject* cameraObj() { return m_cameraObj; } inline GameObject* cameraObj() { return m_cameraObj; }
inline Camera* camera() { return m_camera; } inline Camera* camera() { return m_camera; }
inline Transform* cameraTransform() { return m_cameraTransform; } inline Transform* cameraTransform() { return m_cameraTransform; }

78
src/base/Transform.cpp Normal file
View File

@ -0,0 +1,78 @@
/*
* Transform.cpp
*
* Created on: Dec 2, 2016
* Author: tibi
*/
#include <base/GameObject.h>
#include <base/Transform.h>
#include <iostream>
namespace farmlands {
namespace base {
Transform::Transform()
: x(0), y(0),
w(0), h(0),
m_parent(nullptr)
{
}
Transform::~Transform()
{
}
Component* Transform::clone()
{
Transform* clone = new Transform();
clone->x = x;
clone->y = y;
clone->w = w;
clone->h = h;
return clone;
}
void farmlands::base::Transform::onCreate()
{
if (gameObject->parent() != nullptr)
m_parent = gameObject->parent()->component<Transform>();
}
float Transform::globalX() const
{
return (m_parent) ? m_parent->globalX() + x : x;
}
float Transform::globalY() const
{
return (m_parent) ? m_parent->globalY() + y : y;
}
void Transform::setGlobalX(float x)
{
this->x = (m_parent) ? x - m_parent->globalX() : x;
}
void Transform::setGlobalY(float y)
{
this->y = (m_parent) ? y - m_parent->globalY() : y;
}
void Transform::dump(unsigned level)
{
for (unsigned i = 0; i < level; i++)
std::cout<<" ";
std::cout << " .Component: Transform ";
std::cout << "x="<<x<<" ";
std::cout << "y="<<y<<" ";
std::cout << "w="<<w<<" ";
std::cout << "h="<<h<<"\n";
}
} /* namespace base */
} /* namespace farmlands */

View File

@ -13,9 +13,31 @@
namespace farmlands { namespace farmlands {
namespace base { namespace base {
struct Transform: public Component class Transform: public Component
{ {
public:
Transform();
virtual ~Transform();
virtual base::Component* clone() override;
virtual void dump(unsigned level) override;
virtual void onCreate();
// Getters
float globalX() const;
float globalY() const;
// Setters
void setGlobalX(float x);
void setGlobalY(float y);
// Local coordinates (relative to parent)
float x, y; float x, y;
float w, h;
private:
Transform* m_parent;
}; };
} /* namespace base */ } /* namespace base */

View File

@ -10,6 +10,8 @@
#include <controller/DebugController.h> #include <controller/DebugController.h>
#include <input/Input.h> #include <input/Input.h>
#include <iostream>
using namespace farmlands::input; using namespace farmlands::input;
namespace farmlands { namespace farmlands {
@ -19,6 +21,7 @@ static const float ScaleVelocity = 0.5f;
static const float ScaleShiftVelocity = 2.0f; static const float ScaleShiftVelocity = 2.0f;
DebugController::DebugController() DebugController::DebugController()
: m_camera(nullptr)
{ {
} }
@ -26,6 +29,11 @@ DebugController::~DebugController()
{ {
} }
base::Component* DebugController::clone()
{
return new DebugController();
}
void DebugController::onInitialize() void DebugController::onInitialize()
{ {
m_camera = GameState::current().renderContext.camera(); m_camera = GameState::current().renderContext.camera();
@ -49,5 +57,13 @@ void DebugController::onUpdateLogic()
m_camera->scale *= 1 - vel; m_camera->scale *= 1 - vel;
} }
void DebugController::dump(unsigned level)
{
for (unsigned i = 0; i < level; i++)
std::cout<<" ";
std::cout << " .Component: DebugController\n";
}
} /* namespace controller */ } /* namespace controller */
} /* namespace farmlands */ } /* namespace farmlands */

View File

@ -20,6 +20,9 @@ namespace controller {
DebugController(); DebugController();
virtual ~DebugController(); virtual ~DebugController();
virtual base::Component* clone() override;
virtual void dump(unsigned level) override;
virtual void onInitialize() override; virtual void onInitialize() override;
virtual void onUpdateLogic() override; virtual void onUpdateLogic() override;

View File

@ -51,6 +51,7 @@ bool FarmlandsGame::initialize()
// Finish initialization // Finish initialization
GameState::current().scene->root.onInitialize(); GameState::current().scene->root.onInitialize();
GameState::current().gameInitialized = true;
return true; return true;
} }

View File

@ -9,10 +9,10 @@
#include <controller/GuiController.h> #include <controller/GuiController.h>
#include <gui/widgets/TextArea.h> #include <gui/widgets/TextArea.h>
namespace farmlands #include <iostream>
{
namespace controller namespace farmlands {
{ namespace controller {
GuiController::GuiController() GuiController::GuiController()
: m_canvas() : m_canvas()
@ -23,6 +23,11 @@ GuiController::~GuiController()
{ {
} }
base::Component* GuiController::clone()
{
return new GuiController();
}
void GuiController::onInitialize() void GuiController::onInitialize()
{ {
m_context = &GameState::current().renderContext; m_context = &GameState::current().renderContext;
@ -70,5 +75,13 @@ void GuiController::onRender()
m_canvas.render(m_context); m_canvas.render(m_context);
} }
void GuiController::dump(unsigned level)
{
for (unsigned i = 0; i < level; i++)
std::cout<<" ";
std::cout << " .Component: DebugController\n";
}
} /* namespace controller */ } /* namespace controller */
} /* namespace farmlands */ } /* namespace farmlands */

View File

@ -23,6 +23,9 @@ namespace controller {
GuiController(); GuiController();
virtual ~GuiController(); virtual ~GuiController();
virtual base::Component* clone() override;
virtual void dump(unsigned level) override;
/** /**
* Initializes game renderer * Initializes game renderer
*/ */

View File

@ -0,0 +1,50 @@
/*
* Giftable.cpp
*
* Created on: Dec 2, 2016
* Author: tibi
*/
#include <controller/items/Giftable.h>
#include <iostream>
namespace farmlands {
namespace controller {
namespace items {
Giftable::Giftable()
{
}
Giftable::~Giftable()
{
}
base::Component* Giftable::clone()
{
return new Giftable();
}
bool Giftable::canGift(float x, float y, model::Direction d)
{
// TODO: implement Giftable::canGift
return false;
}
void Giftable::offerGift(float x, float y, model::Direction d)
{
// TODO: implement Giftable::offerGift
}
void Giftable::dump(unsigned level)
{
for (unsigned i = 0; i < level; i++)
std::cout<<" ";
std::cout << " .Component: Giftable\n";
}
} /* namespace items */
} /* namespace controller */
} /* namespace farmlands */

View File

@ -0,0 +1,35 @@
/*
* Giftable.h
*
* Created on: Dec 2, 2016
* Author: tibi
*/
#ifndef CONTROLLER_ITEMS_GIFTABLE_H_
#define CONTROLLER_ITEMS_GIFTABLE_H_
#include <base/Component.h>
#include <model/Direction.h>
namespace farmlands {
namespace controller {
namespace items {
class Giftable: public base::Component
{
public:
Giftable();
virtual ~Giftable();
virtual base::Component* clone() override;
virtual void dump(unsigned level) override;
bool canGift(float x, float y, model::Direction d);
void offerGift(float x, float y, model::Direction d);
};
} /* namespace items */
} /* namespace controller */
} /* namespace farmlands */
#endif /* CONTROLLER_ITEMS_GIFTABLE_H_ */

View File

@ -1,30 +0,0 @@
/*
* ItemController.cpp
*
* Created on: Nov 30, 2016
* Author: tibi
*/
#include <controller/items/ItemController.h>
namespace farmlands
{
namespace controller
{
namespace items
{
ItemController::ItemController()
{
// TODO Auto-generated constructor stub
}
ItemController::~ItemController()
{
// TODO Auto-generated destructor stub
}
} /* namespace items */
} /* namespace controller */
} /* namespace farmlands */

View File

@ -1,30 +0,0 @@
/*
* ItemController.h
*
* Created on: Nov 30, 2016
* Author: tibi
*/
#ifndef CONTROLLER_ITEMS_ITEMCONTROLLER_H_
#define CONTROLLER_ITEMS_ITEMCONTROLLER_H_
#include <base/Component.h>
namespace farmlands {
namespace controller {
namespace items {
class ItemController: public base::Component
{
public:
ItemController();
virtual ~ItemController();
float enemyDamage;
};
} /* namespace items */
} /* namespace controller */
} /* namespace farmlands */
#endif /* CONTROLLER_ITEMS_ITEMCONTROLLER_H_ */

View File

@ -0,0 +1,83 @@
/*
* Weapon.cpp
*
* Created on: Dec 2, 2016
* Author: tibi
*/
#include <GameState.h>
#include <controller/items/Weapon.h>
#include <iostream>
namespace farmlands {
namespace controller {
namespace items {
Weapon::Weapon()
: damage(0),
critProbability(0),
critDamage(0),
attackDuration(1.0f),
m_spriteRenderer(nullptr),
m_attackTimeLeft(0)
{
}
Weapon::~Weapon()
{
}
base::Component* Weapon::clone()
{
Weapon* clone = new Weapon();
clone->damage = damage;
clone->critProbability = critProbability;
clone->critDamage = critDamage;
clone->attackDuration = attackDuration;
return clone;
}
void Weapon::onInitialize()
{
m_spriteRenderer = gameObject->component<graphics::SpriteRenderer>();
}
void Weapon::onPreRender()
{
m_spriteRenderer->sprite->setState(m_attackTimeLeft > 0);
}
void Weapon::onUpdateLogic()
{
if (m_attackTimeLeft > 0)
{
m_attackTimeLeft -= GameState::current().elapsedTime;
}
}
void Weapon::performAttack(float x, float y, model::Direction d)
{
if (m_attackTimeLeft <= 0)
{
m_attackTimeLeft = attackDuration;
}
}
void Weapon::dump(unsigned level)
{
for (unsigned i = 0; i < level; i++)
std::cout<<" ";
std::cout << " .Component: Transform ";
std::cout << "damage="<<damage<<" ";
std::cout << "critProbability="<<critProbability<<" ";
std::cout << "critDamage="<<critDamage<<" ";
std::cout << "attackDuration="<<attackDuration<<"\n";
}
}
} /* namespace model */
} /* namespace farmlands */

View File

@ -0,0 +1,53 @@
/*
* Weapon.h
*
* Created on: Dec 2, 2016
* Author: tibi
*/
#ifndef CONTROLLER_ITEMS_WEAPON_H_
#define CONTROLLER_ITEMS_WEAPON_H_
#include <base/Component.h>
#include <graphics/SpriteRenderer.h>
#include <model/Direction.h>
namespace farmlands {
namespace controller {
namespace items {
class Weapon: public base::Component
{
public:
Weapon();
virtual ~Weapon();
virtual base::Component* clone() override;
virtual void dump(unsigned level) override;
virtual void onInitialize() override;
virtual void onUpdateLogic() override;
virtual void onPreRender() override;
/**
* Performs everything required to attacking an enemy with a weapon. To be called from player controller.
*/
void performAttack(float x, float y, model::Direction d);
// Properties
float damage;
float critProbability;
float critDamage;
float attackDuration; // In seconds
private:
graphics::SpriteRenderer* m_spriteRenderer;
float m_attackTimeLeft;
};
}
} /* namespace model */
} /* namespace farmlands */
#endif /* CONTROLLER_ITEMS_WEAPON_H_ */

View File

@ -6,13 +6,20 @@
*/ */
#include <GameState.h> #include <GameState.h>
#include <controller/items/Giftable.h>
#include <controller/items/Weapon.h>
#include <controller/player/PlayerController.h> #include <controller/player/PlayerController.h>
#include <graphics/SpriteRenderer.h> #include <graphics/SpriteRenderer.h>
#include <input/Input.h> #include <input/Input.h>
#include <model/Item.h>
#include <utils/Assert.h> #include <utils/Assert.h>
using namespace farmlands::input; #include <iostream>
using namespace farmlands::base;
using namespace farmlands::controller::items;
using namespace farmlands::graphics; using namespace farmlands::graphics;
using namespace farmlands::input;
using namespace farmlands::model; using namespace farmlands::model;
namespace farmlands { namespace farmlands {
@ -35,10 +42,10 @@ static const Direction VelocitySignDirections[3][3] =
PlayerController::PlayerController() PlayerController::PlayerController()
: m_transform(nullptr), : m_transform(nullptr),
m_attackTimeLeft(0),
m_facingDirection(Direction::South), m_facingDirection(Direction::South),
m_walking(false), m_walking(false),
m_running(false) m_running(false),
m_currentItem(nullptr)
{ {
} }
@ -46,6 +53,11 @@ PlayerController::~PlayerController()
{ {
} }
base::Component* PlayerController::clone()
{
return new PlayerController();
}
void PlayerController::onInitialize() void PlayerController::onInitialize()
{ {
m_transform = gameObject->component<base::Transform>(); m_transform = gameObject->component<base::Transform>();
@ -53,18 +65,68 @@ void PlayerController::onInitialize()
bool PlayerController::onEvent(SDL_Event& event) bool PlayerController::onEvent(SDL_Event& event)
{ {
bool attack1 = (Input::instance().down(GameKey::Action, event)); handleAttackEvents(event);
bool attack2 = (Input::instance().down(GameKey::Action2, event)); handleInventoryEvents(event);
if (m_attackTimeLeft == 0 && (attack1 || attack2))
{
attack();
m_attackTimeLeft = 20 + attack2 * 20;
}
return false; return false;
} }
void PlayerController::handleAttackEvents(SDL_Event& event)
{
bool attack = (Input::instance().down(GameKey::Action, event));
if (attack && m_currentItem != nullptr)
{
// Weapon behavior
Weapon* weapon = m_currentItem->component<Weapon>();
if (weapon)
weapon->performAttack(m_transform->x, m_transform->y, m_facingDirection);
// Gift behavior
Giftable* giftable = m_currentItem->component<Giftable>();
if (giftable)
giftable->offerGift(m_transform->x, m_transform->y, m_facingDirection);
}
}
void PlayerController::handleInventoryEvents(SDL_Event& event)
{
// See what key was pressed
int slot = -1;
if (Input::instance().down(GameKey::Inventory1, event)) slot = 1;
if (Input::instance().down(GameKey::Inventory2, event)) slot = 2;
if (Input::instance().down(GameKey::Inventory3, event)) slot = 3;
if (Input::instance().down(GameKey::Inventory4, event)) slot = 4;
if (Input::instance().down(GameKey::Inventory5, event)) slot = 5;
if (Input::instance().down(GameKey::Inventory6, event)) slot = 6;
if (Input::instance().down(GameKey::Inventory7, event)) slot = 7;
if (Input::instance().down(GameKey::Inventory8, event)) slot = 8;
if (Input::instance().down(GameKey::Inventory9, event)) slot = 9;
if (Input::instance().down(GameKey::Inventory10, event)) slot = 10;
// For now we don't have an inventory, so just instantiate some object
if (0 <= slot && slot <= GameState::current().itemPrefabs.size())
{
GameObject* itemPrefab = GameState::current().itemPrefabs[slot - 1];
// Get rid of old object
if (m_currentItem != nullptr)
gameObject->destroyChild(m_currentItem);
// Instantiate new object
m_currentItem = GameObject::instantiate(itemPrefab, "Current item", gameObject);
// Print some information
// Item* item = itemPrefab->component<Item>();
// std::string name = (item == nullptr) ? "unknown" : item->name;
// std::cout << "Instantiated object " << slot << " (" << name << ")\n";
}
else if (0 <= slot)
{
std::cout << "Slot " << slot << "empty\n";
}
}
void PlayerController::onUpdateLogic() void PlayerController::onUpdateLogic()
{ {
m_running = false; m_running = false;
@ -73,13 +135,13 @@ void PlayerController::onUpdateLogic()
// Compute movement velocity // Compute movement velocity
float velMultiplier = PlayerWalkVelocity; float velMultiplier = PlayerWalkVelocity;
if (m_attackTimeLeft) // if (m_attackTimeLeft)
{ // {
velMultiplier = PlayerAttackVelocity; // velMultiplier = PlayerAttackVelocity;
--m_attackTimeLeft; // --m_attackTimeLeft;
} // } else
else if (Input::instance().pressed(GameKey::Run)) if (Input::instance().pressed(GameKey::Run))
{ {
velMultiplier = PlayerRunVelocity; velMultiplier = PlayerRunVelocity;
m_running = true; m_running = true;
@ -127,11 +189,19 @@ void PlayerController::onPreRender()
// Set animation velocity // Set animation velocity
float animVelocity = (m_running) ? 1.0f : 0.7f; float animVelocity = (m_running) ? 1.0f : 0.7f;
if (m_attackTimeLeft) // if (m_attackTimeLeft)
animVelocity = 0.1f; // animVelocity = 0.1f;
spriteRenderer->sprite->setAnimationVelocity(animVelocity); spriteRenderer->sprite->setAnimationVelocity(animVelocity);
// Set weapon
if (m_currentItem)
{
Transform* itemTransf = m_currentItem->component<Transform>();
itemTransf->x = 0.2f;
itemTransf->y = -0.8f;
}
// Set camera // Set camera
base::Transform* cam = GameState::current().renderContext.cameraTransform(); base::Transform* cam = GameState::current().renderContext.cameraTransform();
cam->x = m_transform->x; cam->x = m_transform->x;
@ -157,6 +227,14 @@ void PlayerController::attack()
// For now - nothing // For now - nothing
} }
void PlayerController::dump(unsigned level)
{
for (unsigned i = 0; i < level; i++)
std::cout<<" ";
std::cout << " .Component: PlayerController\n";
}
} }
} /* namespace controller */ } /* namespace controller */
} /* namespace farmlands */ } /* namespace farmlands */

View File

@ -24,6 +24,9 @@ namespace player {
PlayerController(); PlayerController();
virtual ~PlayerController(); virtual ~PlayerController();
virtual base::Component* clone() override;
virtual void dump(unsigned level) override;
virtual void onInitialize() override; virtual void onInitialize() override;
virtual bool onEvent(SDL_Event& event) override; virtual bool onEvent(SDL_Event& event) override;
virtual void onUpdateLogic() override; virtual void onUpdateLogic() override;
@ -32,14 +35,17 @@ namespace player {
private: private:
static model::Direction getDirection(float vx, float vy); static model::Direction getDirection(float vx, float vy);
void handleAttackEvents(SDL_Event& event);
void handleInventoryEvents(SDL_Event& event);
bool canMove(float x, float y); bool canMove(float x, float y);
void attack(); void attack();
base::Transform* m_transform; base::Transform* m_transform;
uint32_t m_attackTimeLeft;
model::Direction m_facingDirection; model::Direction m_facingDirection;
bool m_walking, m_running; bool m_walking, m_running;
base::GameObject* m_currentItem;
}; };
} }

View File

@ -13,6 +13,7 @@
#include <math/GameMath.h> #include <math/GameMath.h>
#include <utils/Assert.h> #include <utils/Assert.h>
#include <iostream>
#include <cmath> #include <cmath>
using namespace farmlands::graphics::backend; using namespace farmlands::graphics::backend;
@ -31,6 +32,11 @@ BackgroundRenderer::~BackgroundRenderer()
{ {
} }
base::Component* BackgroundRenderer::clone()
{
return new BackgroundRenderer();
}
void BackgroundRenderer::onInitialize() void BackgroundRenderer::onInitialize()
{ {
Assert(gameObject != nullptr, "Component not properly initialized!"); Assert(gameObject != nullptr, "Component not properly initialized!");
@ -105,5 +111,13 @@ void BackgroundRenderer::getCell(SDL_Texture* texture, uint32_t cell, int* outX,
*outY = ((cell * ppuX) / texWidth) * ppuY; *outY = ((cell * ppuX) / texWidth) * ppuY;
} }
void BackgroundRenderer::dump(unsigned level)
{
for (unsigned i = 0; i < level; i++)
std::cout<<" ";
std::cout << " .Component: BackgroundRenderer\n";
}
} /* namespace graphics */ } /* namespace graphics */
} /* namespace farmlands */ } /* namespace farmlands */

View File

@ -23,6 +23,9 @@ public:
BackgroundRenderer(); BackgroundRenderer();
virtual ~BackgroundRenderer(); virtual ~BackgroundRenderer();
virtual base::Component* clone() override;
virtual void dump(unsigned level) override;
virtual void onInitialize() override; virtual void onInitialize() override;
virtual void onRender() override; virtual void onRender() override;

View File

@ -12,6 +12,8 @@
#include <graphics/SpriteRenderer.h> #include <graphics/SpriteRenderer.h>
#include <utils/Assert.h> #include <utils/Assert.h>
#include <iostream>
using namespace farmlands::graphics::backend; using namespace farmlands::graphics::backend;
using namespace farmlands::resources; using namespace farmlands::resources;
@ -27,6 +29,15 @@ SpriteRenderer::SpriteRenderer()
SpriteRenderer::~SpriteRenderer() SpriteRenderer::~SpriteRenderer()
{ {
delete sprite;
}
base::Component* SpriteRenderer::clone()
{
SpriteRenderer* clone = new SpriteRenderer();
clone->sprite = new base::Sprite(*sprite);
return clone;
} }
void SpriteRenderer::onInitialize() void SpriteRenderer::onInitialize()
@ -39,30 +50,36 @@ void SpriteRenderer::onInitialize()
void SpriteRenderer::onRender() void SpriteRenderer::onRender()
{ {
float posX = m_context->xToScreen(m_transform->x); float posX = m_context->xToScreen(m_transform->globalX());
float posY = m_context->yToScreen(m_transform->y); float posY = m_context->yToScreen(m_transform->globalY());
// Obtain texture float w = sprite->currentFrame().width * m_context->viewport.pixelsPerUnitX;
int texId = sprite->currentFrame().tileSetId; float h = sprite->currentFrame().height * m_context->viewport.pixelsPerUnitY;
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 // Compute destination rectangle
float scale = m_context->camera()->scale; float scale = m_context->camera()->scale;
SDL_Rect dest; SDL_Rect dest;
dest.x = posX - sprite->anchorX * src.w * scale; dest.x = posX - sprite->anchorX * w * scale;
dest.y = posY - sprite->anchorY * src.h * scale; dest.y = posY - sprite->anchorY * h * scale;
dest.w = src.w * scale; dest.w = w * scale;
dest.h = src.h * scale; dest.h = h * scale;
// Draw if (m_context->visible(dest))
SdlRenderer::instance().renderTexture(texture, &src, &dest); {
// Obtain texture
int texId = sprite->currentFrame().tileSetId;
SDL_Texture* texture = resources::ResourceManager::instance().texture(texId);
// Compute source rectangle
SDL_Rect src;
getCell(texture, sprite->currentFrame().tileSetCell, &src.x, &src.y);
src.w = w;
src.h = h;
// Draw
SdlRenderer::instance().renderTexture(texture, &src, &dest);
}
} }
void SpriteRenderer::onPostRender() void SpriteRenderer::onPostRender()
@ -86,5 +103,14 @@ void SpriteRenderer::getCell(SDL_Texture* texture, uint32_t cell, int* outX, int
*outY = ((cell * ppuX) / texWidth) * ppuY; *outY = ((cell * ppuX) / texWidth) * ppuY;
} }
void SpriteRenderer::dump(unsigned level)
{
for (unsigned i = 0; i < level; i++)
std::cout<<" ";
std::cout << " .Component: SpriteRenderer sprite=";
std::cout << sprite->name <<"\n";
}
} /* namespace graphics */ } /* namespace graphics */
} /* namespace farmlands */ } /* namespace farmlands */

View File

@ -24,6 +24,9 @@ namespace graphics {
SpriteRenderer(); SpriteRenderer();
virtual ~SpriteRenderer(); virtual ~SpriteRenderer();
virtual base::Component* clone() override;
virtual void dump(unsigned level) override;
virtual void onInitialize() override; virtual void onInitialize() override;
virtual void onRender() override; virtual void onRender() override;
virtual void onPostRender() override; virtual void onPostRender() override;

View File

@ -58,7 +58,7 @@ float Input::getX()
else if (pressed(GameKey::Left) || pressed(GameKey::AltLeft)) else if (pressed(GameKey::Left) || pressed(GameKey::AltLeft))
return -1.0f; return -1.0f;
// TODO: controller // TODO: controller input
return 0.0f; return 0.0f;
} }
@ -71,7 +71,7 @@ float Input::getY()
else if (pressed(GameKey::Up) || pressed(GameKey::AltUp)) else if (pressed(GameKey::Up) || pressed(GameKey::AltUp))
return -1.0f; return -1.0f;
// TODO: controller // TODO: controller input
return 0.0f; return 0.0f;
} }

View File

@ -8,6 +8,8 @@
#include <model/Background.h> #include <model/Background.h>
#include <utils/Assert.h> #include <utils/Assert.h>
#include <iostream>
namespace farmlands { namespace farmlands {
namespace model { namespace model {
@ -27,6 +29,15 @@ Background::~Background()
delete[] m_textures; delete[] m_textures;
} }
base::Component* Background::clone()
{
Background* clone = new Background(m_layers, m_rows, m_columns);
memcpy(clone->m_cells, m_cells, sizeof(Cell) * m_layers * m_rows * m_columns);
memcpy(clone->m_textures, m_textures, sizeof(resources::ResourceId) * m_layers);
return clone;
}
Cell Background::cell(size_t layer, size_t row, size_t col) const Cell Background::cell(size_t layer, size_t row, size_t col) const
{ {
Assert(layer < m_layers, "Layer out of bounds."); Assert(layer < m_layers, "Layer out of bounds.");
@ -57,5 +68,13 @@ void Background::setTexture(size_t layer, resources::ResourceId textureId) const
m_textures[layer] = textureId; m_textures[layer] = textureId;
} }
void Background::dump(unsigned level)
{
for (unsigned i = 0; i < level; i++)
std::cout<<" ";
std::cout << " .Component: Background\n";
}
} /* namespace model */ } /* namespace model */
} /* namespace farmlands */ } /* namespace farmlands */

View File

@ -22,6 +22,9 @@ namespace model {
Background(size_t layerCount, size_t rowCount, size_t columnCount); Background(size_t layerCount, size_t rowCount, size_t columnCount);
virtual ~Background(); virtual ~Background();
virtual base::Component* clone() override;
virtual void dump(unsigned level) override;
inline size_t layerCount() const { return m_layers; } inline size_t layerCount() const { return m_layers; }
inline size_t rowCount() const { return m_rows; } inline size_t rowCount() const { return m_rows; }
inline size_t columnCount() const { return m_columns; } inline size_t columnCount() const { return m_columns; }

65
src/model/Item.h Normal file
View File

@ -0,0 +1,65 @@
/*
* Item.h
*
* Created on: Dec 2, 2016
* Author: tibi
*/
#ifndef MODEL_ITEM_H_
#define MODEL_ITEM_H_
#include <base/Component.h>
#include <iostream>
namespace farmlands {
namespace model {
class Item: public base::Component
{
public:
Item();
virtual ~Item();
virtual base::Component* clone() override;
virtual void dump(unsigned level) override;
std::string name;
std::string description;
uint8_t level;
};
/****** Implementation ******/
inline Item::Item()
: name(), description(),
level(0)
{
}
inline Item::~Item()
{
}
inline base::Component* Item::clone()
{
Item* clone = new Item();
clone->name = name;
clone->description = description;
clone->level = level;
return clone;
}
inline void Item::dump(unsigned level)
{
for (unsigned i = 0; i < level; i++)
std::cout<<" ";
std::cout << " .Component: Item\n";
}
} /* namespace model */
} /* namespace farmlands */
#endif /* MODEL_ITEM_H_ */

View File

@ -10,13 +10,15 @@
#include <base/GameObject.h> #include <base/GameObject.h>
#include <vector>
namespace farmlands { namespace farmlands {
namespace base { namespace model {
struct Scene struct Scene
{ {
GameObject root; uint32_t cellWidth = 1, cellHeight = 1;
uint32_t cellWidth, cellHeight; base::GameObject root;
}; };
} /* namespace model */ } /* namespace model */

View File

@ -22,6 +22,7 @@ namespace resources {
Background, Background,
BackgroundLayer, BackgroundLayer,
Item, Item,
ItemCollection,
}; };
struct ResourceInfo struct ResourceInfo

View File

@ -80,8 +80,11 @@ void ResourceManager::loadMainMenu()
void ResourceManager::loadGame() void ResourceManager::loadGame()
{ {
GameState::current().config = storage::parse<model::Configuration>(R::Config::Default); GameState::current().config = storage::parse<model::Configuration>(R::Config::Default);
GameState::current().scene = storage::parse<base::Scene>(R::Scenes::Game); GameState::current().scene = storage::parse<model::Scene>(R::Scenes::Game);
GameState::current().scene->root.onCreate(); GameState::current().scene->root.onCreate();
// storage::parseCollection(R::Items::Tools, GameState::current().itemPrefabs);
storage::parseCollection(R::Items::Weapons, GameState::current().itemPrefabs);
} }
std::string ResourceManager::getPath(ResourceId resourceId) std::string ResourceManager::getPath(ResourceId resourceId)

View File

@ -15,59 +15,63 @@ namespace resources {
enum Sprites enum Sprites
{ {
Player = 0, Player = 0,
items_Lvl1_sword = 1, items_Lvl2Sword = 1,
items_Stone_pickaxe = 2, items_Stone_pickaxe = 2,
items_Lvl1Sword = 3,
items_Sword = 4,
}; };
enum Scenes enum Scenes
{ {
Game = 3, Game = 5,
}; };
enum Fonts enum Fonts
{ {
DejaVuSans = 4, DejaVuSans = 6,
}; };
enum Tilesets enum Tilesets
{ {
PlayerTiles = 5, PlayerTiles = 7,
Ground = 6, Ground = 8,
}; };
enum Ui enum Ui
{ {
Mini_inventory = 7, Mini_inventory = 9,
Cursor = 8, Cursor = 10,
}; };
enum Levels enum Levels
{ {
Farm_Background = 9, Farm_Background = 11,
Farm = 10, Farm = 12,
}; };
enum Config enum Config
{ {
Default = 11, Default = 13,
}; };
enum Items enum Items
{ {
Stone_pickaxe = 12, Tools = 14,
Lvl1_sword = 13, Weapons = 15,
}; };
} }
const int RInfo_Sprites_Begin = 0; const int RInfo_Sprites_Begin = 0;
const int RInfo_Scenes_Begin = 3; const int RInfo_Scenes_Begin = 5;
const int RInfo_Fonts_Begin = 4; const int RInfo_Fonts_Begin = 6;
const int RInfo_Tilesets_Begin = 5; const int RInfo_Tilesets_Begin = 7;
const int RInfo_Ui_Begin = 7; const int RInfo_Ui_Begin = 9;
const int RInfo_Levels_Begin = 9; const int RInfo_Levels_Begin = 11;
const int RInfo_Config_Begin = 11; const int RInfo_Config_Begin = 13;
const int RInfo_Items_Begin = 12; const int RInfo_Items_Begin = 14;
/** /**
* This array contains the names of all the files, and the corresponding file type. * This array contains the names of all the files, and the corresponding file type.
*/ */
const ResourceInfo RInfo[] = { const ResourceInfo RInfo[] = {
{ "sprites/Player.sprite", ResourceType::Sprite }, { "sprites/Player.sprite", ResourceType::Sprite },
{ "sprites/items/lvl1_sword.sprite", ResourceType::Sprite }, { "sprites/items/Lvl2Sword.sprite", ResourceType::Sprite },
{ "sprites/items/stone_pickaxe.sprite", ResourceType::Sprite }, { "sprites/items/stone_pickaxe.sprite", ResourceType::Sprite },
{ "sprites/items/Lvl1Sword.sprite", ResourceType::Sprite },
{ "sprites/items/sword.png", ResourceType::Texture },
{ "scenes/Game.scene", ResourceType::Scene }, { "scenes/Game.scene", ResourceType::Scene },
{ "fonts/DejaVuSans.ttf", ResourceType::Font }, { "fonts/DejaVuSans.ttf", ResourceType::Font },
{ "tilesets/PlayerTiles.png", ResourceType::Texture }, { "tilesets/PlayerTiles.png", ResourceType::Texture },
@ -77,8 +81,8 @@ namespace resources {
{ "levels/Farm_Background.csv", ResourceType::BackgroundLayer }, { "levels/Farm_Background.csv", ResourceType::BackgroundLayer },
{ "levels/Farm.back", ResourceType::Background }, { "levels/Farm.back", ResourceType::Background },
{ "config/Default.config", ResourceType::Configuration }, { "config/Default.config", ResourceType::Configuration },
{ "items/stone_pickaxe.item", ResourceType::Item }, { "items/Tools.items", ResourceType::ItemCollection },
{ "items/lvl1_sword.item", ResourceType::Item }, { "items/Weapons.items", ResourceType::ItemCollection },
}; };
} }

View File

@ -11,9 +11,12 @@
#include <resources/ResourceManager.h> #include <resources/ResourceManager.h>
#include <utils/Assert.h> #include <utils/Assert.h>
#include <boost/algorithm/string.hpp>
#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp> #include <boost/property_tree/xml_parser.hpp>
#include <vector>
namespace farmlands { namespace farmlands {
namespace storage { namespace storage {
@ -39,6 +42,24 @@ namespace storage {
template <typename T> template <typename T>
T* parse(boost::property_tree::ptree& root); T* parse(boost::property_tree::ptree& root);
/**
* Parses a resource collection by reading from resource file
*/
template <typename T>
void parseCollection(resources::ResourceId resourceId, std::vector<T*>& dest);
/**
* Parses a resource collection by reading from resource file
*/
template <typename T>
void parseCollection(std::string filePath, std::vector<T*>& dest);
/**
* Parses a resource collection from property tree
*/
template <typename T>
void parseCollection(boost::property_tree::ptree& root, std::vector<T*>& dest);
/****** Implementations ******/ /****** Implementations ******/
@ -79,6 +100,59 @@ namespace storage {
THROW(utils::NotImplementedException, "No parser implemented for type " + typeName); THROW(utils::NotImplementedException, "No parser implemented for type " + typeName);
} }
template <typename T>
void parseCollection(resources::ResourceId resourceId, std::vector<T*>& dest)
{
// Get resource file
std::string path = resources::ResourceManager::instance().getPath(resourceId);
// Parse the tree
return parseCollection<T>(path, dest);
}
/**
* Parses a resource collection by reading from resource file
*/
template <typename T>
void parseCollection(std::string path, std::vector<T*>& dest)
{
// Open file
std::ifstream resourceIn(path);
if (!resourceIn)
THROW(utils::ResourceLoadException, "Failed to load resource " + path);
// Read property tree
boost::property_tree::ptree tree;
boost::property_tree::read_xml(resourceIn, tree);
resourceIn.close();
// Parse the tree (give root element)
return parseCollection<T>(tree, dest);
}
/**
* Parses a resource collection from property tree
*/
template <typename T>
void parseCollection(boost::property_tree::ptree& root, std::vector<T*>& dest)
{
// Go in the right child
if (root.size() > 0 && boost::ends_with(root.front().first, "Collection"))
root = root.front().second;
// Parse children
for (auto child : root)
{
// Ignore xml specific stuff
if (child.first.size() == 0) continue;
if (child.first[0] == '<') continue;
// Parse child
T* parsedChild = parse<T>(child.second);
dest.push_back(parsedChild);
}
}
} }
} }

385
src/storage/Parsers.cpp Normal file
View File

@ -0,0 +1,385 @@
/*
* Parsers.cpp
*
* Created on: Dec 2, 2016
* Author: tibi
*/
#include <storage/Parsers.h>
#include <resources/Resources.h>
using namespace farmlands::resources;
namespace farmlands {
namespace storage {
/****** Base namespace ******/
template <>
base::Camera* parse<base::Camera> (boost::property_tree::ptree& root)
{
if (root.front().first == "Camera")
root = root.front().second;
base::Camera* camera = new base::Camera();
camera->scale = root.get<float>("<xmlattr>.scale", 1.0f);
camera->mainCamera = root.get<bool>("<xmlattr>.mainCamera", false);
return camera;
}
template <>
base::Frame* parse<base::Frame> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
if (root.front().first == "Frame")
root = root.front().second;
base::Frame* frame = new base::Frame();
// Obtine tile set id
std::string tileSetPath = root.get<std::string>("<xmlattr>.tileSet");
frame->tileSetId = resources::ResourceManager::instance().getId(tileSetPath);
// Set properties
frame->tileSetCell = root.get<int>("<xmlattr>.cell");
frame->width = root.get<uint32_t>("<xmlattr>.w", 1u);
frame->height = root.get<uint32_t>("<xmlattr>.h", 1u);
frame->duration = root.get<uint32_t>("<xmlattr>.duration");
return frame;
}
template <>
base::GameObject* parse<base::GameObject> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
if (root.front().first == "GameObject")
root = root.front().second;
base::GameObject* gameObj = new base::GameObject();
gameObj->name = root.get<std::string>("<xmlattr>.name");
for (auto child : root)
{
// Base objects
if (child.first == "Transform")
gameObj->addComponent(parse<base::Transform>(child.second));
else if (child.first == "Camera")
gameObj->addComponent(parse<base::Camera>(child.second));
// Model
else if (child.first == "Background")
{
std::string path = child.second.get<std::string>("<xmlattr>.src");
resources::ResourceId id = resources::ResourceManager::instance().getId(path);
gameObj->addComponent(parse<model::Background>(id));
}
else if (child.first == "Item")
gameObj->addComponent(parse<model::Item>(child.second));
// Graphics
else if (child.first == "BackgroundRenderer")
gameObj->addComponent(parse<graphics::BackgroundRenderer>(child.second));
else if (child.first == "SpriteRenderer")
gameObj->addComponent(parse<graphics::SpriteRenderer>(child.second));
// Controllers
else if (child.first == "DebugController")
gameObj->addComponent(parse<controller::DebugController>(child.second));
else if (child.first == "Giftable")
gameObj->addComponent(parse<controller::items::Giftable>(child.second));
else if (child.first == "Weapon")
gameObj->addComponent(parse<controller::items::Weapon>(child.second));
else if (child.first == "PlayerController")
gameObj->addComponent(parse<controller::player::PlayerController>(child.second));
// !!! Add additional types here !!!
}
return gameObj;
}
template <>
base::Sprite* parse<base::Sprite> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
if (root.front().first == "Sprite")
root = root.front().second;
base::Sprite* sprite = new base::Sprite();
sprite->anchorX = root.get<float>("<xmlattr>.anchorX");
sprite->anchorY = root.get<float>("<xmlattr>.anchorY");
for (auto child : root)
{
if (child.first == "State")
{
base::SpriteState* state = parse<base::SpriteState>(child.second);
sprite->addState(*state);
delete state;
}
}
return sprite;
}
template <>
base::SpriteState* parse<base::SpriteState> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
if (root.front().first == "SpriteState")
root = root.front().second;
base::SpriteState* spriteState = new base::SpriteState();
spriteState->name = root.get<std::string>("<xmlattr>.name");
for (auto child : root)
{
if (child.first == "Frame")
{
base::Frame* frame = parse<base::Frame>(child.second);
spriteState->frames.push_back(*frame);
delete frame;
}
}
return spriteState;
}
template <>
base::Transform* parse<base::Transform> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
if (root.front().first == "Transform")
root = root.front().second;
base::Transform* transform = new base::Transform();
transform->x = root.get<float>("<xmlattr>.x", 0.0f);
transform->y = root.get<float>("<xmlattr>.y", 0.0f);
transform->w = root.get<float>("<xmlattr>.w", 0.0f);
transform->h = root.get<float>("<xmlattr>.h", 0.0f);
return transform;
}
/****** Model namespace ******/
void parseBackgroundCells(resources::ResourceId cellsResource, model::Background* back, size_t layer)
{
Assert(RInfo[cellsResource].type == ResourceType::BackgroundLayer, "Resource must be a level layer.");
char buffer[1024 * 10];
// Open file
std::string pathIn = ResourceManager::instance().getPath(cellsResource);
std::ifstream in(pathIn);
if (!in)
THROW(utils::ResourceLoadException, "Could not load level layer " + pathIn);
// Read CSV file line by line
for (size_t row = 0; row < back->rowCount(); row++)
{
in.getline(buffer, sizeof(buffer));
if (in.eof())
THROW(utils::ResourceLoadException, "Unexpected end of file " + pathIn);
// Separated by comma (or maybe semicolon)
char* nextNum = strtok(buffer, ",;");
for (size_t col = 0; col < back->columnCount() && nextNum != NULL; col++)
{
model::Cell cell = (model::Cell)strtol(nextNum, NULL, 10);
back->setCell(layer, row, col, cell);
nextNum = strtok(NULL, ",;");
}
}
in.close();
}
template <>
model::Background* parse<model::Background> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
if (root.front().first == "Background")
root = root.front().second;
// Read sizes
uint32_t layers = root.count("Layer");
uint32_t rows = root.get<uint32_t>("<xmlattr>.rows");
uint32_t cols = root.get<uint32_t>("<xmlattr>.columns");
// Create background object
model::Background* back = new model::Background(layers, rows, cols);
// Read layers
size_t layerNum = 0;
for (auto layer : root)
{
if (layer.first == "Layer")
{
// Read cells
std::string cellsPath = layer.second.get<std::string>("<xmlattr>.cells");
resources::ResourceId cellsId = resources::ResourceManager::instance().getId(cellsPath);
parseBackgroundCells(cellsId, back, layerNum);
// Read texture name
std::string texPath = layer.second.get<std::string>("<xmlattr>.texture");
resources::ResourceId tex = resources::ResourceManager::instance().getId(texPath);
back->setTexture(layerNum, tex);
++layerNum;
}
}
return back;
}
template <>
model::Configuration* parse<model::Configuration> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
if (root.front().first == "Configuration")
root = root.front().second;
model::Configuration* config = new model::Configuration();
config->animationFps = root.get<float>("animationFps");
return config;
}
template <>
model::Item* parse<model::Item> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
if (root.front().first == "Item")
root = root.front().second;
// Parse
model::Item* item = new model::Item();
item->name = root.get<std::string>("<xmlattr>.name");
item->description = root.get<std::string>("<xmlattr>.description");
item->level = root.get<uint8_t>("<xmlattr>.level");
return item;
}
template <>
model::Scene* parse<model::Scene> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
if (root.front().first == "Scene")
root = root.front().second;
model::Scene* scene = new model::Scene();
scene->cellWidth = root.get<uint32_t>("<xmlattr>.cellWidth");
scene->cellHeight = root.get<uint32_t>("<xmlattr>.cellHeight");
for (auto child : root)
{
if (child.first == "GameObject")
{
base::GameObject* obj = parse<base::GameObject>(child.second);
scene->root.addChild(obj);
}
}
return scene;
}
/****** Controller namespace ******/
template <>
controller::DebugController* parse<controller::DebugController> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
if (root.front().first == "DebugController")
root = root.front().second;
controller::DebugController* controller = new controller::DebugController();
return controller;
}
template <>
controller::items::Giftable* parse<controller::items::Giftable> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
if (root.front().first == "Giftable")
root = root.front().second;
// Parse
return new controller::items::Giftable();
}
template <>
controller::items::Weapon* parse<controller::items::Weapon> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
if (root.front().first == "Weapon")
root = root.front().second;
// Parse
controller::items::Weapon* weapon = new controller::items::Weapon();
weapon->damage = root.get<float>("<xmlattr>.damage");
weapon->critProbability = root.get<float>("<xmlattr>.critProbability");
weapon->critDamage = root.get<float>("<xmlattr>.critDamage");
weapon->attackDuration = root.get<float>("<xmlattr>.attackDuration");
return weapon;
}
template <>
controller::player::PlayerController* parse<controller::player::PlayerController> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
if (root.front().first == "PlayerController")
root = root.front().second;
controller::player::PlayerController* controller = new controller::player::PlayerController();
return controller;
}
/****** Graphics namespace ******/
template <>
graphics::BackgroundRenderer* parse<graphics::BackgroundRenderer> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
if (root.front().first == "BackgroundRenderer")
root = root.front().second;
graphics::BackgroundRenderer* renderer = new graphics::BackgroundRenderer();
return renderer;
}
template <>
graphics::SpriteRenderer* parse<graphics::SpriteRenderer> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
if (root.front().first == "SpriteRenderer")
root = root.front().second;
graphics::SpriteRenderer* renderer = new graphics::SpriteRenderer();
// Load sprite
std::string spritePath = root.get<std::string>("<xmlattr>.sprite");
resources::ResourceId spriteId = resources::ResourceManager::instance().getId(spritePath);
renderer->sprite = parse<base::Sprite>(spriteId);
return renderer;
}
}
}

View File

@ -8,15 +8,89 @@
#ifndef STORAGE_PARSERS_PARSERS_H_ #ifndef STORAGE_PARSERS_PARSERS_H_
#define STORAGE_PARSERS_PARSERS_H_ #define STORAGE_PARSERS_PARSERS_H_
#include <base/Camera.h>
#include <base/GameObject.h>
#include <base/Sprite.h>
#include <base/Transform.h>
#include <controller/DebugController.h>
#include <controller/items/Giftable.h>
#include <controller/items/Weapon.h>
#include <controller/player/PlayerController.h>
#include <graphics/BackgroundRenderer.h>
#include <graphics/SpriteRenderer.h>
#include <model/Configuration.h>
#include <model/Item.h>
#include <model/Scene.h>
#include <storage/Parse.h> #include <storage/Parse.h>
#include <storage/parsers/ParseComponents_base.h>
#include <storage/parsers/ParseComponents_controller.h>
#include <storage/parsers/ParseComponents_graphics.h>
#include <storage/parsers/ParseComponents_model.h>
#include <storage/parsers/ParseConfiguration.h>
#include <storage/parsers/ParseSprite.h>
#include <storage/parsers/ParseGameObject.h>
#include <storage/parsers/ParseScene.h>
namespace farmlands {
namespace storage {
/****** Base namespace ******/
template <>
base::Camera* parse<base::Camera> (boost::property_tree::ptree& root);
template <>
base::Frame* parse<base::Frame> (boost::property_tree::ptree& root);
template <>
base::GameObject* parse<base::GameObject> (boost::property_tree::ptree& root);
template <>
base::Sprite* parse<base::Sprite> (boost::property_tree::ptree& root);
template <>
base::SpriteState* parse<base::SpriteState> (boost::property_tree::ptree& root);
template <>
base::Transform* parse<base::Transform> (boost::property_tree::ptree& root);
/****** Model namespace ******/
template <>
model::Background* parse<model::Background> (boost::property_tree::ptree& root);
template <>
model::Configuration* parse<model::Configuration> (boost::property_tree::ptree& root);
template <>
model::Item* parse<model::Item> (boost::property_tree::ptree& root);
template <>
model::Scene* parse<model::Scene> (boost::property_tree::ptree& root);
/****** Controller namespace ******/
template <>
controller::DebugController* parse<controller::DebugController> (boost::property_tree::ptree& root);
template <>
controller::items::Giftable* parse<controller::items::Giftable> (boost::property_tree::ptree& root);
template <>
controller::items::Weapon* parse<controller::items::Weapon> (boost::property_tree::ptree& root);
template <>
controller::DebugController* parse<controller::DebugController> (boost::property_tree::ptree& root);
template <>
controller::player::PlayerController* parse<controller::player::PlayerController> (boost::property_tree::ptree& root);
/****** Graphics namespace ******/
template <>
graphics::BackgroundRenderer* parse<graphics::BackgroundRenderer> (boost::property_tree::ptree& root);
template <>
graphics::SpriteRenderer* parse<graphics::SpriteRenderer> (boost::property_tree::ptree& root);
}
}
#endif /* STORAGE_PARSERS_PARSERS_H_ */ #endif /* STORAGE_PARSERS_PARSERS_H_ */

View File

@ -1,39 +0,0 @@
/*
* ParseComponents_base.cpp
*
* Created on: Dec 1, 2016
* Author: tibi
*/
#include <storage/parsers/ParseComponents_base.h>
namespace farmlands {
namespace storage {
template <>
base::Transform* parse<base::Transform> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
if (root.front().first == "Transform")
root = root.front().second;
base::Transform* transform = new base::Transform();
transform->x = root.get<float>("<xmlattr>.x", 0.0f);
transform->y = root.get<float>("<xmlattr>.y", 0.0f);
return transform;
}
template <>
base::Camera* parse<base::Camera> (boost::property_tree::ptree& root)
{
if (root.front().first == "Camera")
root = root.front().second;
base::Camera* camera = new base::Camera();
camera->scale = root.get<float>("<xmlattr>.scale", 1.0f);
camera->mainCamera = root.get<bool>("<xmlattr>.mainCamera", false);
return camera;
}
}
}

View File

@ -1,27 +0,0 @@
/*
* ParseGameObject.h
*
* Created on: Dec 1, 2016
* Author: tibi
*/
#ifndef STORAGE_PARSERS_PARSECOMPONENTS_BASE_H_
#define STORAGE_PARSERS_PARSECOMPONENTS_BASE_H_
#include <base/GameObject.h>
#include <base/Camera.h>
#include <base/Transform.h>
#include <storage/Parse.h>
namespace farmlands {
namespace storage {
template <>
base::Transform* parse<base::Transform> (boost::property_tree::ptree& root);
template <>
base::Camera* parse<base::Camera> (boost::property_tree::ptree& root);
}
}
#endif /* STORAGE_PARSERS_PARSEGAMEOBJECT_H_ */

View File

@ -1,36 +0,0 @@
/*
* ParseComponents_controller.cpp
*
* Created on: Dec 1, 2016
* Author: tibi
*/
#include <storage/parsers/ParseComponents_controller.h>
namespace farmlands {
namespace storage {
template <>
controller::player::PlayerController* parse<controller::player::PlayerController> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
if (root.front().first == "PlayerController")
root = root.front().second;
controller::player::PlayerController* controller = new controller::player::PlayerController();
return controller;
}
template <>
controller::DebugController* parse<controller::DebugController> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
if (root.front().first == "DebugController")
root = root.front().second;
controller::DebugController* controller = new controller::DebugController();
return controller;
}
}
}

View File

@ -1,27 +0,0 @@
/*
* ParseComponents_controller.h
*
* Created on: Dec 1, 2016
* Author: tibi
*/
#ifndef STORAGE_PARSERS_PARSECOMPONENTS_CONTROLLER_H_
#define STORAGE_PARSERS_PARSECOMPONENTS_CONTROLLER_H_
#include <controller/player/PlayerController.h>
#include <controller/DebugController.h>
#include <storage/Parse.h>
namespace farmlands {
namespace storage {
template <>
controller::player::PlayerController* parse<controller::player::PlayerController> (boost::property_tree::ptree& root);
template <>
controller::DebugController* parse<controller::DebugController> (boost::property_tree::ptree& root);
}
}
#endif /* STORAGE_PARSERS_PARSECOMPONENTS_CONTROLLER_H_ */

View File

@ -1,42 +0,0 @@
/*
* ParseComponents_graphics.cpp
*
* Created on: Dec 1, 2016
* Author: tibi
*/
#include <storage/parsers/ParseComponents_graphics.h>
namespace farmlands {
namespace storage {
template <>
graphics::BackgroundRenderer* parse<graphics::BackgroundRenderer> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
if (root.front().first == "BackgroundRenderer")
root = root.front().second;
graphics::BackgroundRenderer* renderer = new graphics::BackgroundRenderer();
return renderer;
}
template <>
graphics::SpriteRenderer* parse<graphics::SpriteRenderer> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
if (root.front().first == "SpriteRenderer")
root = root.front().second;
graphics::SpriteRenderer* renderer = new graphics::SpriteRenderer();
// Load sprite
std::string spritePath = root.get<std::string>("<xmlattr>.sprite");
resources::ResourceId spriteId = resources::ResourceManager::instance().getId(spritePath);
renderer->sprite = parse<base::Sprite>(spriteId);
return renderer;
}
}
}

View File

@ -1,27 +0,0 @@
/*
* ParseComponents_graphics.h
*
* Created on: Dec 1, 2016
* Author: tibi
*/
#ifndef STORAGE_PARSERS_PARSECOMPONENTS_GRAPHICS_H_
#define STORAGE_PARSERS_PARSECOMPONENTS_GRAPHICS_H_
#include <graphics/BackgroundRenderer.h>
#include <graphics/SpriteRenderer.h>
#include <storage/Parse.h>
namespace farmlands {
namespace storage {
template <>
graphics::BackgroundRenderer* parse<graphics::BackgroundRenderer> (boost::property_tree::ptree& root);
template <>
graphics::SpriteRenderer* parse<graphics::SpriteRenderer> (boost::property_tree::ptree& root);
}
}
#endif /* STORAGE_PARSERS_PARSECOMPONENTS_GRAPHICS_H_ */

View File

@ -1,92 +0,0 @@
/*
* ParseComponents_model.cpp
*
* Created on: Dec 1, 2016
* Author: tibi
*/
#include <storage/parsers/ParseComponents_model.h>
#include <resources/Resources.h>
using namespace farmlands::resources;
namespace farmlands {
namespace storage {
void parseBackgroundCells(resources::ResourceId cellsResource, model::Background* back, size_t layer)
{
Assert(RInfo[cellsResource].type == ResourceType::BackgroundLayer, "Resource must be a level layer.");
char buffer[1024 * 10];
// Open file
std::string pathIn = ResourceManager::instance().getPath(cellsResource);
std::ifstream in(pathIn);
if (!in)
THROW(utils::ResourceLoadException, "Could not load level layer " + pathIn);
// Read CSV file line by line
for (size_t row = 0; row < back->rowCount(); row++)
{
in.getline(buffer, sizeof(buffer));
if (in.eof())
THROW(utils::ResourceLoadException, "Unexpected end of file " + pathIn);
// Separated by comma (or maybe semicolon)
char* nextNum = strtok(buffer, ",;");
for (size_t col = 0; col < back->columnCount() && nextNum != NULL; col++)
{
model::Cell cell = (model::Cell)strtol(nextNum, NULL, 10);
back->setCell(layer, row, col, cell);
nextNum = strtok(NULL, ",;");
}
}
in.close();
}
template <>
model::Background* parse<model::Background> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
if (root.front().first == "Background")
root = root.front().second;
// Read sizes
uint32_t layers = root.count("Layer");
uint32_t rows = root.get<uint32_t>("<xmlattr>.rows");
uint32_t cols = root.get<uint32_t>("<xmlattr>.columns");
// Create background object
model::Background* back = new model::Background(layers, rows, cols);
// Read layers
size_t layerNum = 0;
for (auto layer : root)
{
if (layer.first == "Layer")
{
// Read cells
std::string cellsPath = layer.second.get<std::string>("<xmlattr>.cells");
resources::ResourceId cellsId = resources::ResourceManager::instance().getId(cellsPath);
parseBackgroundCells(cellsId, back, layerNum);
// Read texture name
std::string texPath = layer.second.get<std::string>("<xmlattr>.texture");
resources::ResourceId tex = resources::ResourceManager::instance().getId(texPath);
back->setTexture(layerNum, tex);
++layerNum;
}
}
return back;
}
}
}

View File

@ -1,27 +0,0 @@
/*
* ParseComponents_model.h
*
* Created on: Dec 1, 2016
* Author: tibi
*/
#ifndef STORAGE_PARSERS_PARSECOMPONENTS_MODEL_H_
#define STORAGE_PARSERS_PARSECOMPONENTS_MODEL_H_
#include <model/Background.h>
#include <storage/Parse.h>
namespace farmlands {
namespace storage {
void parseBackgroundCells(resources::ResourceId cellsResource, model::Background* back, size_t layer);
template <>
model::Background* parse<model::Background> (boost::property_tree::ptree& root);
}
}
#endif /* STORAGE_PARSERS_PARSECOMPONENTS_MODEL_H_ */

View File

@ -1,30 +0,0 @@
/*
* ParseConfiguration.cpp
*
* Created on: Dec 1, 2016
* Author: tibi
*/
#include <storage/parsers/ParseConfiguration.h>
#include <resources/Resources.h>
using namespace farmlands::resources;
namespace farmlands {
namespace storage {
template <>
model::Configuration* parse<model::Configuration> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
if (root.front().first == "Configuration")
root = root.front().second;
model::Configuration* config = new model::Configuration();
config->animationFps = root.get<float>("animationFps");
return config;
}
} /* namespace storage */
} /* namespace farmlands */

View File

@ -1,23 +0,0 @@
/*
* ParseConfiguration.h
*
* Created on: Dec 1, 2016
* Author: tibi
*/
#ifndef STORAGE_PARSERS_PARSECONFIGURATION_H_
#define STORAGE_PARSERS_PARSECONFIGURATION_H_
#include <model/Configuration.h>
#include <storage/Parse.h>
namespace farmlands {
namespace storage {
template <>
model::Configuration* parse<model::Configuration> (boost::property_tree::ptree& root);
} /* namespace storage */
} /* namespace farmlands */
#endif /* STORAGE_PARSERS_PARSECONFIGURATION_H_ */

View File

@ -1,61 +0,0 @@
/*
* ParseGameObject.cpp
*
* Created on: Dec 1, 2016
* Author: tibi
*/
#include <model/Background.h>
#include <storage/parsers/ParseGameObject.h>
namespace farmlands {
namespace storage {
template <>
base::GameObject* parse<base::GameObject> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
if (root.front().first == "GameObject")
root = root.front().second;
base::GameObject* gameObj = new base::GameObject();
gameObj->name = root.get<std::string>("<xmlattr>.name");
for (auto child : root)
{
// Base objects
if (child.first == "Transform")
gameObj->addComponent(parse<base::Transform>(child.second));
else if (child.first == "Camera")
gameObj->addComponent(parse<base::Camera>(child.second));
// Model
else if (child.first == "Background")
{
std::string path = child.second.get<std::string>("<xmlattr>.src");
resources::ResourceId id = resources::ResourceManager::instance().getId(path);
gameObj->addComponent(parse<model::Background>(id));
}
// Graphics
else if (child.first == "BackgroundRenderer")
gameObj->addComponent(parse<graphics::BackgroundRenderer>(child.second));
else if (child.first == "SpriteRenderer")
gameObj->addComponent(parse<graphics::SpriteRenderer>(child.second));
// Controllers
else if (child.first == "PlayerController")
gameObj->addComponent(parse<controller::player::PlayerController>(child.second));
else if (child.first == "DebugController")
gameObj->addComponent(parse<controller::DebugController>(child.second));
// !!! Add additional types here !!!
}
return gameObj;
}
}
}

View File

@ -1,30 +0,0 @@
/*
* ParseGameObject.h
*
* Created on: Dec 1, 2016
* Author: tibi
*/
#ifndef STORAGE_PARSERS_PARSEGAMEOBJECT_H_
#define STORAGE_PARSERS_PARSEGAMEOBJECT_H_
#include <base/GameObject.h>
#include <base/Camera.h>
#include <base/Transform.h>
#include <controller/player/PlayerController.h>
#include <controller/DebugController.h>
#include <graphics/BackgroundRenderer.h>
#include <graphics/SpriteRenderer.h>
#include <storage/Parse.h>
#include <resources/Resources.h>
namespace farmlands {
namespace storage {
template <>
base::GameObject* parse<base::GameObject> (boost::property_tree::ptree& root);
}
}
#endif /* STORAGE_PARSERS_PARSEGAMEOBJECT_H_ */

View File

@ -1,39 +0,0 @@
/*
* ParseScene.cpp
*
* Created on: Dec 1, 2016
* Author: tibi
*/
#include <storage/parsers/ParseScene.h>
namespace farmlands {
namespace storage {
template <>
base::Scene* parse<base::Scene> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
if (root.front().first == "Scene")
root = root.front().second;
base::Scene* scene = new base::Scene();
scene->cellWidth = root.get<uint32_t>("<xmlattr>.cellWidth");
scene->cellHeight = root.get<uint32_t>("<xmlattr>.cellHeight");
for (auto child : root)
{
if (child.first == "GameObject")
{
base::GameObject* obj = parse<base::GameObject>(child.second);
scene->root.addChild(obj);
}
}
return scene;
}
}
}

View File

@ -1,27 +0,0 @@
/*
* ParseScene.h
*
* Created on: Dec 1, 2016
* Author: tibi
*/
#ifndef STORAGE_PARSERS_PARSE_SCENE_H_
#define STORAGE_PARSERS_PARSE_SCENE_H_
#include <base/GameObject.h>
#include <base/Scene.h>
#include <storage/Parse.h>
#include <resources/Resources.h>
namespace farmlands {
namespace storage {
template <>
base::Scene* parse<base::Scene> (boost::property_tree::ptree& root);
}
}
#endif /* STORAGE_PARSE_H_ */

View File

@ -1,84 +0,0 @@
/*
* ParseSprite.cpp
*
* Created on: Dec 1, 2016
* Author: tibi
*/
#include <storage/parsers/ParseSprite.h>
#include <resources/Resources.h>
namespace farmlands {
namespace storage {
template <>
base::Frame* parse<base::Frame> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
if (root.front().first == "Frame")
root = root.front().second;
base::Frame* frame = new base::Frame();
// Obtine tile set id
std::string tileSetPath = root.get<std::string>("<xmlattr>.tileSet");
frame->tileSetId = resources::ResourceManager::instance().getId(tileSetPath);
// Set properties
frame->tileSetCell = root.get<int>("<xmlattr>.cell");
frame->width = root.get<uint32_t>("<xmlattr>.w", 1u);
frame->height = root.get<uint32_t>("<xmlattr>.h", 1u);
frame->duration = root.get<uint32_t>("<xmlattr>.duration");
return frame;
}
template <>
base::SpriteState* parse<base::SpriteState> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
if (root.front().first == "SpriteState")
root = root.front().second;
base::SpriteState* spriteState = new base::SpriteState();
spriteState->name = root.get<std::string>("<xmlattr>.name");
for (auto child : root)
{
if (child.first == "Frame")
{
base::Frame* frame = parse<base::Frame>(child.second);
spriteState->frames.push_back(*frame);
delete frame;
}
}
return spriteState;
}
template <>
base::Sprite* parse<base::Sprite> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
if (root.front().first == "Sprite")
root = root.front().second;
base::Sprite* sprite = new base::Sprite();
sprite->anchorX = root.get<float>("<xmlattr>.anchorX");
sprite->anchorY = root.get<float>("<xmlattr>.anchorY");
for (auto child : root)
{
if (child.first == "State")
{
base::SpriteState* state = parse<base::SpriteState>(child.second);
sprite->addState(*state);
delete state;
}
}
return sprite;
}
}
}

View File

@ -1,29 +0,0 @@
/*
* ParseSprite.h
*
* Created on: Dec 1, 2016
* Author: tibi
*/
#ifndef STORAGE_PARSERS_PARSESPRITE_H_
#define STORAGE_PARSERS_PARSESPRITE_H_
#include <base/Sprite.h>
#include <storage/Parse.h>
namespace farmlands {
namespace storage {
template <>
base::Frame* parse<base::Frame> (boost::property_tree::ptree& root);
template <>
base::SpriteState* parse<base::SpriteState> (boost::property_tree::ptree& root);
template <>
base::Sprite* parse<base::Sprite> (boost::property_tree::ptree& root);
}
}
#endif /* STORAGE_PARSERS_PARSESPRITE_H_ */