diff --git a/assets/config/Default.config b/assets/config/Default.config
new file mode 100644
index 0000000..c912747
--- /dev/null
+++ b/assets/config/Default.config
@@ -0,0 +1,4 @@
+
+
+ 60
+
\ No newline at end of file
diff --git a/assets/items/lvl1_sword.item b/assets/items/lvl1_sword.item
new file mode 100644
index 0000000..9541784
--- /dev/null
+++ b/assets/items/lvl1_sword.item
@@ -0,0 +1,15 @@
+{
+ "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"
+}
\ No newline at end of file
diff --git a/assets/items/stone_pickaxe.item b/assets/items/stone_pickaxe.item
new file mode 100644
index 0000000..7de64ec
--- /dev/null
+++ b/assets/items/stone_pickaxe.item
@@ -0,0 +1,16 @@
+{
+ "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"
+}
\ No newline at end of file
diff --git a/assets/levels/Farm.back b/assets/levels/Farm.back
new file mode 100644
index 0000000..4e1cce0
--- /dev/null
+++ b/assets/levels/Farm.back
@@ -0,0 +1,8 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/levels/Farm.level b/assets/levels/Farm.level
deleted file mode 100644
index 2c16e27..0000000
--- a/assets/levels/Farm.level
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "cellWidth": 16,
- "cellHeight": 16,
-
- "layerCount" : 1,
- "width" : 380,
- "height" : 213,
-
- "layers":
- [
- {
- "name" : "Background",
- "cellsFile" : "levels/Farm_Background.csv",
- "textureFile" : "tilesets/Ground.png"
- }
- ]
-}
\ No newline at end of file
diff --git a/assets/scenes/Game.scene b/assets/scenes/Game.scene
new file mode 100644
index 0000000..50302fc
--- /dev/null
+++ b/assets/scenes/Game.scene
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/sprites/Player.sprite b/assets/sprites/Player.sprite
new file mode 100644
index 0000000..b73bd84
--- /dev/null
+++ b/assets/sprites/Player.sprite
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/sprites/items/lvl1_sword.sprite b/assets/sprites/items/lvl1_sword.sprite
new file mode 100644
index 0000000..719bf11
--- /dev/null
+++ b/assets/sprites/items/lvl1_sword.sprite
@@ -0,0 +1,36 @@
+{
+ "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
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/assets/sprites/items/stone_pickaxe.sprite b/assets/sprites/items/stone_pickaxe.sprite
new file mode 100644
index 0000000..63ac5c4
--- /dev/null
+++ b/assets/sprites/items/stone_pickaxe.sprite
@@ -0,0 +1,36 @@
+{
+ "name" : "Stone pickaxe",
+ "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
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/assets/sprites/player.sprite b/assets/sprites/player.sprite
deleted file mode 100644
index fa65df7..0000000
--- a/assets/sprites/player.sprite
+++ /dev/null
@@ -1,148 +0,0 @@
-{
- "name" : "Player",
- "anchorX" : 0.5,
- "anchorY" : 1,
-
- "states" :
- [
- {
- "name" : "Idle right",
- "frames" :
- [
- {
- "tileSet" : "tilesets/PlayerTiles.png",
- "cell" : 0,
- "width" : 1,
- "height" : 2,
- "duration" : 1
- }
- ]
- },
-
- {
- "name" : "Idle up",
- "frames" :
- [
- {
- "tileSet" : "tilesets/PlayerTiles.png",
- "cell" : 2,
- "width" : 1,
- "height" : 2,
- "duration" : 1
- }
- ]
- },
-
- {
- "name" : "Idle left",
- "frames" :
- [
- {
- "tileSet" : "tilesets/PlayerTiles.png",
- "cell" : 4,
- "width" : 1,
- "height" : 2,
- "duration" : 1
- }
- ]
- },
-
- {
- "name" : "Idle down",
- "frames" :
- [
- {
- "tileSet" : "tilesets/PlayerTiles.png",
- "cell" : 6,
- "width" : 1,
- "height" : 2,
- "duration" : 1
- }
- ]
- },
-
- {
- "name" : "Walking right",
- "frames" :
- [
- {
- "tileSet" : "tilesets/PlayerTiles.png",
- "cell" : 0,
- "width" : 1,
- "height" : 2,
- "duration" : 7
- },
- {
- "tileSet" : "tilesets/PlayerTiles.png",
- "cell" : 1,
- "width" : 1,
- "height" : 2,
- "duration" : 7
- }
- ]
- },
-
- {
- "name" : "Walking up",
- "frames" :
- [
- {
- "tileSet" : "tilesets/PlayerTiles.png",
- "cell" : 2,
- "width" : 1,
- "height" : 2,
- "duration" : 7
- },
- {
- "tileSet" : "tilesets/PlayerTiles.png",
- "cell" : 3,
- "width" : 1,
- "height" : 2,
- "duration" : 7
- }
- ]
- },
-
- {
- "name" : "Walking left",
- "frames" :
- [
- {
- "tileSet" : "tilesets/PlayerTiles.png",
- "cell" : 4,
- "width" : 1,
- "height" : 2,
- "duration" : 7
- },
- {
- "tileSet" : "tilesets/PlayerTiles.png",
- "cell" : 5,
- "width" : 1,
- "height" : 2,
- "duration" : 7
- }
- ]
- },
-
- {
- "name" : "Walking down",
- "frames" :
- [
- {
- "tileSet" : "tilesets/PlayerTiles.png",
- "cell" : 6,
- "width" : 1,
- "height" : 2,
- "duration" : 7
- },
- {
- "tileSet" : "tilesets/PlayerTiles.png",
- "cell" : 7,
- "width" : 1,
- "height" : 2,
- "duration" : 7
- }
- ]
- }
- ]
-}
\ No newline at end of file
diff --git a/assets/ui/mini_inventory.png b/assets/ui/mini_inventory.png
new file mode 100644
index 0000000..3b1b0d5
Binary files /dev/null and b/assets/ui/mini_inventory.png differ
diff --git a/assets_original/inventory_active.xcf b/assets_original/inventory_active.xcf
new file mode 100644
index 0000000..b5e339a
Binary files /dev/null and b/assets_original/inventory_active.xcf differ
diff --git a/build/prepareAssets.py b/build/prepareAssets.py
index 505d704..365c91c 100755
--- a/build/prepareAssets.py
+++ b/build/prepareAssets.py
@@ -45,10 +45,13 @@ RINFO_FOOTER=" };\n"
#
FILE_TYPES = [
([".png", ".bmp"], "Texture"),
- ([".level"], "Level"),
- ([".csv"], "LevelLayer"),
([".ttf"], "Font"),
- ([".sprite"], "Sprite"),
+ ([".sprite"], "Sprite"),
+ ([".config"], "Configuration"),
+ ([".scene"], "Scene"),
+ ([".back"], "Background"),
+ ([".csv"], "BackgroundLayer"),
+ ([".item"], "Item"),
]
diff --git a/src/GameState.cpp b/src/GameState.cpp
index b8493a9..b130e05 100644
--- a/src/GameState.cpp
+++ b/src/GameState.cpp
@@ -10,6 +10,20 @@ namespace farmlands {
GameState GameState::s_current;
+GameState::GameState()
+ : renderContext(),
+ scene(nullptr),
+ config(nullptr),
+ elapsedTime(0)
+{
+}
+
+GameState::~GameState()
+{
+ if (scene) delete scene;
+ if (config) delete config;
+}
+
GameState& farmlands::GameState::current()
{
return s_current;
diff --git a/src/GameState.h b/src/GameState.h
index b345bfc..b5d2f15 100644
--- a/src/GameState.h
+++ b/src/GameState.h
@@ -10,8 +10,7 @@
#include
#include
-#include
-#include
+#include
#include
#include
@@ -19,30 +18,20 @@
namespace farmlands {
- struct GuiState
- {
- };
-
class GameState
{
public:
+ GameState();
+ ~GameState();
static GameState& current();
static void setCurrent(GameState& state);
// Render context
base::RenderContext renderContext;
+ base::Scene* scene;
+ model::Configuration* config;
- // Gui
- GuiState gui;
-
- // Settings
- model::Configuration config;
-
- // Current game
- model::Player player;
- model::Level* currentLevel;
- base::GameObject root;
-
+ // Misc
float elapsedTime;
private:
diff --git a/src/Main.cpp b/src/Main.cpp
index 087f8ef..c318219 100644
--- a/src/Main.cpp
+++ b/src/Main.cpp
@@ -17,4 +17,9 @@ int main()
std::cerr << typeid(ex).name() << " : " << ex.message() << "\n";
std::cerr << "Source: file " << ex.file() << " line " << ex.line() << "\n";
}
+ catch (std::exception& ex)
+ {
+ std::cerr << "Panic: Caught unhandled exception!\n";
+ std::cerr << typeid(ex).name() << " : " << ex.what() << "\n";
+ }
}
diff --git a/src/base/Camera.cpp b/src/base/Camera.cpp
new file mode 100644
index 0000000..5409f88
--- /dev/null
+++ b/src/base/Camera.cpp
@@ -0,0 +1,35 @@
+/*
+ * Camera.cpp
+ *
+ * Created on: Dec 1, 2016
+ * Author: tibi
+ */
+
+#include
+#include
+#include
+
+namespace farmlands {
+namespace base {
+
+Camera::Camera()
+ : scale(1),
+ mainCamera(true)
+{
+}
+
+Camera::~Camera()
+{
+}
+
+void Camera::onCreate()
+{
+ if (mainCamera)
+ {
+ GameState::current().renderContext.setCamera(gameObject);
+ }
+}
+
+}
+}
+
diff --git a/src/base/Camera.h b/src/base/Camera.h
index d612780..5a0fc7b 100644
--- a/src/base/Camera.h
+++ b/src/base/Camera.h
@@ -13,9 +13,17 @@
namespace farmlands {
namespace base {
- struct Camera : public Component
+ class Camera : public Component
{
+ public:
+ Camera();
+ virtual ~Camera();
+
+ virtual void onCreate();
+
float scale;
+ bool mainCamera;
+
};
}
diff --git a/src/base/GameObject.h b/src/base/GameObject.h
index ef5de83..df79949 100644
--- a/src/base/GameObject.h
+++ b/src/base/GameObject.h
@@ -52,6 +52,9 @@ namespace base {
void onPostRender();
void onDestroy();
+ // Other properties
+ std::string name;
+
private:
std::unordered_map m_components;
diff --git a/src/base/Scene.h b/src/base/Scene.h
new file mode 100644
index 0000000..05bfaf4
--- /dev/null
+++ b/src/base/Scene.h
@@ -0,0 +1,25 @@
+/*
+ * Scene.h
+ *
+ * Created on: Dec 1, 2016
+ * Author: tibi
+ */
+
+#ifndef MODEL_SCENE_H_
+#define MODEL_SCENE_H_
+
+#include
+
+namespace farmlands {
+namespace base {
+
+ struct Scene
+ {
+ GameObject root;
+ uint32_t cellWidth, cellHeight;
+ };
+
+} /* namespace model */
+} /* namespace farmlands */
+
+#endif /* MODEL_SCENE_H_ */
diff --git a/src/base/Sprite.cpp b/src/base/Sprite.cpp
index 0e7d3c1..bef3819 100644
--- a/src/base/Sprite.cpp
+++ b/src/base/Sprite.cpp
@@ -19,7 +19,8 @@ Sprite::Sprite()
m_states(),
m_currentState(0),
m_currentFrame(0),
- m_currentFrameTimeLeft(0)
+ m_currentFrameTimeLeft(0),
+ m_animationVelocity(1)
{
}
@@ -53,7 +54,7 @@ void Sprite::setState(size_t stateId)
m_currentState = stateId;
m_currentFrame = 0;
- m_currentFrameTimeLeft = currentFrame().duration * 1;
+ m_currentFrameTimeLeft = currentFrame().duration;
}
void Sprite::setState(const std::string& name)
@@ -62,28 +63,19 @@ void Sprite::setState(const std::string& name)
setState(m_stateNames.at(name));
}
-void Sprite::advanceTime(uint32_t steps)
+void Sprite::advanceTime(float fractions)
{
Assert(m_states.size() > 0, "Sprite must have at least one state!");
- while (steps > 0)
+ m_currentFrameTimeLeft -= fractions * m_animationVelocity;
+
+ while (m_currentFrameTimeLeft <= 0)
{
- // There is time left in the current frame?
- if (m_currentFrameTimeLeft > 0)
- {
- uint32_t sub = std::min(steps, m_currentFrameTimeLeft);
- m_currentFrameTimeLeft -= sub;
- steps -= sub;
- }
+ // Move to the next frame
+ if (++m_currentFrame >= currentState().frames.size())
+ m_currentFrame = 0;
- if (m_currentFrameTimeLeft == 0)
- {
- // Move to the next frame
- if (++m_currentFrame >= currentState().frames.size())
- m_currentFrame = 0;
-
- m_currentFrameTimeLeft = currentFrame().duration * 1;
- }
+ m_currentFrameTimeLeft += currentFrame().duration;
}
}
@@ -93,6 +85,11 @@ SpriteState& Sprite::currentState()
return m_states.at(m_currentState);
}
+void Sprite::setAnimationVelocity(float velocity)
+{
+ m_animationVelocity = velocity;
+}
+
Frame& Sprite::currentFrame()
{
Assert(currentState().frames.size() > 0, "State must have at least one frame!");
diff --git a/src/base/Sprite.h b/src/base/Sprite.h
index f166032..494fc44 100644
--- a/src/base/Sprite.h
+++ b/src/base/Sprite.h
@@ -63,8 +63,12 @@ namespace base {
/**
* Advances the current frame
*/
- void advanceTime(uint32_t steps);
+ void advanceTime(float fractions);
+ /**
+ * Sets the animation velocity. Using this property, animation can be slowed or accelerated.
+ */
+ void setAnimationVelocity(float velocity);
// Getters
SpriteState& currentState();
@@ -80,7 +84,8 @@ namespace base {
size_t m_currentState;
size_t m_currentFrame;
- uint32_t m_currentFrameTimeLeft;
+ float m_currentFrameTimeLeft;
+ float m_animationVelocity;
};
} /* namespace model */
diff --git a/src/controller/FarmlandsGame.cpp b/src/controller/FarmlandsGame.cpp
index dcfd32c..bd55262 100644
--- a/src/controller/FarmlandsGame.cpp
+++ b/src/controller/FarmlandsGame.cpp
@@ -34,63 +34,6 @@ FarmlandsGame::FarmlandsGame() :
{
}
-void FarmlandsGame::createScene()
-{
- // Create camera
- Transform* cameraTransform = new Transform();
- cameraTransform->x = 120;
- cameraTransform->y = 100 - 1;
-
- Camera* camera = new Camera();
- camera->scale = 4.0f;
-
- GameObject* cameraObj = new GameObject();
- cameraObj->addComponent(cameraTransform);
- cameraObj->addComponent(camera);
-
- GameState::current().root.addChild(cameraObj);
- GameState::current().renderContext.setCamera(cameraObj);
- cameraObj->onCreate();
-
- // Create background
- BackgroundRenderer* backRenderer = new BackgroundRenderer();
- backRenderer->level = GameState::current().currentLevel;
-
- GameObject* backObj = new GameObject();
- backObj->addComponent(backRenderer);
-
- GameState::current().root.addChild(backObj);
- backObj->onCreate();
-
- // Create player
- Transform* playerTransform = new Transform();
- playerTransform->x = 120;
- playerTransform->y = 100;
-
- SpriteRenderer* playerRender = new SpriteRenderer();
- playerRender->sprite = ResourceManager::instance().sprite(R::Sprites::Player);
-
- PlayerController* playerCtrl = new PlayerController();
-
- GameObject* playerObj = new GameObject();
- playerObj->addComponent(playerTransform);
- playerObj->addComponent(playerRender);
- playerObj->addComponent(playerCtrl);
-
- GameState::current().root.addChild(playerObj);
- playerObj->onCreate();
-
- // Create debug object
- DebugController* dbgController = new DebugController();
-
- GameObject* dbgObj = new GameObject();
- dbgObj->addComponent(dbgController);
-
- GameState::current().root.addChild(dbgObj);
- dbgObj->onCreate();
-
-}
-
bool FarmlandsGame::initialize()
{
bool ok = true;
@@ -102,41 +45,36 @@ bool FarmlandsGame::initialize()
// Initialize & load resources
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();
+ ResourceManager::instance().loadGame();
+ GameState::current().renderContext.viewport.pixelsPerUnitX = GameState::current().scene->cellWidth;
+ GameState::current().renderContext.viewport.pixelsPerUnitY = GameState::current().scene->cellHeight;
// Finish initialization
- GameState::current().root.onInitialize();
+ GameState::current().scene->root.onInitialize();
return true;
}
void FarmlandsGame::onUpdateLogic()
{
- GameState::current().root.onUpdateLogic();
+ GameState::current().scene->root.onUpdateLogic();
}
void FarmlandsGame::onPreRender()
{
- GameState::current().root.onPreRender();
+ GameState::current().scene->root.onPreRender();
SdlRenderer::instance().renderBegin();
}
void FarmlandsGame::onRender()
{
- GameState::current().root.onRender();
+ GameState::current().scene->root.onRender();
}
void FarmlandsGame::onEvent(SDL_Event& event)
{
// Let controllers handle event
- if (GameState::current().root.onEvent(event))
+ if (GameState::current().scene->root.onEvent(event))
return;
// Nobody? Handle global events
@@ -159,13 +97,13 @@ void FarmlandsGame::onEvent(SDL_Event& event)
void FarmlandsGame::onPostRender()
{
SdlRenderer::instance().renderEnd();
- GameState::current().root.onPostRender();
+ GameState::current().scene->root.onPostRender();
}
void FarmlandsGame::stop()
{
m_running = false;
- GameState::current().root.onDestroy();
+ GameState::current().scene->root.onDestroy();
}
int FarmlandsGame::run()
diff --git a/src/controller/FarmlandsGame.h b/src/controller/FarmlandsGame.h
index b360700..30887af 100644
--- a/src/controller/FarmlandsGame.h
+++ b/src/controller/FarmlandsGame.h
@@ -9,8 +9,6 @@
#define FARMLANDSGAME_H_
#include
-#include
-#include
#include
#include
@@ -36,7 +34,6 @@ namespace controller {
void stop();
private:
- void createScene();
bool m_running;
Uint32 m_time;
diff --git a/src/controller/items/ItemController.cpp b/src/controller/items/ItemController.cpp
new file mode 100644
index 0000000..ff5e602
--- /dev/null
+++ b/src/controller/items/ItemController.cpp
@@ -0,0 +1,30 @@
+/*
+ * ItemController.cpp
+ *
+ * Created on: Nov 30, 2016
+ * Author: tibi
+ */
+
+#include
+
+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 */
diff --git a/src/controller/items/ItemController.h b/src/controller/items/ItemController.h
new file mode 100644
index 0000000..5ebb7e3
--- /dev/null
+++ b/src/controller/items/ItemController.h
@@ -0,0 +1,30 @@
+/*
+ * ItemController.h
+ *
+ * Created on: Nov 30, 2016
+ * Author: tibi
+ */
+
+#ifndef CONTROLLER_ITEMS_ITEMCONTROLLER_H_
+#define CONTROLLER_ITEMS_ITEMCONTROLLER_H_
+
+#include
+
+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_ */
diff --git a/src/controller/PlayerController.cpp b/src/controller/player/PlayerController.cpp
similarity index 72%
rename from src/controller/PlayerController.cpp
rename to src/controller/player/PlayerController.cpp
index ee7172e..e052641 100644
--- a/src/controller/PlayerController.cpp
+++ b/src/controller/player/PlayerController.cpp
@@ -6,7 +6,7 @@
*/
#include
-#include
+#include
#include
#include
#include
@@ -17,21 +17,11 @@ using namespace farmlands::model;
namespace farmlands {
namespace controller {
+namespace player {
-/**
- * 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;
+static const float PlayerWalkVelocity = 2.0f; // The default velocity of the player when walking (units/sec).
+static const float PlayerRunVelocity = 4.0f; // The default velocity of the player when running (units/sec).
+static const float PlayerAttackVelocity = 0.1f; // Movement speed when attacking.
/**
* Direction enum based on sign of velocity on x and y
@@ -43,12 +33,12 @@ static const Direction VelocitySignDirections[3][3] =
{ Direction::NorthEast, Direction::East, Direction::SouthEast },
};
-
PlayerController::PlayerController()
: m_transform(nullptr),
m_attackTimeLeft(0),
- m_vx(0), m_vy(0),
- m_facingDirection(Direction::South)
+ m_facingDirection(Direction::South),
+ m_walking(false),
+ m_running(false)
{
}
@@ -77,18 +67,25 @@ bool PlayerController::onEvent(SDL_Event& event)
void PlayerController::onUpdateLogic()
{
+ m_running = false;
+ m_walking = false;
+
// Compute movement velocity
float velMultiplier = PlayerWalkVelocity;
- if (Input::instance().pressed(GameKey::Run))
- velMultiplier = PlayerRunVelocity;
-
if (m_attackTimeLeft)
{
velMultiplier = PlayerAttackVelocity;
--m_attackTimeLeft;
}
+ else if (Input::instance().pressed(GameKey::Run))
+ {
+ velMultiplier = PlayerRunVelocity;
+ m_running = true;
+ }
+
+
// Make movement time independent
velMultiplier *= GameState::current().elapsedTime;
@@ -97,25 +94,15 @@ void PlayerController::onUpdateLogic()
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;
+ float newX = m_transform->x + vx;
+ float newY = m_transform->y + vy;
if ((vx || vy) && canMove(newX, newY))
{
- m_vx = vx;
- m_vy = vy;
+ m_walking = true;
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;
}
}
@@ -125,8 +112,7 @@ void PlayerController::onPreRender()
SpriteRenderer* spriteRenderer = gameObject->component();
// Compute current state
- bool idle = (m_vx == 0 && m_vy == 0);
- std::string stateName = (idle) ? "Idle " : "Walking ";
+ std::string stateName = (m_walking) ? "Walking " : "Idle ";
if (m_facingDirection & Direction::East)
stateName += "right";
@@ -138,6 +124,18 @@ void PlayerController::onPreRender()
stateName += "down";
spriteRenderer->sprite->setState(stateName);
+
+ // Set animation velocity
+ float animVelocity = (m_running) ? 1.0f : 0.7f;
+ if (m_attackTimeLeft)
+ animVelocity = 0.1f;
+
+ spriteRenderer->sprite->setAnimationVelocity(animVelocity);
+
+ // Set camera
+ base::Transform* cam = GameState::current().renderContext.cameraTransform();
+ cam->x = m_transform->x;
+ cam->y = m_transform->y - 1;
}
bool PlayerController::canMove(float x, float y)
@@ -159,5 +157,6 @@ void PlayerController::attack()
// For now - nothing
}
+}
} /* namespace controller */
} /* namespace farmlands */
diff --git a/src/controller/PlayerController.h b/src/controller/player/PlayerController.h
similarity index 91%
rename from src/controller/PlayerController.h
rename to src/controller/player/PlayerController.h
index f176f8f..3e416d2 100644
--- a/src/controller/PlayerController.h
+++ b/src/controller/player/PlayerController.h
@@ -10,14 +10,13 @@
#include
#include
+#include
+
#include
namespace farmlands {
-
-// Forward declarations
-struct GameState;
-
namespace controller {
+namespace player {
class PlayerController : public base::Component
{
@@ -38,10 +37,12 @@ namespace controller {
base::Transform* m_transform;
uint32_t m_attackTimeLeft;
- float m_vx, m_vy;
+
model::Direction m_facingDirection;
+ bool m_walking, m_running;
};
+}
} /* namespace controller */
} /* namespace farmlands */
diff --git a/src/graphics/BackgroundRenderer.cpp b/src/graphics/BackgroundRenderer.cpp
index 329bffb..75b9232 100644
--- a/src/graphics/BackgroundRenderer.cpp
+++ b/src/graphics/BackgroundRenderer.cpp
@@ -22,8 +22,8 @@ namespace farmlands {
namespace graphics {
BackgroundRenderer::BackgroundRenderer()
- : level(nullptr),
- m_context(nullptr)
+ : m_context(nullptr),
+ m_back(nullptr)
{
}
@@ -36,6 +36,7 @@ void BackgroundRenderer::onInitialize()
Assert(gameObject != nullptr, "Component not properly initialized!");
m_context = &GameState::current().renderContext;
+ m_back = gameObject->component();
}
void BackgroundRenderer::onRender()
@@ -53,21 +54,21 @@ void BackgroundRenderer::onRender()
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);
+ minCellX = clamp(minCellX, 0, (int)m_back->columnCount() - 1);
+ maxCellX = clamp(maxCellX, 0, (int)m_back->columnCount() - 1);
+ minCellY = clamp(minCellY, 0, (int)m_back->rowCount() - 1);
+ maxCellY = clamp(maxCellY, 0, (int)m_back->rowCount() - 1);
// Draw each layer
- for (size_t i = 0; i < level->layerCount(); i++)
+ for (size_t i = 0; i < m_back->layerCount(); i++)
{
- int textureId = level->texture(i);
+ resources::ResourceId textureId = m_back->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);
+ int cellId = m_back->cell(i, y, x);
// Obtain texture
SDL_Texture* texture = ResourceManager::instance().texture(textureId);
diff --git a/src/graphics/BackgroundRenderer.h b/src/graphics/BackgroundRenderer.h
index 0d9087a..8a6f443 100644
--- a/src/graphics/BackgroundRenderer.h
+++ b/src/graphics/BackgroundRenderer.h
@@ -11,7 +11,8 @@
#include
#include
#include
-#include
+#include
+#include
namespace farmlands {
namespace graphics {
@@ -25,14 +26,12 @@ public:
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;
+ model::Background* m_back;
};
} /* namespace graphics */
diff --git a/src/graphics/SpriteRenderer.cpp b/src/graphics/SpriteRenderer.cpp
index f79b02f..bbeeab7 100644
--- a/src/graphics/SpriteRenderer.cpp
+++ b/src/graphics/SpriteRenderer.cpp
@@ -13,6 +13,7 @@
#include
using namespace farmlands::graphics::backend;
+using namespace farmlands::resources;
namespace farmlands {
namespace graphics {
@@ -66,7 +67,10 @@ void SpriteRenderer::onRender()
void SpriteRenderer::onPostRender()
{
- sprite->advanceTime(1);
+ float animFps = GameState::current().config->animationFps;
+ float deltaTime = GameState::current().elapsedTime;
+
+ sprite->advanceTime(animFps * deltaTime);
}
void SpriteRenderer::getCell(SDL_Texture* texture, uint32_t cell, int* outX, int* outY)
diff --git a/src/gui/widgets/TextArea.cpp b/src/gui/widgets/TextArea.cpp
index 8188af4..a9910a4 100644
--- a/src/gui/widgets/TextArea.cpp
+++ b/src/gui/widgets/TextArea.cpp
@@ -171,7 +171,7 @@ void TextArea::wrapText(TTF_Font* font)
m_wrappedText = m_text + " ";
// Process characters
- for (int i = 0; i < m_wrappedText.size(); i++)
+ for (int i = 0; i < (int)m_wrappedText.size(); i++)
{
// Remove unwanted character
if (m_wrappedText[i] == '\r')
diff --git a/src/input/GameKey.h b/src/input/GameKey.h
index 683000e..f126888 100644
--- a/src/input/GameKey.h
+++ b/src/input/GameKey.h
@@ -13,20 +13,37 @@ namespace input {
enum GameKey
{
+ // Movement
Right,
Up,
Left,
Down,
-
- Action,
- Action2,
Run,
+ // Actions
+ Action,
+ Action2,
+
+ // Alternative move keys
AltRight,
AltUp,
AltLeft,
AltDown,
+ // Inventory
+ InventoryToggle,
+ Inventory1,
+ Inventory2,
+ Inventory3,
+ Inventory4,
+ Inventory5,
+ Inventory6,
+ Inventory7,
+ Inventory8,
+ Inventory9,
+ Inventory10,
+
+ // Debug keys
Debug_ZoomIn,
Debug_ZoomOut,
diff --git a/src/input/GameKeyConfiguration.cpp b/src/input/GameKeyConfiguration.cpp
index 36a43a1..1c1e1c0 100644
--- a/src/input/GameKeyConfiguration.cpp
+++ b/src/input/GameKeyConfiguration.cpp
@@ -17,20 +17,37 @@ namespace input {
{
.keys =
{
+ // Movement
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
+ // Action keys
+ SDL_SCANCODE_SPACE, // Action
+ SDL_SCANCODE_LCTRL, // Action2
+
+ // Alternative movement
SDL_SCANCODE_D, // AltRight
SDL_SCANCODE_W, // AltUp
SDL_SCANCODE_A, // AltLeft
SDL_SCANCODE_S, // AltRight
+ // Inventory
+ SDL_SCANCODE_I, // InventoryToggle
+ SDL_SCANCODE_1, // Inventory1
+ SDL_SCANCODE_2, // Inventory2
+ SDL_SCANCODE_3, // Inventory3
+ SDL_SCANCODE_4, // Inventory4
+ SDL_SCANCODE_5, // Inventory5
+ SDL_SCANCODE_6, // Inventory6
+ SDL_SCANCODE_7, // Inventory7
+ SDL_SCANCODE_8, // Inventory8
+ SDL_SCANCODE_9, // Inventory9
+ SDL_SCANCODE_0, // Inventory10
+
+ // Debug
SDL_SCANCODE_KP_PLUS, // Debug_ZoomIn,
SDL_SCANCODE_KP_MINUS, // Debug_ZoomOut,
}
diff --git a/src/model/Background.cpp b/src/model/Background.cpp
new file mode 100644
index 0000000..cb89132
--- /dev/null
+++ b/src/model/Background.cpp
@@ -0,0 +1,61 @@
+/*
+ * Background.cpp
+ *
+ * Created on: Dec 1, 2016
+ * Author: tibi
+ */
+
+#include
+#include
+
+namespace farmlands {
+namespace model {
+
+
+Background::Background(size_t layerCount, size_t rowCount, size_t columnCount)
+ : m_cells(new Cell[layerCount * rowCount * columnCount]),
+ m_textures(new resources::ResourceId[layerCount]),
+ m_layers(layerCount),
+ m_rows(rowCount),
+ m_columns(columnCount)
+{
+}
+
+Background::~Background()
+{
+ delete[] m_cells;
+ delete[] m_textures;
+}
+
+Cell Background::cell(size_t layer, size_t row, size_t col) const
+{
+ Assert(layer < m_layers, "Layer out of bounds.");
+ Assert(row < m_rows, "Row out of bounds.");
+ Assert(col < m_columns, "Column out of bounds.");
+
+ return m_cells[layer * m_rows * m_columns + row * m_columns + col];
+}
+
+void Background::setCell(size_t layer, size_t row, size_t col, Cell value)
+{
+ Assert(layer < m_layers, "Layer out of bounds.");
+ Assert(row < m_rows, "Row out of bounds.");
+ Assert(col < m_columns, "Column out of bounds.");
+
+ m_cells[layer * m_rows * m_columns + row * m_columns + col] = value;
+}
+
+resources::ResourceId Background::texture(size_t layer) const
+{
+ Assert(layer < m_layers, "Layer out of bounds.");
+ return m_textures[layer];
+}
+
+void Background::setTexture(size_t layer, resources::ResourceId textureId) const
+{
+ Assert(layer < m_layers, "Layer out of bounds.");
+ m_textures[layer] = textureId;
+}
+
+} /* namespace model */
+} /* namespace farmlands */
diff --git a/src/model/Level.h b/src/model/Background.h
similarity index 52%
rename from src/model/Level.h
rename to src/model/Background.h
index 14b7fdb..f3145d4 100644
--- a/src/model/Level.h
+++ b/src/model/Background.h
@@ -1,29 +1,26 @@
/*
- * Level.h
+ * Background.h
*
- * Created on: Nov 11, 2016
+ * Created on: Dec 1, 2016
* Author: tibi
*/
-#ifndef MODEL_LEVEL_H_
-#define MODEL_LEVEL_H_
+#ifndef MODEL_BACKGROUND_H_
+#define MODEL_BACKGROUND_H_
-#include
-#include
+#include
+#include
namespace farmlands {
namespace model {
typedef int16_t Cell;
- class Level
+ class Background: public base::Component
{
public:
- Level(size_t layerCount, size_t rowCount, size_t columnCount);
- Level(const Level&) = delete;
- Level& operator= (const Level&) = delete;
-
- virtual ~Level();
+ Background(size_t layerCount, size_t rowCount, size_t columnCount);
+ virtual ~Background();
inline size_t layerCount() const { return m_layers; }
inline size_t rowCount() const { return m_rows; }
@@ -32,14 +29,12 @@ namespace model {
Cell cell(size_t layer, size_t row, size_t col) const;
void setCell(size_t layer, size_t row, size_t col, Cell value);
- int texture(size_t layer) const;
- void setTexture(size_t layer, int textureId) const;
-
- size_t m_cellWidth, m_cellHeight;
+ resources::ResourceId texture(size_t layer) const;
+ void setTexture(size_t layer, resources::ResourceId textureId) const;
private:
Cell* m_cells;
- int* m_textures;
+ resources::ResourceId* m_textures;
size_t m_layers;
size_t m_rows;
size_t m_columns;
@@ -48,4 +43,4 @@ namespace model {
} /* namespace model */
} /* namespace farmlands */
-#endif /* MODEL_LEVEL_H_ */
+#endif /* MODEL_BACKGROUND_H_ */
diff --git a/src/model/Configuration.h b/src/model/Configuration.h
index 6639a61..08b075d 100644
--- a/src/model/Configuration.h
+++ b/src/model/Configuration.h
@@ -4,37 +4,20 @@
* Created on: Nov 13, 2016
* Author: tibi
*/
+#ifndef MODEL_CONFIGURATION_H_
+#define MODEL_CONFIGURATION_H_
#include
namespace farmlands {
namespace model {
- struct KeyConfiguration
- {
- SDL_Scancode Right = SDL_SCANCODE_RIGHT;
- SDL_Scancode Up = SDL_SCANCODE_UP;
- SDL_Scancode Left = SDL_SCANCODE_LEFT;
- SDL_Scancode Down = SDL_SCANCODE_DOWN;
-
- SDL_Scancode AltRight = SDL_SCANCODE_D;
- SDL_Scancode AltUp = SDL_SCANCODE_W;
- SDL_Scancode AltLeft = SDL_SCANCODE_A;
- SDL_Scancode AltDown = SDL_SCANCODE_S;
-
- SDL_Scancode Action = SDL_SCANCODE_SPACE;
- SDL_Scancode Action2 = SDL_SCANCODE_LCTRL;
- SDL_Scancode Run = SDL_SCANCODE_LSHIFT;
-
- SDL_Scancode Debug_ZoomIn = SDL_SCANCODE_KP_PLUS;
- SDL_Scancode Debug_ZoomOut = SDL_SCANCODE_KP_MINUS;
- };
-
struct Configuration
{
- KeyConfiguration keys;
+ float animationFps = 60.0f;
};
}
}
+#endif
diff --git a/src/model/Level.cpp b/src/model/Level.cpp
deleted file mode 100644
index 03d54cf..0000000
--- a/src/model/Level.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Level.cpp
- *
- * Created on: Nov 11, 2016
- * Author: tibi
- */
-
-#include "Level.h"
-#include
-
-namespace farmlands {
-namespace model {
-
-Level::Level(size_t layerCount, size_t rowCount, size_t columnCount)
- : m_cellWidth(0),
- m_cellHeight(0),
- m_cells(new Cell[layerCount * rowCount * columnCount]),
- m_textures(new int[layerCount]),
- m_layers(layerCount),
- m_rows(rowCount),
- m_columns(columnCount)
-{
-}
-
-Level::~Level()
-{
- delete[] m_cells;
- delete[] m_textures;
-}
-
-
-Cell Level::cell(size_t layer, size_t row, size_t col) const
-{
- assert(layer < m_layers);
- assert(row < m_rows);
- assert(col < m_columns);
-
- return m_cells[layer * m_rows * m_columns + row * m_columns + col];
-}
-
-void Level::setCell(size_t layer, size_t row, size_t col, Cell value)
-{
- assert(layer < m_layers);
- assert(row < m_rows);
- assert(col < m_columns);
-
- m_cells[layer * m_rows * m_columns + row * m_columns + col] = value;
-}
-
-int Level::texture(size_t layer) const
-{
- return m_textures[layer];
-}
-
-void Level::setTexture(size_t layer, int textureId) const
-{
- m_textures[layer] = textureId;
-}
-
-} /* namespace model */
-} /* namespace farmlands */
-
diff --git a/src/model/Player.h b/src/model/Player.h
deleted file mode 100644
index 67eff6d..0000000
--- a/src/model/Player.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Player.h
- *
- * Created on: Nov 26, 2016
- * Author: tibi
- */
-
-#ifndef MODEL_PLAYER_H_
-#define MODEL_PLAYER_H_
-
-#include
-
-namespace farmlands {
-namespace model {
-
-#define PLAYER_INVENTORY_SIZE 3*12
-
- struct Player
- {
- float posX, posY;
- float lastDeltaX, lastDeltaY;
- Direction direction;
-
- bool attacking;
- uint32_t attackTimeLeft;
-
- int inventorySelection = -1;
- int inventory[PLAYER_INVENTORY_SIZE];
- };
-
-}
-}
-
-
-
-#endif /* MODEL_PLAYER_H_ */
diff --git a/src/resources/ResourceInfo.h b/src/resources/ResourceInfo.h
index 61e44ae..2fd35e4 100644
--- a/src/resources/ResourceInfo.h
+++ b/src/resources/ResourceInfo.h
@@ -15,10 +15,13 @@ namespace resources {
{
None,
Texture,
- Sprite,
- Level,
- LevelLayer,
Font,
+ Sprite,
+ Configuration,
+ Scene,
+ Background,
+ BackgroundLayer,
+ Item,
};
struct ResourceInfo
diff --git a/src/resources/ResourceManager.cpp b/src/resources/ResourceManager.cpp
new file mode 100644
index 0000000..1aba72e
--- /dev/null
+++ b/src/resources/ResourceManager.cpp
@@ -0,0 +1,162 @@
+/*
+ * ResourceManager.cpp
+ *
+ * Created on: Nov 7, 2016
+ * Author: tibi
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include
+
+#define FONTID(id,size) (id * 1000 + size)
+#define FONTID_SIZE(fontid) (fontid % 1000)
+#define FONTID_ID(fontid) (fontid / 1000)
+
+using namespace farmlands::graphics::backend;
+
+namespace farmlands {
+namespace resources {
+
+ResourceManager ResourceManager::s_instance;
+
+ResourceManager& ResourceManager::instance()
+{
+ return s_instance;
+}
+
+ResourceManager::ResourceManager()
+ : 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;
+}
+
+ResourceManager::~ResourceManager()
+{
+ // Unload resources
+ for(size_t i = 0; i < sizeof(RInfo) / sizeof(RInfo[0]); i++)
+ {
+ if (m_loadedResources[i].loaded)
+ {
+ switch(RInfo[i].type)
+ {
+ case ResourceType::Texture:
+ SDL_DestroyTexture(m_loadedResources[i].texture.texture);
+ SDL_FreeSurface(m_loadedResources[i].texture.surface);
+ break;
+
+ default:
+ std::cerr << "Warning: Cannot free resource " << i << " of type " << (int)RInfo[i].type << "\n";
+ break;
+ }
+ }
+ }
+
+ delete[] m_loadedResources;
+
+ // Unload fonts
+ for (auto pair : m_fontCache)
+ {
+ TTF_CloseFont(pair.second);
+ }
+}
+
+void ResourceManager::initialize()
+{
+}
+
+void ResourceManager::loadMainMenu()
+{
+}
+
+void ResourceManager::loadGame()
+{
+ GameState::current().config = storage::parse(R::Config::Default);
+ GameState::current().scene = storage::parse(R::Scenes::Game);
+ GameState::current().scene->root.onCreate();
+}
+
+std::string ResourceManager::getPath(ResourceId resourceId)
+{
+ Assert(resourceId >= 0 && resourceId < sizeof(RInfo) / sizeof(RInfo[0]), "Resource id out of bounds.");
+
+ boost::filesystem::path resPath(ASSETS_DIR);
+ resPath.append(RInfo[resourceId].path);
+
+ return resPath.native();
+}
+
+ResourceId ResourceManager::getId(std::string resPathStr)
+{
+ boost::filesystem::path resPath(resPathStr);
+
+ for(size_t i = 0; i < sizeof(RInfo) / sizeof(RInfo[0]); i++)
+ {
+ boost::filesystem::path iPath (RInfo[i].path);
+ if (resPath == iPath)
+ return i;
+ }
+
+ return (ResourceId)-1;
+}
+
+TTF_Font* ResourceManager::font(ResourceId fontId, int pointSize)
+{
+ Assert(RInfo[fontId].type == ResourceType::Font, "Resource must be a font");
+
+ // Do not load if already loaded
+ auto it = m_fontCache.find(FONTID(fontId, pointSize));
+ if (it != m_fontCache.end())
+ return it->second;
+
+ // Open font
+ std::string fontPath = getPath(fontId);
+ TTF_Font* font = TTF_OpenFont(fontPath.c_str(), pointSize);
+ if (!font)
+ THROW(utils::ResourceLoadException, "Could not load font " + fontPath);
+
+ // Cache font
+ m_fontCache.emplace(FONTID(fontId, pointSize), font);
+
+ return font;
+}
+
+SDL_Texture* ResourceManager::texture(ResourceId textureId)
+{
+ Assert(RInfo[textureId].type == ResourceType::Texture, "Resource must be a texture");
+
+ // See if already loaded
+ if (!m_loadedResources[textureId].loaded)
+ {
+ // Open file
+ std::string texturePath = getPath(textureId);
+ SDL_Surface* surface = IMG_Load(texturePath.c_str());
+ if (surface == NULL)
+ THROW(utils::ResourceLoadException, "Failed to load texture " + texturePath);
+
+ SDL_Texture* texture = SDL_CreateTextureFromSurface(SdlRenderer::instance().internalRenderer(), surface);
+ if (texture == NULL)
+ THROW(utils::ResourceLoadException, "Failed to create texture " + texturePath);
+
+ // Add to loaded resources
+ m_loadedResources[textureId].texture.surface = surface;
+ m_loadedResources[textureId].texture.texture = texture;
+ m_loadedResources[textureId].loaded = true;
+ }
+
+ return m_loadedResources[textureId].texture.texture;
+}
+
+
+} /* namespace storage */
+} /* namespace farmlands */
+
+
diff --git a/src/resources/ResourceManager.h b/src/resources/ResourceManager.h
index 13a641b..dd1430d 100644
--- a/src/resources/ResourceManager.h
+++ b/src/resources/ResourceManager.h
@@ -9,7 +9,6 @@
#define STORAGE_RESOURCEMANAGER_H_
#include
-#include
#include
#include