The raycaster can now pair a floor with a ceiling tile and to demonstrate this I have a blue light that shines on to a stone floor. I also played with just pixelating a regular image rather than painting it and honestly it looks better in a lot of ways.

master
Zed A. Shaw 5 days ago
parent e015652f4c
commit 931d9493d2
  1. BIN
      assets/ceiling_moss_brick_blue_light-256.png
  2. 2
      assets/enemies.json
  3. BIN
      assets/large_stone_floor-256.png
  4. 17
      assets/tiles.json
  5. 12
      raycaster.cpp
  6. 2
      raycaster.hpp
  7. 2
      systems.cpp
  8. 6
      tests/textures.cpp
  9. 35
      textures.cpp
  10. 11
      textures.hpp
  11. 2
      worldbuilder.cpp

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

@ -20,7 +20,7 @@
{"_type": "Combat", "hp": 20, "max_hp": 20, "damage": 1, "dead": false},
{"_type": "Motion", "dx": 0, "dy": 0, "random": false},
{"_type": "EnemyConfig", "ai_script": "Enemy::actions", "ai_start_name": "Enemy::initial_state", "ai_goal_name": "Enemy::final_state"},
{"_type": "Personality", "hearing_distance": 5, "tough": true},
{"_type": "Personality", "hearing_distance": 5, "tough": false},
{"_type": "Animation", "easing": 1, "ease_rate": 0.2, "scale": 0.1, "simple": true, "frames": 10, "speed": 0.3, "stationary": false},
{"_type": "Sprite", "name": "gold_savior", "width": 256, "height": 256, "width": 256, "height": 256, "scale": 1.0},
{"_type": "Sound", "attack": "Sword_Hit_2", "death": "Humanoid_Death_1"}

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

@ -3,6 +3,7 @@
"texture": "assets/floor_tile_test-256.png",
"collision": false,
"display": 10398,
"ceiling": "ceiling_plain",
"id": 0
},
"wall_plain": {
@ -23,7 +24,7 @@
"display": 35,
"id": 3
},
"plain_ceiling": {
"ceiling_plain": {
"texture": "assets/ceiling_test-256.png",
"collision": false,
"display": 35,
@ -33,6 +34,20 @@
"texture": "assets/lava_floor-256.png",
"collision": false,
"display": 35,
"ceiling": "ceiling_plain",
"id": 5
},
"large_stone_floor": {
"texture": "assets/large_stone_floor-256.png",
"collision": false,
"display": 35,
"ceiling": "ceiling_moss_brick_blue_light",
"id": 6
},
"ceiling_moss_brick_blue_light": {
"texture": "assets/ceiling_moss_brick_blue_light-256.png",
"collision": false,
"display": 35,
"id": 7
}
}

@ -66,8 +66,6 @@ Raycaster::Raycaster(int width, int height) :
$view_sprite.setPosition({0, 0});
$pixels = make_unique<RGBA[]>($width * $height);
$view_texture.setSmooth(false);
$floor_texture = textures::get_floor();
$ceiling_texture = textures::get_ceiling();
}
void Raycaster::set_position(int x, int y) {
@ -329,6 +327,8 @@ void Raycaster::draw_ceiling_floor() {
constexpr static const int texture_height = TEXTURE_HEIGHT;
auto &lights = $level.lights->lighting();
size_t surface_i = 0;
const uint32_t *floor_texture = textures::get_surface(surface_i);
const uint32_t *ceiling_texture = textures::get_ceiling(surface_i);
for(int y = $height / 2 + 1; y < $height; ++y) {
// rayDir for leftmost ray (x=0) and rightmost (x = w)
@ -388,18 +388,18 @@ void Raycaster::draw_ceiling_floor() {
if(new_surface_i != surface_i) {
surface_i = new_surface_i;
$floor_texture = textures::get_surface(surface_i);
$ceiling_texture = textures::get_surface(surface_i);
floor_texture = textures::get_surface(surface_i);
ceiling_texture = textures::get_ceiling(surface_i);
}
// NOTE: use map_x/y to get the floor, ceiling texture.
// FLOOR
color = $floor_texture[texture_width * ty + tx];
color = floor_texture[texture_width * ty + tx];
$pixels[pixcoord(x, y)] = lighting_calc(color, row_distance, light_level);
// CEILING
color = $ceiling_texture[texture_width * ty + tx];
color = ceiling_texture[texture_width * ty + tx];
$pixels[pixcoord(x, $height - y - 1)] = lighting_calc(color, row_distance, light_level);
}
}

@ -25,8 +25,6 @@ struct Raycaster {
double $plane_y = 0.66;
sf::Texture $view_texture;
sf::Sprite $view_sprite;
const uint32_t *$floor_texture = nullptr;
const uint32_t *$ceiling_texture = nullptr;
DinkyECS::Entity aiming_at = 0;
std::unique_ptr<RGBA[]> $pixels = nullptr;

@ -390,7 +390,7 @@ std::wstring System::draw_map(GameLevel level, size_t view_x, size_t view_y, int
auto player_pos = world.get<Position>(level.player).location;
Point cam_orig = map.center_camera(player_pos, view_x, view_y);
auto &tiles = map.tiles();
auto &tile_set = textures::get_tile_set();
auto &tile_set = textures::get_map_tile_set();
// make a grid of chars to work with
auto grid = shiterator::make<wchar_t>(view_x+1, view_y+1);

@ -17,12 +17,6 @@ TEST_CASE("test texture management", "[textures]") {
auto img_ptr = textures::get_surface(0);
REQUIRE(img_ptr != nullptr);
auto floor_ptr = textures::get_floor();
REQUIRE(floor_ptr != nullptr);
auto ceiling_ptr = textures::get_ceiling();
REQUIRE(ceiling_ptr != nullptr);
LevelManager levels;
GameLevel level = levels.current();
auto& tiles = level.map->tiles();

@ -27,16 +27,15 @@ namespace textures {
TMGR.sprite_textures.try_emplace(name, sprite, texture);
}
TMGR.floor = load_image(assets["sprites"]["floor"]["path"]);
TMGR.ceiling = load_image(assets["sprites"]["ceiling"]["path"]);
}
void load_tiles() {
Config assets("assets/tiles.json");
auto &tiles = assets.json();
TMGR.surfaces.resize(tiles.size());
TMGR.tile_set.resize(tiles.size());
TMGR.ceilings.resize(tiles.size());
TMGR.map_tile_set.resize(tiles.size());
for(auto &el : tiles.items()) {
auto &config = el.value();
@ -45,11 +44,22 @@ namespace textures {
if(surface_i >= tiles.size()) {
TMGR.surfaces.resize(surface_i + 1);
TMGR.tile_set.resize(surface_i + 1);
TMGR.ceilings.resize(surface_i + 1);
TMGR.map_tile_set.resize(surface_i + 1);
}
TMGR.tile_set[surface_i] = config["display"];
TMGR.map_tile_set[surface_i] = config["display"];
TMGR.surfaces[surface_i] = load_image(texture_fname);
// NOTE: ceilings defaults to 0 which is floor texture so only need to update
if(config.contains("ceiling")) {
const std::string& name = config["ceiling"];
dbc::check(tiles.contains(name), fmt::format("invalid ceiling name {} in tile config {}", name, (std::string)el.key()));
auto& ceiling = tiles[name];
TMGR.ceilings[surface_i] = ceiling["id"];
}
}
}
@ -83,19 +93,16 @@ namespace textures {
return texture;
}
std::vector<wchar_t>& get_tile_set() {
return TMGR.tile_set;
std::vector<wchar_t>& get_map_tile_set() {
return TMGR.map_tile_set;
}
const uint32_t* get_surface(size_t num) {
return (const uint32_t *)TMGR.surfaces[num].getPixelsPtr();
}
const uint32_t* get_floor() {
return (const uint32_t *)TMGR.floor.getPixelsPtr();
}
const uint32_t* get_ceiling() {
return (const uint32_t *)TMGR.ceiling.getPixelsPtr();
const uint32_t* get_ceiling(size_t num) {
size_t ceiling_num = TMGR.ceilings[num];
return (const uint32_t *)TMGR.surfaces[ceiling_num].getPixelsPtr();
}
};

@ -16,10 +16,9 @@ namespace textures {
struct TextureManager {
std::vector<sf::Image> surfaces;
std::vector<wchar_t> tile_set;
std::vector<size_t> ceilings;
std::vector<wchar_t> map_tile_set;
std::unordered_map<std::string, SpriteTexture> sprite_textures;
sf::Image floor;
sf::Image ceiling;
};
void init();
@ -28,11 +27,9 @@ namespace textures {
sf::Image load_image(const std::string& filename);
std::vector<wchar_t>& get_tile_set();
std::vector<wchar_t>& get_map_tile_set();
const uint32_t* get_surface(size_t num);
const uint32_t* get_floor();
const uint32_t* get_ceiling();
const uint32_t* get_ceiling(size_t num);
}

@ -18,7 +18,7 @@ void WorldBuilder::stylize_rooms() {
if(tiles[it.y][it.x] == 1) {
tiles[it.y][it.x] = 2;
} else if(tiles[it.y][it.x] == 0) {
tiles[it.y][it.x] = 5;
tiles[it.y][it.x] = 6;
}
}
}

Loading…
Cancel
Save