razterizer / DungGine

A dungeon engine for rogue-like style games.
MIT License
9 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 Static Badge Static Badge

build ubuntu build macos build ubuntu

Top Languages GitHub repo size Commit Activity Last Commit Contributors

image

Ubuntu WSL

ubuntu_QPClLlbOCK

Windows

demo vs_YSrQHcSQqu

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.

Features

There is no skill progression yet and underground rooms are currently mixed with surface-level rooms, so there are some things to improve on in the future. But it does feature:

and stuff like that. The corridors are all straight (for now). Other than that, I think the BSP generation is pretty standard. Items you can pick up are keys, torches, lanterns, magic lamps (isotropic light), potions (some contain poison, so gotta watch out), weapons and armour.

Keys

NPCs

There are a bunch of different NPCs and that have different behaviours. The following are supported:

They all look different visually and have different walking styles etc. Some can swim, some can fly, and some can only walk.

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.

Demo - Build and Run

Build by going to <my_source_code_dir>/DungGine/demo/ (preferrably <my_source_code_dir>/lib/DungGine/demo/) and build with build_demo.sh for Linux/MacOS or build_demo.bat for Windows.

Linux / MacOS

Then you run by typing bin/demo.

Windows

Then you run by cd to demo.vs followed by x64\Release\demo.

Alternatively, you can open the solution demo.vs/demo.vs.sln and build and run from there.

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).

ScreenHandler<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, 0);
sh.print_screen_buffer(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;
ScreenHandler<NR, NC> sh;
Color bg_color = Color::Black;
int anim_ctr = 0;
const float fire_smoke_dt_factor = 0.5f;

// 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_frame_count(), get_real_fps(), 
  get_real_time_s(), get_sim_time_s(), get_sim_dt_s(),
  fire_smoke_dt_factor,
  kpdp, &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(),
  get_anim_count(0), get_anim_count(1));
sh.print_screen_buffer(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;
ScreenHandler<NR, NC> sh;
Color bg_color = Color::Black;
int anim_ctr = 0;
const float fire_smoke_dt_factor = 0.5f;

// 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(100, 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_frame_count(), get_real_fps(),
  get_real_time_s(), get_sim_time_s(), get_sim_dt_s(),
  fire_smoke_dt_factor,
  kpdp, &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(),
  get_anim_count(0), get_anim_count(1),
  ui::VerticalAlignment::BOTTOM, ui::HorizontalAlignment::CENTER,
  -5, 0, false, true);
sh.print_screen_buffer(bg_color);
anim_ctr++;