Exploring raycasters and possibly make a little "doom like" game based on it.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
raycaster/boss_fight_ui.cpp

129 lines
3.7 KiB

#include "boss_fight_ui.hpp"
#include "easings.hpp"
#include "sound.hpp"
namespace gui {
BossFightUI::BossFightUI(GameLevel level)
: $level(level)
{
$status.position(0, 0, 300, SCREEN_HEIGHT);
$status.layout(
"[main_status]"
"[(150)status_3|(150)status_4]"
"[(150)status_5|(150)status_6]"
"[(150)status_7|(150)status_8]"
);
$overlay.position(300, 0, SCREEN_WIDTH - 300, SCREEN_HEIGHT);
$overlay.layout("[overlay_1|overlay_2|overlay_4]"
"[overlay_5|overlay_6|overlay_8]"
"[overlay_9|overlay_10|overlay_12]"
"[overlay_13|overlay_14|overlay_16]");
$boss_background = textures::get("boss_fight_background");
auto bg_bounds = $boss_background.sprite->getLocalBounds();
$boss_background.sprite->setPosition({300, 0});
$boss_image = textures::get("rat_king_boss");
sf::IntRect frame_rect{{0,0},{720,720}};
$boss_image.sprite->setTextureRect(frame_rect);
$boss_image.sprite->setScale($scale);
auto bounds = $boss_image.sprite->getLocalBounds();
float x_diff = bg_bounds.size.x / 2;
$boss_image.sprite->setOrigin({bounds.size.x / 2, bounds.size.y / 2});
$boss_image.sprite->setPosition({300.0f + x_diff, bounds.size.y / 2});
}
void BossFightUI::init() {
auto& config = $level.world->get_the<components::GameConfig>();
$sounds = components::get<components::Sound>(config.enemies["RAT_KING"]);
$animation = components::get<components::Animation>(config.enemies["RAT_KING"]);
$animation.texture_width = 720;
$status.world().set_the<Background>({$status.$parser});
for(auto& [name, cell] : $status.cells()) {
auto button = $status.entity(name);
$status.set<Rectangle>(button, {});
$status.set<Clickable>(button, {
[this, name](auto, auto){ fmt::println("STATUS: {}", name); }
});
if(name == "main_status") {
$status.set<Textual>(button, {fmt::format("HP: {}", $boss_hp)});
} else {
$status.set<Label>(button, {"Attack"});
}
}
$status.init();
for(auto& [name, cell] : $overlay.cells()) {
auto region = $overlay.entity(name);
$overlay.set<Clickable>(region, {
[this, name](auto, auto){ fmt::println("OVERLAY: {}", name); }
});
}
$overlay.init();
}
void BossFightUI::bounce_boss(sf::RenderWindow& window) {
sf::IntRect frame_rect{{0,0},{720,720}};
auto scale = $scale;
$animation.step(scale, frame_rect);
$boss_image.sprite->setScale(scale);
if(!sound::playing($sounds.attack) && $animation.current == 1) {
sound::play($sounds.attack);
}
if(!sound::playing("Sword_Hit_2") && $animation.subframe > 1.2 && $animation.subframe < 1.5) {
sound::play("Sword_Hit_2");
}
$boss_image.sprite->setTextureRect(frame_rect);
window.draw(*$boss_image.sprite);
}
void BossFightUI::render(sf::RenderWindow& window) {
window.draw(*$boss_background.sprite);
if($boss_hit) {
bounce_boss(window);
} else {
window.draw(*$boss_image.sprite);
}
if($boss_hp == 0) {
$overlay.show_label("overlay_1", "YOU WON!");
$overlay.show_label("overlay_4", "CLICK TO CONTINUE...");
}
$status.render(window);
$overlay.render(window);
}
bool BossFightUI::mouse(float x, float y) {
if($status.mouse(x, y)) {
fmt::println("STATUS");
}
if($overlay.mouse(x, y)) {
$animation.play();
sound::play("Sword_Hit_1");
$boss_hit = !$boss_hit;
$boss_hp--;
}
return false;
}
void BossFightUI::update_level(GameLevel &level) {
$level = level;
$boss_hp = 10 * $level.index + 1; // make him stronger
$boss_hit = false;
$overlay.close<Label>("overlay_1");
$overlay.close<Label>("overlay_4");
init();
}
}