Skip to content

Commit 9708391

Browse files
committed
Allow customizing OOB tiles in level_bgs_*
* Improve example to showcase this
1 parent f255a34 commit 9708391

File tree

7 files changed

+120
-9
lines changed

7 files changed

+120
-9
lines changed

examples/parallax_level_bgs/src/main.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "ldtk_gen_idents.h"
1010
#include "ldtk_gen_project.h"
1111

12+
#include <bn_assert.h>
1213
#include <bn_backdrop.h>
1314
#include <bn_blending.h>
1415
#include <bn_camera_ptr.h>
@@ -31,6 +32,7 @@ int main()
3132
"PAD: move camera",
3233
"A: toggle all layer bgs visibility",
3334
"B: toggle top layer bg visibility",
35+
"L: toggle bottom layer oob tile",
3436
};
3537

3638
bn::sprite_text_generator big_text_generator(common::variable_8x16_sprite_font);
@@ -75,6 +77,38 @@ int main()
7577
}
7678
}
7779

80+
if (bn::keypad::l_pressed())
81+
{
82+
// You MUST check if `level_bgs` has the background of the layer before calling gettes/setters;
83+
// If `tiles_layer_8` doesn't have a single visible tile, it doesn't generate a BG, so it will error out.
84+
if (level_bgs.has_background(ldtk::gen::layer_ident::tiles_layer_8))
85+
{
86+
ldtk::tile_grid_base::tile_info oob_tile_info =
87+
level_bgs.out_of_bound_tile_info(ldtk::gen::layer_ident::tiles_layer_8);
88+
89+
// Tile index `0` is always a valid tile index, which denotes a fully transparent tile.
90+
if (oob_tile_info.index == 0)
91+
{
92+
// Get the tile grid from the `tiles_layer_8` layer.
93+
// If `tiles_layer_8` was an auto-tile layer, you need to use `auto_layer_tiles()` instead.
94+
const ldtk::tile_grid_base* tile_grid =
95+
level.get_layer(ldtk::gen::layer_ident::tiles_layer_8).grid_tiles();
96+
BN_ASSERT(tile_grid != nullptr, "Layer is not a tile layer");
97+
98+
// Set the tile to the same one as the top-left(x=0, y=0) tile in the grid.
99+
oob_tile_info = tile_grid->cell_tile_info(0, 0);
100+
}
101+
else // OOB tile was previously non-transparent
102+
{
103+
// Set it to transparent again
104+
oob_tile_info.index = 0;
105+
}
106+
107+
// Apply the OOB tile change
108+
level_bgs.set_out_of_bound_tile_info(oob_tile_info, ldtk::gen::layer_ident::tiles_layer_8);
109+
}
110+
}
111+
78112
static constexpr bn::fixed CAMERA_MOVE_SPEED = 4.0f;
79113

80114
if (bn::keypad::left_held())

include/ldtk_level_bgs_builder.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include "ldtk_gen_idents_fwd.h"
77
#include "ldtk_level_bgs_ptr.h"
8+
#include "ldtk_tile_grid_base.h"
89

910
#include <bn_camera_ptr.h>
1011
#include <bn_config_bgs.h>
@@ -394,6 +395,20 @@ class level_bgs_builder
394395
/// @brief Releases and returns the camera_ptr to attach to the level backgrounds to generate (if any).
395396
[[nodiscard]] auto release_camera() -> bn::optional<bn::camera_ptr>;
396397

398+
/// @brief Returns the tile info that fills the out-of-bound region of a level background.
399+
/// @note Before calling this, you @b must make sure `has_background()` returns `true`.
400+
/// @param layer_identifier identifier of the layer to get the tile info from.
401+
[[nodiscard]] auto out_of_bound_tile_info(gen::layer_ident layer_identifier) const -> tile_grid_base::tile_info;
402+
403+
/// @brief Sets the tile info that fills the out-of-bound region of a level background.
404+
/// @note Before calling this, you @b must make sure `has_background()` returns `true`. \n
405+
/// Also, you @b must use the valid tile index for the background.
406+
/// @param tile_info tile info to fill the out-of-bound region of a level background.
407+
/// @param layer_identifier identifier of the layer to set the tile info to.
408+
/// @return Reference to `this`.
409+
auto set_out_of_bound_tile_info(tile_grid_base::tile_info oob_tile_info, gen::layer_ident layer_identifier)
410+
-> level_bgs_builder&;
411+
397412
/// @brief Generates and returns a `level_bgs_ptr` without releasing the acquired resources.
398413
[[nodiscard]] auto build() const -> level_bgs_ptr;
399414

@@ -425,6 +440,8 @@ class level_bgs_builder
425440
bn::green_swap_mode green_swap_mode = bn::green_swap_mode::DEFAULT;
426441
bool mosaic_enabled = false;
427442
bool blending_bottom_enabled = true;
443+
444+
tile_grid_base::tile_info oob_tile_info = {.index = 0, .x_flip = false, .y_flip = false};
428445
};
429446
/// @endcond
430447

include/ldtk_level_bgs_ptr.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#pragma once
55

66
#include "ldtk_gen_idents_fwd.h"
7+
#include "ldtk_tile_grid_base.h"
78

89
#include <bn_camera_ptr.h>
910
#include <bn_fixed_point.h>
@@ -398,6 +399,18 @@ class level_bgs_ptr
398399
/// @brief Removes the `bn::camera_ptr` attached to these level backgrounds (if any).
399400
void remove_camera();
400401

402+
/// @brief Returns the tile info that fills the out-of-bound region of a level background.
403+
/// @note Before calling this, you @b must make sure `has_background()` returns `true`.
404+
/// @param layer_identifier identifier of the layer to get the tile info from.
405+
[[nodiscard]] auto out_of_bound_tile_info(gen::layer_ident layer_identifier) const -> tile_grid_base::tile_info;
406+
407+
/// @brief Sets the tile info that fills the out-of-bound region of a level background.
408+
/// @note Before calling this, you @b must make sure `has_background()` returns `true`. \n
409+
/// Also, you @b must use the valid tile index for the background.
410+
/// @param oob_tile_info tile info to fill the out-of-bound region of a level background.
411+
/// @param layer_identifier identifier of the layer to set the tile info to.
412+
void set_out_of_bound_tile_info(tile_grid_base::tile_info oob_tile_info, gen::layer_ident layer_identifier);
413+
401414
public:
402415
/// @brief Returns the internal handle.
403416
[[nodiscard]] const auto handle() const -> void*

src/ldtk_level_bgs_builder.cpp.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,18 @@ auto level_bgs_builder::release_camera() -> bn::optional<bn::camera_ptr>
217217
return result;
218218
}
219219

220+
auto level_bgs_builder::out_of_bound_tile_info(gen::layer_ident layer_identifier) const -> tile_grid_base::tile_info
221+
{
222+
return bg_attr(layer_identifier).oob_tile_info;
223+
}
224+
225+
auto level_bgs_builder::set_out_of_bound_tile_info(tile_grid_base::tile_info oob_tile_info,
226+
gen::layer_ident layer_identifier) -> level_bgs_builder&
227+
{
228+
bg_attr(layer_identifier).oob_tile_info = oob_tile_info;
229+
return *this;
230+
}
231+
220232
auto level_bgs_builder::build() const -> level_bgs_ptr
221233
{
222234
return level_bgs_ptr::create(*this);

src/ldtk_level_bgs_manager.cpp

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,14 @@ struct bg_t
5151
const layer& layer_instance;
5252
const tile_grid_base& grid;
5353

54+
tile_grid_base::tile_info oob_tile;
55+
5456
alignas(int) bn::regular_bg_map_cell cells[ROWS * COLUMNS];
5557
bn::regular_bg_map_item map_item;
5658
bn::regular_bg_ptr bg_ptr;
5759
bn::regular_bg_map_ptr map_ptr;
5860
bool next_visible;
61+
bool force_reload;
5962
bool grid_bloated;
6063

6164
bg_t(const level& lv_, const layer& layer_, const bn::fixed_point& cam_applied_pos, const level_bgs_builder&);
@@ -156,18 +159,20 @@ bg_t::bg_t(const level& lv_, const layer& layer_, const bn::fixed_point& cam_app
156159
const level_bgs_builder& builder)
157160
: lv(lv_), layer_instance(layer_),
158161
grid(layer_.auto_layer_tiles() ? *layer_.auto_layer_tiles() : *layer_.grid_tiles()),
159-
map_item(cells[0], bn::size(COLUMNS, ROWS)), bg_ptr(init_bg_ptr(layer_, cam_applied_pos, builder)),
160-
map_ptr(bg_ptr.map()), next_visible(bg_ptr.visible()), grid_bloated(grid.bloated())
162+
oob_tile(builder.out_of_bound_tile_info(layer_.identifier())), map_item(cells[0], bn::size(COLUMNS, ROWS)),
163+
bg_ptr(init_bg_ptr(layer_, cam_applied_pos, builder)), map_ptr(bg_ptr.map()), next_visible(bg_ptr.visible()),
164+
force_reload(false), grid_bloated(grid.bloated())
161165
{
162166
}
163167

164168
void bg_t::update(const bn::fixed_point& next_cam_applied_pos, const bn::fixed_point& prev_cam_applied_pos)
165169
{
166170
if (next_visible)
167171
{
168-
if (!bg_ptr.visible())
172+
if (force_reload || !bg_ptr.visible())
169173
{
170174
update_all_cells(next_cam_applied_pos);
175+
force_reload = false;
171176
}
172177
// Update cells when level position changed
173178
else if (next_cam_applied_pos != prev_cam_applied_pos)
@@ -300,9 +305,9 @@ void bg_t::reset_rows(const int level_8x8_first_y, const int level_8x8_last_y, c
300305

301306
if (mx < 0 || mx >= grid.c_width() || my < 0 || my >= grid.c_height())
302307
{
303-
m_tile_info.index = 0;
304-
m_tile_info.x_flip = false;
305-
m_tile_info.y_flip = false;
308+
m_tile_info.index = oob_tile.index;
309+
m_tile_info.x_flip = oob_tile.x_flip;
310+
m_tile_info.y_flip = oob_tile.y_flip;
306311
}
307312
else
308313
{
@@ -380,9 +385,9 @@ void bg_t::reset_columns(const int level_8x8_first_y, const int level_8x8_last_y
380385

381386
if (mx < 0 || mx >= grid.c_width() || my < 0 || my >= grid.c_height())
382387
{
383-
m_tile_info.index = 0;
384-
m_tile_info.x_flip = false;
385-
m_tile_info.y_flip = false;
388+
m_tile_info.index = oob_tile.index;
389+
m_tile_info.x_flip = oob_tile.x_flip;
390+
m_tile_info.y_flip = oob_tile.y_flip;
386391
}
387392
else
388393
{
@@ -872,4 +877,18 @@ void remove_camera(id_t id)
872877
lv->cam.reset();
873878
}
874879

880+
auto out_of_bound_tile_info(id_t id, gen::layer_ident layer_identifier) -> tile_grid_base::tile_info
881+
{
882+
auto lv = static_cast<const lv_t*>(id);
883+
return lv->get_bg(layer_identifier).oob_tile;
884+
}
885+
886+
void set_out_of_bound_tile_info(id_t id, tile_grid_base::tile_info oob_tile_info, gen::layer_ident layer_identifier)
887+
{
888+
auto lv = static_cast<lv_t*>(id);
889+
auto& bg = lv->get_bg(layer_identifier);
890+
bg.oob_tile = oob_tile_info;
891+
bg.force_reload = true;
892+
}
893+
875894
} // namespace ldtk::level_bgs_manager

src/ldtk_level_bgs_manager.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#pragma once
55

66
#include "ldtk_gen_idents_fwd.h"
7+
#include "ldtk_tile_grid_base.h"
78

89
#include <bn_fixed.h>
910
#include <bn_fixed_point_fwd.h>
@@ -121,6 +122,10 @@ void set_camera(id_t id, bn::camera_ptr&& camera);
121122

122123
void remove_camera(id_t id);
123124

125+
[[nodiscard]] auto out_of_bound_tile_info(id_t id, gen::layer_ident layer_identifier) -> tile_grid_base::tile_info;
126+
127+
void set_out_of_bound_tile_info(id_t id, tile_grid_base::tile_info oob_tile_info, gen::layer_ident layer_identifier);
128+
124129
} // namespace level_bgs_manager
125130

126131
} // namespace ldtk

src/ldtk_level_bgs_ptr.cpp.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,4 +414,15 @@ void level_bgs_ptr::remove_camera()
414414
level_bgs_manager::remove_camera(_handle);
415415
}
416416

417+
auto level_bgs_ptr::out_of_bound_tile_info(gen::layer_ident layer_identifier) const -> tile_grid_base::tile_info
418+
{
419+
return level_bgs_manager::out_of_bound_tile_info(_handle, layer_identifier);
420+
}
421+
422+
void level_bgs_ptr::set_out_of_bound_tile_info(tile_grid_base::tile_info oob_tile_info,
423+
gen::layer_ident layer_identifier)
424+
{
425+
level_bgs_manager::set_out_of_bound_tile_info(_handle, oob_tile_info, layer_identifier);
426+
}
427+
417428
} // namespace ldtk

0 commit comments

Comments
 (0)