razterizer / DungGine

A dungeon engine for rogue-like style games.
MIT License
1 stars 0 forks source link
2d 2d-game 2d-game-engine dungeon-crawler dungeon-crawler-game dungeon-generator game-engine game-engine-2d roguelike roguelike-game terminal-based

DungGine

GitHub License

build ubuntu build macos build ubuntu

Top Languages Goto Commit Activity Last Commit Contributors

image

dunggine_demo-comp

(Gif animation produced using terminalizer and gifsicle.)

DungGine is a terminal based dungeon engine for RPGs and dungeon-crawlers (e.g. Rogue-likes) and that uses Termin8or for rendering. This is a header only library. The engine works very well together with the GameEngine class of lib Termin8or.

There are two main classes for this dungeon generator: BSPTree that is responsible for creating the rooms, corridors and doors in the "dungeon", and then there is the class DungGine that is the dungeon game engine itself. See the next section for a summary over these two classes.

Headers

Texturing

Texturing done using the editor TextUR. Use the TextUR command line argument -c to convert a normal/fill texture to a shadow texture. DungGine supports texture animations.

Examples

dung::BSPTree::draw_regions()
image
dung::BSPTree::draw_rooms()
image
dung::BSPTree::draw_rooms()
dung::BSPTree::draw_corridors()
image
dung::BSPTree bsp_tree { 4 }; // argument: `min_room_length = 4`.
bsp_tree.generate(29, 79, dung::Orientation::Vertical); // arguments: world_size_rows, world_size_cols,
                  first_split_orientation.
bsp_tree.pad_rooms(4); // arguments: min_rnd_wall_padding = 4, [max_rnd_wall_padding = 4].
bsp_tree.create_corridors(1); // argument: min_corridor_half_width = 1, (1 means it will be three chars wide).

Text t;
SpriteHandler<NR, NC> sh;
Color bg_color = Color::Default;

dung::DungGine dungeon_engine;
dungeon_engine.load_dungeon(&bsp_tree);
dungeon_engine.style_dungeon();
dungeon_engine.draw(sh, get_real_time_s(), get_sim_time_s(), 0);
sh.print_screen_buffer(t, bg_color);
image
// Declarations
dung::BSPTree bsp_tree { 4 }; // argument: `min_room_length = 4`.
dung::DungGineTextureParams texture_params;
std::unique_ptr<dung::DungGine> dungeon_engine;
Text t;
SpriteHandler<NR, NC> sh;
Color bg_color = Color::Black;
int anim_ctr = 0;

// Initializations
bsp_tree.generate(200, 400, dung::Orientation::Vertical); // arguments: world_size_rows, world_size_cols,
                  first_split_orientation.
bsp_tree.pad_rooms(4); // arguments: min_rnd_wall_padding = 4, [max_rnd_wall_padding = 4].
bsp_tree.create_corridors(1); // argument: min_corridor_half_width = 1, (1 means it will be three chars wide).
bsp_tree.create_doors(100, true); // We also create doors here. Arguments: max_num_locked_doors, allow_passageways.

dungeon_engine = std::make_unique<dung::DungGine>(get_exe_folder(), true); // arguments: exe_folder, use_fow, texture_params.
dungeon_engine.load_dungeon(&bsp_tree);
dungeon_engine.configure_sun_rand(20.f, 120.f, dung::Latitude::NorthernHemisphere, dung::Longitude::FW, false); // 20 minutes per day and 120 minutes per year. Global shadow.
dungeon_engine.style_dungeon();
if (!dungeon_engine.place_player(sh.size()))
  std::cerr << "ERROR : Unable to place the playable character!" << std::endl;
dungeon_engine->place_keys(true);
dungeon_engine->place_lamps(20, 5, 3, true);
dungeon_engine->place_weapons(100, true);
dungeon_engine->place_potions(100, true);
dungeon_engine.set_screen_scrolling_mode(ScreenScrollingMode::WhenOutsideScreen);

// In game loop:
sh.clear();
bool game_over = false;
dungeon_engine->update(get_real_time_s(), get_sim_time_s(), get_sim_time_dt(), kpd, &game_over); // arg0 : time from game start, arg3 : keyboard::KeyPressData object, arg4 : retrieves game over state.
if (game_over)
  set_state_game_over();
dungeon_engine->draw(sh, get_real_time_s(), get_sim_time_s(), anim_ctr);
sh.print_screen_buffer(t, bg_color);
anim_ctr++;
image

Note the playable character marked as a "@" in the centre of the screen. To move the character in a game loop, use function update() to allow keystrokes to be registered. Then control the character by pressing the ASWD keys. Press space-bar to open and close doors that you are located next to.


// Declarations
dung::BSPTree bsp_tree { 4 }; // argument: `min_room_length = 4`.
dung::DungGineTextureParams texture_params;
std::unique_ptr<dung::DungGine> dungeon_engine;
Text t;
SpriteHandler<NR, NC> sh;
Color bg_color = Color::Black;
int anim_ctr = 0;

// Initializations
bsp_tree.generate(200, 400, dung::Orientation::Vertical); // arguments: world_size_rows, world_size_cols,
                  first_split_orientation.
bsp_tree.pad_rooms(4); // arguments: min_rnd_wall_padding = 4, [max_rnd_wall_padding = 4].
bsp_tree.create_corridors(1); // argument: min_corridor_half_width = 1, (1 means it will be three chars wide).
bsp_tree.create_doors(100, true); // We also create doors here. Arguments: max_num_locked_doors, allow_passageways.

texture_params.dt_anim_s = 0.5;
auto f_tex_path = [](const auto& filename)
{
  return folder::join_path({ "textures", filename });
};
texture_params.texture_file_names_surface_level_fill.emplace_back(f_tex_path("texture_sl_fill_0.tex"));
texture_params.texture_file_names_surface_level_fill.emplace_back(f_tex_path("texture_sl_fill_1.tex"));
texture_params.texture_file_names_surface_level_shadow.emplace_back(f_tex_path("texture_sl_shadow_0.tex"));
texture_params.texture_file_names_surface_level_shadow.emplace_back(f_tex_path("texture_sl_shadow_1.tex"));

dungeon_engine = std::make_unique<dung::DungGine>(get_exe_folder(), true, texture_params); // arguments: exe_folder, use_fow, texture_params.
dungeon_engine.load_dungeon(&bsp_tree);
dungeon_engine.configure_sun_rand(20.f, 120.f, dung::Latitude::Equator, dung::Longitude::F, true); // 20 minutes per day and 120 minutes per year. Localized shadows across the map starting at Equator & Front.
dungeon_engine.style_dungeon();
if (!dungeon_engine.place_player(sh.size()))
  std::cerr << "ERROR : Unable to place the playable character!" << std::endl;
dungeon_engine->place_keys(true);
dungeon_engine->place_lamps(20, 15, 5, true);
dungeon_engine->place_weapons(150, true);
dungeon_engine->place_potions(150, true);
dungeon_engine->place_armour(150, true);
dungeon_engine->place_npcs(100, false);
dungeon_engine.set_screen_scrolling_mode(ScreenScrollingMode::WhenOutsideScreen);

// In game loop:
sh.clear();
bool game_over = false;
dungeon_engine->update(get_real_time_s(), get_sim_time_s(), get_sim_time_dt(), kpd, &game_over); // arg0 : time from game start, arg3 : keyboard::KeyPressData object, arg4 : retrieves game over state.
if (game_over)
  set_state_game_over();
dungeon_engine->draw(sh, get_real_time_s(), get_sim_time_s(), anim_ctr, ui::VerticalAlignment::BOTTOM, ui::HorizontalAlignment::CENTER, -5, 0, false, true);
sh.print_screen_buffer(t, bg_color);
anim_ctr++;