feat: world rendering

This commit is contained in:
Sara 2025-06-04 17:21:50 +02:00
parent d5d98c25c2
commit 7b6855321f
4 changed files with 67 additions and 23 deletions

View file

@ -3,7 +3,7 @@
#include "SDL2/SDL_rect.h" #include "SDL2/SDL_rect.h"
enum class Directions : unsigned short { enum Directions : unsigned short {
NORTH = 0x1, NORTH = 0x1,
EAST = 0x2, EAST = 0x2,
SOUTH = 0x4, SOUTH = 0x4,

View file

@ -1,15 +1,39 @@
#include "world.h" #include "world.h"
#include "core/character.h" #include "core/character.h"
#include "core/renderer.h"
#include "core/roguedefs.h"
#include <SDL2/SDL_log.h>
#include <cassert> #include <cassert>
namespace rogue { namespace rogue {
void Room::draw() { void Room::draw(Tile world_pivot) {
// TODO: . for(Tile local_tile{0, 0}; local_tile.y < this->chunk_size;) {
if(this->tile_is_wall({local_tile.x, local_tile.y})) {
Render::draw({
world_pivot.x + local_tile.x,
world_pivot.y + local_tile.y
}, 1);
}
if((++local_tile.x %= this->chunk_size) == 0) {
++local_tile.y;
}
}
} }
bool Room::tile_is_wall(Tile local_tile) const { bool Room::tile_is_wall(Tile local_tile) const {
// TODO: I wonder what bool const is_outside_room{
return false; local_tile.x <= this->rect.x
|| local_tile.y <= this->rect.y
|| local_tile.x >= this->rect.x + this->rect.w-1
|| local_tile.y >= this->rect.y + this->rect.h-1};
int chunk_size2 = chunk_size/2;
bool const is_outside_hallways{
((this->hallway_paths & Directions::NORTH) == 0 || local_tile.x != chunk_size / 2 || local_tile.y > chunk_size2)
&& ((this->hallway_paths & Directions::SOUTH) == 0 || local_tile.x != chunk_size / 2 || local_tile.y < chunk_size2)
&& ((this->hallway_paths & Directions::WEST) == 0 || local_tile.y != chunk_size / 2 || local_tile.x < chunk_size2)
&& ((this->hallway_paths & Directions::EAST) == 0 || local_tile.y != chunk_size / 2 || local_tile.x > chunk_size2)
};
return is_outside_room && is_outside_hallways;
} }
void World::act() { void World::act() {
@ -19,8 +43,12 @@ void World::act() {
} }
void World::render() { void World::render() {
for(Room &room : this->rooms) { Render::clear({this->chunk_size/2, this->chunk_size/2});
room.draw(); for(size_t i{0}; i < this->rooms.size(); ++i) {
this->rooms[i].draw({
.x = int(i % this->shear * this->chunk_size),
.y = int(i / this->shear * this->chunk_size)
});
} }
for(Character &character : this->characters) { for(Character &character : this->characters) {
character.draw(); character.draw();
@ -70,16 +98,30 @@ WorldGenerator &WorldGenerator::with_room_size(unsigned min_side_length, unsigne
} }
World WorldGenerator::generate() { World WorldGenerator::generate() {
// TODO: the rest of the fucking owl assert(this->chunk_side_length > 0 && "Chunk size is required to generate world");
assert(this->min_room_size > 0 && "Room size is required to generate world");
assert(this->min_room_size < this->max_room_size && "Room size is required to generate world");
assert(this->world_side_length > 0 && "World size is required to generate world");
World world{}; World world{};
Character character{Character(world, {0,0}, CharacterData { world.chunk_size = this->chunk_side_length;
world.shear = this->world_side_length;
world.characters.push_back(Character(world, {this->chunk_side_length/2, this->chunk_side_length/2}, CharacterData {
.health = 1, .health = 1,
.damage = 1, .damage = 1,
.sprite = 0, .sprite = 0,
.logic = null_character_logic_function .logic = null_character_logic_function
})}; }));
character.data.logic(character); world.rooms.reserve(this->world_side_length * this->world_side_length);
world.characters.push_back(character); world.rooms.push_back(Room {
.hallway_paths = Directions(Directions::NORTH | Directions::EAST),
.chunk_size = this->chunk_side_length,
.rect = {
(this->chunk_side_length - this->max_room_size) / 2,
(this->chunk_side_length - this->max_room_size) / 2,
this->max_room_size,
this->max_room_size
}
});
return world; return world;
} }
} }

View file

@ -15,9 +15,12 @@ struct TileData {
}; };
struct Room { struct Room {
// bitmask of hallways
Directions hallway_paths{0}; Directions hallway_paths{0};
int chunk_size{0};
// the starting tile and length of the walls
SDL_Rect rect{0, 0, 1, 1}; SDL_Rect rect{0, 0, 1, 1};
void draw(); void draw(Tile pivot);
bool tile_is_wall(Tile local_tile) const; bool tile_is_wall(Tile local_tile) const;
}; };
@ -45,8 +48,8 @@ public:
WorldGenerator &with_room_size(unsigned min_side_length, unsigned max_side_length); WorldGenerator &with_room_size(unsigned min_side_length, unsigned max_side_length);
World generate(); World generate();
private: private:
unsigned chunk_side_length{0}, world_side_length{0}; int chunk_side_length{0}, world_side_length{0};
unsigned max_room_size{0}, min_room_size{0}; int max_room_size{0}, min_room_size{0};
}; };
} }

View file

@ -5,24 +5,23 @@
using namespace rogue; using namespace rogue;
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
World world{WorldGenerator().generate()}; World world{WorldGenerator()
.with_world_size(5)
.with_chunk_size(9)
.with_room_size(2, 5)
.generate()
};
RenderData data{RenderDataSetup() RenderData data{RenderDataSetup()
.with_window("roguelike", SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_FULLSCREEN) .with_window("roguelike", SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_FULLSCREEN)
.with_renderer(SDL_RENDERER_ACCELERATED) .with_renderer(SDL_RENDERER_ACCELERATED)
.with_resource_path("resources/") .with_resource_path("resources/")
.with_sprite("wizard.png") .with_sprite("wizard.png")
.with_sprite("wall.png")
.build() .build()
}; };
Render::provide_render_data(data); Render::provide_render_data(data);
SDL_Event evt; SDL_Event evt;
for(;;) { for(;;) {
Render::clear({0, 0});
/*
Render::draw({0, 0}, 0);
Render::draw({1, 0}, 0);
Render::draw({2, 0}, 0);
Render::draw({3, 0}, 0);
*/
world.render(); world.render();
Render::present(); Render::present();
if(SDL_WaitEvent(&evt)) { if(SDL_WaitEvent(&evt)) {