Added Map Rendering
This commit is contained in:
parent
37a249dc62
commit
ea72294a3e
8 changed files with 114 additions and 97 deletions
|
@ -55,7 +55,7 @@ target_link_libraries(colysis
|
|||
|
||||
target_compile_definitions(colysis PUBLIC "$<$<CONFIG:DEBUG>:_DEBUG>")
|
||||
|
||||
target_include_directories(colysis PUBLIC include )
|
||||
target_include_directories(colysis PUBLIC include)
|
||||
|
||||
# put the assets folder path as a C preprocessor define
|
||||
set(ASSETS_PATH "${CMAKE_CURRENT_SOURCE_DIR}/assets/")
|
||||
|
|
10
src/Game.cpp
10
src/Game.cpp
|
@ -2,8 +2,6 @@
|
|||
|
||||
Game::Game(sf::RenderWindow& window) : window(window)
|
||||
{
|
||||
enemies.emplace_back(sf::Vector2f{100, 100});
|
||||
enemies.emplace_back(sf::Vector2f{200, 200});
|
||||
}
|
||||
|
||||
#include <iostream>
|
||||
|
@ -22,12 +20,16 @@ void Game::run()
|
|||
std::cout << "Loading took: " << milliseconds << std::endl;
|
||||
#endif
|
||||
|
||||
map.setPosition(sf::Vector2f{20, 20});
|
||||
|
||||
if (err.code != 0)
|
||||
{
|
||||
std::cout << err.message << std::endl;
|
||||
return;
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
map.debug();
|
||||
#endif
|
||||
while (window.isOpen())
|
||||
{
|
||||
while (const auto event = window.pollEvent())
|
||||
|
@ -42,10 +44,6 @@ void Game::run()
|
|||
// Render game
|
||||
window.clear({0x20, 0x20, 0x20,0xff});
|
||||
|
||||
for (auto& enemy : enemies)
|
||||
{
|
||||
window.draw(enemy);
|
||||
}
|
||||
window.draw(map);
|
||||
|
||||
window.display();
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include <vector>
|
||||
class Game
|
||||
{
|
||||
std::vector<Enemy> enemies;
|
||||
Map map;
|
||||
public:
|
||||
explicit Game(sf::RenderWindow& window);
|
||||
|
|
110
src/Map/Map.cpp
110
src/Map/Map.cpp
|
@ -24,28 +24,85 @@ auto operator<=>(int lhs, TileType rhs)
|
|||
MapError Map::populate_vertex_array() {
|
||||
if (!tiles) return {"Map: [Loading] Tilemap is not loaded", 2};
|
||||
|
||||
vertices.setPrimitiveType(sf::PrimitiveType::Triangles);
|
||||
vertices.resize(map_size.x * map_size.y);
|
||||
atlas.vertices.setPrimitiveType(sf::PrimitiveType::Triangles);
|
||||
atlas.vertices.resize(map_size.x * map_size.y * 6);
|
||||
|
||||
for (uint32_t x = 0; x < map_size.x; x++) {
|
||||
for (uint32_t y = 0; y < map_size.y; ++y)
|
||||
const auto xw = static_cast<float>(atlas.tile_size.x);
|
||||
const auto yw = static_cast<float>(atlas.tile_size.y);
|
||||
const auto tex_w = static_cast<float>(atlas.tile_size.x);
|
||||
const auto tex_h = static_cast<float>(atlas.tile_size.y);
|
||||
for (uint32_t x = 0; x < map_size.y; x++) {
|
||||
for (uint32_t y = 0; y < map_size.z; y++)
|
||||
{
|
||||
uint32_t tile = tiles[x + y * map_size.y];
|
||||
const int32_t tile = tiles[x + y * map_size.y];
|
||||
if (tile < -atlas.wall_tiles || tile > atlas.other_tiles) return {"Map: [Loading] Invalid tile! Tile type does not have a texture; ID: " + std::to_string(tile), 3};
|
||||
// map tile type to atlas
|
||||
/*
|
||||
* -----
|
||||
* --#++
|
||||
* +++++
|
||||
* Atlas:
|
||||
* +++++
|
||||
* +++--
|
||||
* ---##
|
||||
*
|
||||
* + = other
|
||||
* - = wall
|
||||
* # = special
|
||||
* + = wall
|
||||
* # = special
|
||||
* - = other
|
||||
*
|
||||
* wall_tiles = 8
|
||||
* other_tiles = 5
|
||||
* special_tiles = 2
|
||||
*
|
||||
* Tile:
|
||||
* -1 <= wall
|
||||
* 0 == special @ .type == tile_type
|
||||
* 1 >= other
|
||||
*/
|
||||
if (tile == 0) return {"Map: [Loading] [Not Implemented!] Tile is a special tile", 3};
|
||||
|
||||
// atlas tile index
|
||||
const uint32_t atlas_tile = atlas.wall_tiles + (tile - 1);
|
||||
if (atlas_tile >= atlas.wall_tiles + atlas.other_tiles) return {"Map: [Loading] Invalid tile! Tile type does not have a texture", 3};
|
||||
|
||||
// add the vertices
|
||||
const auto xf = static_cast<float>(x);
|
||||
const auto yf = static_cast<float>(y);
|
||||
const uint32_t tile_x = atlas_tile % atlas.tile_count.x;
|
||||
const uint32_t tile_y = atlas_tile / atlas.tile_count.x;
|
||||
const auto tex_x = static_cast<float>(tile_x * atlas.tile_size.x);
|
||||
const auto tex_y = static_cast<float>(tile_y * atlas.tile_size.y);
|
||||
|
||||
sf::Vertex tl = {{xf, yf}, sf::Color::White, {tex_x, tex_y}};
|
||||
sf::Vertex tr = {{xf + xw, yf}, sf::Color::White, {tex_x + tex_w, tex_y}};
|
||||
sf::Vertex bl = {{xf, yf + yw}, sf::Color::White, {tex_x, tex_y + tex_h}};
|
||||
sf::Vertex br = {{xf + xw, yf + yw}, sf::Color::White, {tex_x + tex_w, tex_y + tex_h}};
|
||||
|
||||
atlas.vertices.append(tl);
|
||||
atlas.vertices.append(tr);
|
||||
atlas.vertices.append(bl);
|
||||
|
||||
atlas.vertices.append(bl);
|
||||
atlas.vertices.append(tr);
|
||||
atlas.vertices.append(br);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return {"Map: [Loading] Success", 0};
|
||||
}
|
||||
|
||||
Map::Map() {}
|
||||
void Map::LoadDefaultTilemap() {
|
||||
atlas.wall_tiles = 0;
|
||||
atlas.other_tiles = 1;
|
||||
atlas.special_tiles = 0;
|
||||
atlas.tile_count = {1, 1};
|
||||
atlas.tile_size = {16, 16};
|
||||
if (!atlas.texture.loadFromFile(ASSETS_PATH "/default_tilemap.png")) {
|
||||
throw std::runtime_error("Map: [Loading] Could not load default tilemap -> Fatal");
|
||||
}
|
||||
}
|
||||
|
||||
Map::Map(): atlas() {
|
||||
}
|
||||
|
||||
|
||||
#include <iostream>
|
||||
|
@ -57,11 +114,16 @@ MapError Map::load(const std::filesystem::path& path)
|
|||
{
|
||||
// opening the file and checking the magic number
|
||||
std::ifstream file(path, std::ios::binary | std::ios::in);
|
||||
uint32_t magic;
|
||||
file.read(reinterpret_cast<char*>(&magic), 4);
|
||||
|
||||
if (std::memcmp(&magic, "CYMF", 4) != 0) {
|
||||
return {"Map: [Loading] Invalid magic number: " + std::string(reinterpret_cast<const char *>(&magic), 4) + " (expected CYMF)", 1};
|
||||
if (!file.is_open()) {
|
||||
return {"Map: [Loading] Could not open file: " + path.string(), 1};
|
||||
}
|
||||
|
||||
char magic[4];
|
||||
file.read(magic, 4);
|
||||
|
||||
if (std::memcmp(magic, "CYMF", 4) != 0) {
|
||||
return {"Map: [Loading] Invalid magic number: " + std::string(magic, 4) + " (expected CYMF)", 1};
|
||||
}
|
||||
|
||||
// reading the version
|
||||
|
@ -85,9 +147,13 @@ MapError Map::load(const std::filesystem::path& path)
|
|||
char* filepath_buffer = new char[filepath_buffer_size];
|
||||
file.read(filepath_buffer, filepath_buffer_size);
|
||||
|
||||
return {"Map: [Loading] [Not Implemented] Custom Tilemap is not implemented. Tilemap file: " + std::string(filepath_buffer, filepath_buffer_size), 1};
|
||||
|
||||
delete[] filepath_buffer;
|
||||
}
|
||||
else {
|
||||
LoadDefaultTilemap();
|
||||
}
|
||||
|
||||
|
||||
// load the map info
|
||||
|
@ -96,8 +162,8 @@ MapError Map::load(const std::filesystem::path& path)
|
|||
map_size = sf::Vector3<size_t>(static_cast<size_t>(map_info[0])*map_info[1], map_info[0], map_info[1]);
|
||||
|
||||
// load the tiles
|
||||
tiles = new int[map_info[0] * map_info[1] + map_info[2] * (sizeof(MapSpecial)/4)];
|
||||
for (int i = 0; i < map_info[0] * map_info[1] + map_info[2] * (sizeof(MapSpecial)/4); i++)
|
||||
tiles = new int[map_info[0] * map_info[1]];
|
||||
for (int i = 0; i < map_info[0] * map_info[1]; i++)
|
||||
{
|
||||
// read the special if needed
|
||||
file.read(reinterpret_cast<char*>(&tiles[i]), 4);
|
||||
|
@ -153,7 +219,7 @@ MapError Map::load(const std::filesystem::path& path)
|
|||
}
|
||||
|
||||
// Everything went well
|
||||
return {"Map: [Loading] Success", 0};
|
||||
return populate_vertex_array();
|
||||
}
|
||||
|
||||
sf::Vector2u Map::getSize() const
|
||||
|
@ -169,10 +235,10 @@ void Map::draw(sf::RenderTarget& target, sf::RenderStates states) const
|
|||
states.transform *= getTransform();
|
||||
|
||||
// apply the tileset texture
|
||||
states.texture = &texture;
|
||||
states.texture = &atlas.texture;
|
||||
|
||||
// draw the vertex array
|
||||
target.draw(vertices, states);
|
||||
target.draw(atlas.vertices, states);
|
||||
}
|
||||
|
||||
|
||||
|
@ -181,7 +247,7 @@ void Map::debug()
|
|||
{
|
||||
std::cout << "Map Debug" << std::endl;
|
||||
std::cout << "\tSize : " << map_size.x << ", " << map_size.y << ", " << map_size.z << std::endl;
|
||||
std::cout << "\tTiles : 0x" << tiles << std::endl;
|
||||
std::cout << "\tTiles : " << tiles << std::endl;
|
||||
for (auto& special : specials)
|
||||
{
|
||||
std::cout << "\t\tSpecial : " << special.first.x << ", " << special.first.y << std::endl;
|
||||
|
|
|
@ -71,17 +71,21 @@ struct MapError
|
|||
};
|
||||
|
||||
|
||||
#include "TileAtlas.hpp"
|
||||
|
||||
class Map : public sf::Drawable, public sf::Transformable
|
||||
{
|
||||
static_assert(sizeof(MapSpecial)%4 == 0);
|
||||
|
||||
sf::Vector2u tile_size;
|
||||
sf::Vector2u tile_count;
|
||||
sf::Texture texture;
|
||||
sf::VertexArray vertices;
|
||||
struct {
|
||||
sf::Vector2u tile_size;
|
||||
sf::Vector2u tile_count;
|
||||
|
||||
uint32_t wall_tiles;
|
||||
uint32_t other_tiles;
|
||||
uint32_t special_tiles;
|
||||
|
||||
sf::Texture texture;
|
||||
sf::VertexArray vertices;
|
||||
} atlas;
|
||||
|
||||
sf::Vector3<size_t> map_size; // width * height, width, height
|
||||
int *tiles = nullptr;
|
||||
|
@ -93,6 +97,8 @@ class Map : public sf::Drawable, public sf::Transformable
|
|||
|
||||
MapError populate_vertex_array();
|
||||
|
||||
void LoadDefaultTilemap();
|
||||
|
||||
public:
|
||||
Map();
|
||||
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
#include "TileAtlas.hpp"
|
||||
|
||||
TileAtlas TileAtlas::defaultAtlas()
|
||||
{
|
||||
TileAtlas atlas(sf::Vector2u{16, 16}, sf::Vector2u{16, 16}, ASSETS_PATH "/default_tilemap.png");
|
||||
return atlas;
|
||||
}
|
||||
|
||||
void TileAtlas::set(uint32_t x, uint32_t y)
|
||||
{
|
||||
if (x >= tile_count.x || y >= tile_count.y) return;
|
||||
}
|
||||
|
||||
TileAtlas::TileAtlas(const sf::Vector2u tile_size, const sf::Vector2u tile_count, const std::filesystem::path& path) :
|
||||
tile_size(tile_size), tile_count(tile_count) { load(path); }
|
||||
|
||||
TileAtlas::TileAtlas(sf::Vector2u tile_size, sf::Vector2u tile_count) : tile_size(tile_size), tile_count(tile_count)
|
||||
{
|
||||
}
|
||||
|
||||
void TileAtlas::load(const std::filesystem::path& path) {
|
||||
if (!texture.loadFromFile(path))
|
||||
{
|
||||
throw std::runtime_error("TileAtlas: [Loading] Could not load tilemap -> Fatal");
|
||||
}
|
||||
}
|
||||
|
||||
void TileAtlas::draw(sf::RenderTarget& target, sf::RenderStates states) const
|
||||
{
|
||||
// apply the transform
|
||||
states.transform *= getTransform();
|
||||
|
||||
// apply the tileset texture
|
||||
states.texture = &texture;
|
||||
|
||||
// draw the vertex array
|
||||
target.draw(vertices, states);
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
#pragma once
|
||||
#include <SFML/Graphics.hpp>
|
||||
|
||||
class TileAtlas : public sf::Drawable, public sf::Transformable
|
||||
{
|
||||
sf::Vector2u tile_size;
|
||||
sf::Vector2u tile_count;
|
||||
|
||||
public:
|
||||
explicit TileAtlas(sf::Vector2u tile_size, sf::Vector2u tile_count, const std::filesystem::path& path);
|
||||
TileAtlas(sf::Vector2u tile_size, sf::Vector2u tile_count);
|
||||
|
||||
void load(const std::filesystem::path& path);
|
||||
|
||||
static TileAtlas defaultAtlas();
|
||||
|
||||
void set(uint32_t, uint32_t);
|
||||
|
||||
void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
||||
|
||||
private:
|
||||
|
||||
};
|
|
@ -10,8 +10,17 @@ bitfield OptionFlags {
|
|||
bool CustomeTilemap : 1;
|
||||
};
|
||||
|
||||
struct vec2<T> {
|
||||
T x,y;
|
||||
}[[single_color]];
|
||||
|
||||
struct TilemapInfo {
|
||||
vec2<u32> dimentions;
|
||||
vec2<u32> tile_size;
|
||||
vec2<u32> tile_count;
|
||||
u32 wall_tiles;
|
||||
u32 other_tiles;
|
||||
u32 special_tiles;
|
||||
};
|
||||
|
||||
struct Options {
|
||||
|
|
Loading…
Reference in a new issue