Entities are now constructable

Added utility function to display error window
Added textures
Added font
Added a way to choose resources location
This commit is contained in:
Teo-CD 2019-06-07 22:20:34 +02:00
parent 46d26b6e61
commit 3666b9e7e9
17 changed files with 155 additions and 39 deletions

View file

@ -4,9 +4,10 @@ project(project_maat)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules" ${CMAKE_MODULE_PATH})
add_library(engine Level.cpp Level.h Entity.cpp Entity.h Game.cpp Game.h Utils.h Utils.h)
add_library(engine Level.cpp Level.h Entity.cpp Entity.h Game.cpp Game.h Utils.h Utils.h Utils.cpp)
target_link_libraries(engine
sfml-window
sfml-graphics
sfml-system)
sfml-system
pugixml)

View file

@ -6,28 +6,37 @@
const std::map<std::string,EntityType> Entity::entityTypeLookup = {
{"Citizen",EntityType::Citizen},
{"Player",EntityType::Player},
{"Significant",EntityType::Significant},
{"House",EntityType::House},
{"Car",EntityType::Car}};
Entity::Entity(int x, int y, EntityType type, int width, int height)
Entity::Entity(int x, int y, EntityType type, sf::Texture* texture, int width, int height) : type(type)
{
shape = sf::RectangleShape(sf::Vector2f(width*pro_maat::pixelsPerUnit,height*pro_maat::pixelsPerUnit));
// Sets the origin at the center of the entity
shape.setOrigin(shape.getSize()/2.0f);
// Adjust position for offset origin
shape.setPosition((x+0.5*width)*pro_maat::pixelsPerUnit,(y+0.5*width)*pro_maat::pixelsPerUnit);
shape.setTexture(texture);
currentState = State::Idle;
nextState = State::Idle;
target = sf::Vector2i(shape.getPosition());
nextTarget = target;
}
Entity::Entity(const pugi::xml_node& entityNode)
{
}
void Entity::render(sf::RenderWindow& renderWindow) const
{
}
Entity::Entity(const pugi::xml_node& entityNode, sf::Texture* texture)
: Entity(entityNode.attribute("x").as_int(),
entityNode.attribute("y").as_int(),
entityTypeLookup.at(entityNode.attribute("type").as_string()),
texture,
entityNode.attribute("w").as_int(1),
entityNode.attribute("h").as_int(1)) {}
void Entity::move()
{
// FIXME : Testing purposes
shape.setRotation(shape.getRotation()+90);
}
void Entity::update()

View file

@ -14,7 +14,7 @@
enum class EntityType
{
Citizen,
Player,
Significant,
House,
Car,
};
@ -40,10 +40,9 @@ class Entity
{
public:
/// x,y, width and height are in grid coordinates
Entity(int x, int y, EntityType type, int width = 1, int height = 1);
Entity(const pugi::xml_node& entityNode);
Entity(int x, int y, EntityType type, sf::Texture* texture, int width = 1, int height = 1);
explicit Entity(const pugi::xml_node& entityNode, sf::Texture* texture);
void render(sf::RenderWindow& renderWindow) const;
void move();
void update();
@ -54,6 +53,8 @@ public:
private:
static const std::map<std::string,EntityType> entityTypeLookup;
EntityType type;
// As it contains position, size and orientation, we do not need anything more
sf::RectangleShape shape;

View file

@ -7,22 +7,22 @@
#include "Game.h"
Game::Game(const std::vector<std::string>& levels, const std::vector<std::string>& textures)
Game::Game(std::vector<std::string>& levels, std::vector<std::string>& textures) : levelFiles(std::move(levels)),
textureFiles(std::move(textures))
{
loadTextures();
}
void Game::loadLevel(int levelId)
{
pugi::xml_document document;
pugi::xml_parse_result result = document.load_file(levelFiles.at(levelId).c_str());
pugi::xml_parse_result result = document.load_file((pro_maat::levelFolder+levelFiles.at(levelId)).c_str());
if(!result)
{
std::cerr << "Error while loading level :\n" << "\t" << result.description() << std::endl;
exit(-1);
// std::cerr << "Error while loading level :\n" << "\t" << result.description() << std::endl;
// exit(-1);
pro_maat::errorWindow(result.description());
}
currentLevel = std::make_unique<Level>(document,textures);
@ -34,11 +34,37 @@ void Game::loadTextures()
for(const std::string& filePath : textureFiles)
{
textures.emplace_back(std::make_unique<sf::Texture>());
textures.back()->loadFromFile(filePath);
textures.back()->loadFromFile(pro_maat::textureFolder+filePath);
}
}
void Game::runGame()
{
sf::RenderWindow window(sf::VideoMode(1280,1024),"Project Maat");
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
window.close();
}
// FIXME : For testing purposes
if (event.type == sf::Event::KeyPressed)
{
currentLevel->runStep();
}
}
window.clear(sf::Color::White);
// TODO : Consider drawing in a sf::RenderTexture to allow positioning the level at a fixed position ?
currentLevel->render(window);
window.display();
}
}
Game::operator bool() const
{
return (currentLevel ? true : false);
}

View file

@ -11,14 +11,14 @@
#include "Level.h"
#include "Entity.h"
#include "Utils.h"
// Used for convenience
using TextureStore = std::vector<std::unique_ptr<sf::Texture>>;
class Game {
public:
Game(const std::vector<std::string>& levels, const std::vector<std::string>& textures);
Game(std::vector<std::string>& levels, std::vector<std::string>& textures);
/// Loads the level of corresponding ID from Game::levelFiles
/// Closes the program if there is a fatal error (Missing file, bad file...)
@ -29,6 +29,8 @@ public:
// This should not be called before a level has been loaded
void runGame();
explicit operator bool() const;
private:
/// Store the paths to level files
const std::vector<std::string> levelFiles;

View file

@ -14,17 +14,24 @@ Level::Level(const pugi::xml_document& xmlDoc, const TextureStore& textureStore)
{
if(!strncmp(child.name(),"Entity",6))
{
entities.emplace_back(child);
entities.emplace_back(child,textures.at(child.attribute("textureId").as_int(0)).get());
}
}
}
void Level::render(sf::RenderWindow& renderWindow) const
{
for(const Entity& entity : entities)
{
renderWindow.draw(entity.getShape());
}
}
void Level::runStep() const
void Level::runStep()
{
for(Entity& entity: entities)
{
// FIXME : For testing purposes
entity.move();
}
}

View file

@ -20,7 +20,7 @@ public:
Level(const pugi::xml_document& xmlDoc, const TextureStore& textureStore);
void render(sf::RenderWindow& renderWindow) const;
void runStep() const;
void runStep();
private:
const sf::Vector2i size;

39
src/Utils.cpp Normal file
View file

@ -0,0 +1,39 @@
//
// Created by trotfunky on 07/06/19.
//
#include "Utils.h"
namespace pro_maat
{
void errorWindow(const std::string& error)
{
sf::Font font;
if(!font.loadFromFile(std::string(pro_maat::fontFolder)+"verdana.ttf"))
{
std::cerr << "Error while loading font for error :" << std::endl;
std::cerr << error << std::endl;
}
sf::Text errorMessage(error,font);
errorMessage.setFillColor(sf::Color::Red);
sf::Rect errorArea = errorMessage.getGlobalBounds();
errorMessage.setPosition(errorArea.width*(1.5/2-0.5),errorArea.height*(0.5));
sf::RenderWindow window(sf::VideoMode(errorArea.width*1.5,errorArea.height*2),"ERROR");
while (window.isOpen())
{
sf::Event event;
while(window.pollEvent(event))
{
if (event.type == sf::Event::Closed || event.type == sf::Event::KeyPressed || event.type == sf::Event::MouseButtonPressed)
{
window.close();
exit(-1);
}
}
window.clear(sf::Color::White);
window.draw(errorMessage);
window.display();
}
}
}

View file

@ -6,12 +6,19 @@
#define PROJECT_MAAT_UTILS_H
#include <cstdint>
#include <string>
#include <SFML/Graphics.hpp>
#include <iostream>
namespace pro_maat
{
static constexpr uint8_t pixelsPerUnit = 20;
static constexpr uint8_t pixelsPerUnit = 25;
static constexpr char levelFolder[] = "resources/";
static constexpr char textureFolder[] = "resources/";
static constexpr char fontFolder[] = "resources/";
void errorWindow(const std::string& error);
}