GUI
This commit is contained in:
parent
7d6094a049
commit
cefeacdae9
7
Ai.cpp
7
Ai.cpp
@ -5,6 +5,7 @@
|
||||
#include "Map.h"
|
||||
#include "Destructible.h"
|
||||
#include "Attacker.h"
|
||||
#include "Gui.h"
|
||||
|
||||
void PlayerAi::update(Actor* owner) {
|
||||
SDL_Event event;
|
||||
@ -25,6 +26,10 @@ void PlayerAi::update(Actor* owner) {
|
||||
while (SDL_PollEvent(&event)) {
|
||||
engine->context->convert_event_coordinates(event);
|
||||
switch (event.type) {
|
||||
case SDL_EVENT_MOUSE_MOTION:
|
||||
engine->mouse.cx = event.motion.x;
|
||||
engine->mouse.cy = event.motion.y;
|
||||
break;
|
||||
case SDL_EVENT_KEY_DOWN:
|
||||
switch (event.key.key) {
|
||||
case SDLK_UP:
|
||||
@ -76,7 +81,7 @@ bool PlayerAi::moveOrAttack(Actor* owner, int targetx, int targety) {
|
||||
Actor* actor = *iterator;
|
||||
if (actor->destructible && actor->destructible->isDead()
|
||||
&& actor->x == targetx && actor->y == targety) {
|
||||
printf("There's a %s here\n", actor->name.c_str());
|
||||
engine->gui->message(TCOD_ColorRGB(150,150,150), "There's a %s here\n", actor->name.c_str());
|
||||
}
|
||||
}
|
||||
owner->x = targetx;
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include "Attacker.h"
|
||||
#include "Actor.h"
|
||||
#include "Destructible.h"
|
||||
#include "Engine.h"
|
||||
#include "Gui.h"
|
||||
|
||||
Attacker::Attacker(float power) : power(power) {
|
||||
}
|
||||
@ -8,15 +10,15 @@ Attacker::Attacker(float power) : power(power) {
|
||||
void Attacker::attack(Actor* owner, Actor* target) {
|
||||
if (target->destructible && !target->destructible->isDead()) {
|
||||
if (power - target->destructible->defense > 0) {
|
||||
printf("%s attacks %s for %g hit points.\n", owner->name.c_str(), target->name.c_str(),
|
||||
engine->gui->message(TCOD_ColorRGB(150, 150, 150), "%s attacks %s for %g hit points.\n", owner->name.c_str(), target->name.c_str(),
|
||||
power - target->destructible->defense);
|
||||
}
|
||||
else {
|
||||
printf("%s attacks %s but it has no effect!\n", owner->name.c_str(), target->name.c_str());
|
||||
engine->gui->message(TCOD_ColorRGB(150, 150, 150), "%s attacks %s but it has no effect!\n", owner->name.c_str(), target->name.c_str());
|
||||
}
|
||||
target->destructible->takeDamage(target, power);
|
||||
}
|
||||
else {
|
||||
printf("%s attacks %s in vain.\n", owner->name.c_str(), target->name.c_str());
|
||||
engine->gui->message(TCOD_ColorRGB(150, 150, 150), "%s attacks %s in vain.\n", owner->name.c_str(), target->name.c_str());
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ project ("ADG5")
|
||||
find_package(libtcod CONFIG REQUIRED)
|
||||
|
||||
# Add source to this project's executable.
|
||||
add_executable (ADG5 "ADG5.cpp" "ADG5.h" "Actor.cpp" "Actor.h" "Map.h" "Map.cpp" "Engine.h" "Engine.cpp" "Destructible.h" "Destructible.cpp" "Attacker.h" "Attacker.cpp" "Ai.h" "Ai.cpp")
|
||||
add_executable (ADG5 "ADG5.cpp" "ADG5.h" "Actor.cpp" "Actor.h" "Map.h" "Map.cpp" "Engine.h" "Engine.cpp" "Destructible.h" "Destructible.cpp" "Attacker.h" "Attacker.cpp" "Ai.h" "Ai.cpp" "Gui.h" "Gui.cpp")
|
||||
|
||||
target_link_libraries(ADG5
|
||||
PRIVATE
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "Destructible.h"
|
||||
#include "Actor.h"
|
||||
#include "Engine.h"
|
||||
#include "Gui.h"
|
||||
|
||||
Destructible::Destructible(float maxHp, float defense, std::string corpseName) :
|
||||
maxHp(maxHp), hp(maxHp), defense(defense), corpseName(corpseName) {
|
||||
@ -41,12 +42,12 @@ PlayerDestructible::PlayerDestructible(float maxHp, float defense, std::string c
|
||||
void MonsterDestructible::die(Actor* owner) {
|
||||
// transform it into a nasty corpse! it doesn't block, can't be
|
||||
// attacked and doesn't move
|
||||
printf("%s is dead\n", owner->name.c_str());
|
||||
engine->gui->message(TCOD_ColorRGB(150, 150, 150), "%s is dead\n", owner->name.c_str());
|
||||
Destructible::die(owner);
|
||||
}
|
||||
|
||||
void PlayerDestructible::die(Actor* owner) {
|
||||
printf("You died!\n");
|
||||
engine->gui->message(TCOD_ColorRGB(150, 0, 0), "You died!\n");
|
||||
Destructible::die(owner);
|
||||
engine->gameStatus = Engine::DEFEAT;
|
||||
}
|
14
Engine.cpp
14
Engine.cpp
@ -6,13 +6,14 @@
|
||||
#include "Destructible.h"
|
||||
#include "Attacker.h"
|
||||
#include "Ai.h"
|
||||
#include "Gui.h"
|
||||
|
||||
Engine::Engine(int screenWidth, int screenHeight, tcod::Context *context, tcod::Console *console) {
|
||||
this->context = context;
|
||||
this->console = console;
|
||||
this->screenWidth = screenWidth;
|
||||
this->screenHeight = screenHeight;
|
||||
|
||||
gui = nullptr;
|
||||
map = nullptr;
|
||||
player = nullptr;
|
||||
fovRadius = 10;
|
||||
@ -21,24 +22,26 @@ Engine::Engine(int screenWidth, int screenHeight, tcod::Context *context, tcod::
|
||||
}
|
||||
|
||||
void Engine::init() {
|
||||
|
||||
gui = new Gui(context, console);
|
||||
player = new Actor(40, 25, "@", "player", TCOD_ColorRGB(255, 255, 255));
|
||||
player->destructible = new PlayerDestructible(30, 2, "player corpse");
|
||||
player->attacker = new Attacker(5);
|
||||
player->ai = new PlayerAi();
|
||||
actors.push(player);
|
||||
map = new Map(80, 45);
|
||||
gui->message(TCOD_ColorRGB(150,0,0),
|
||||
"Welcome stranger!\nPrepare to perish in the Tombs Andrew's Dunegon Game.");
|
||||
}
|
||||
|
||||
Engine::~Engine() {
|
||||
actors.clearAndDelete();
|
||||
delete map;
|
||||
delete gui;
|
||||
}
|
||||
|
||||
bool Engine::update() {
|
||||
if (gameStatus == STARTUP) map->computeFov();
|
||||
gameStatus = IDLE;
|
||||
|
||||
player->update();
|
||||
if (gameStatus == NEW_TURN) {
|
||||
for (Actor** iterator = actors.begin(); iterator != actors.end();
|
||||
@ -69,10 +72,7 @@ void Engine::render() {
|
||||
}
|
||||
}
|
||||
player->render(*console);
|
||||
|
||||
std::string hp = "HP : " + std::to_string(player->destructible->hp) + "/" + std::to_string(player->destructible->maxHp);
|
||||
|
||||
tcod::print(*console, { 1, 1 }, hp, TCOD_ColorRGB(255, 255, 255), std::nullopt);
|
||||
gui->render();
|
||||
context->present(*console);
|
||||
}
|
||||
|
||||
|
4
Engine.h
4
Engine.h
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
class Actor;
|
||||
class Map;
|
||||
class Gui;
|
||||
|
||||
#include "libtcod.hpp"
|
||||
|
||||
@ -17,10 +18,11 @@ public:
|
||||
|
||||
int screenWidth;
|
||||
int screenHeight;
|
||||
|
||||
TCOD_mouse_t mouse;
|
||||
TCODList<Actor*> actors;
|
||||
Actor* player;
|
||||
Map* map;
|
||||
Gui* gui;
|
||||
int fovRadius;
|
||||
tcod::Context *context;
|
||||
tcod::Console* console;
|
||||
|
118
Gui.cpp
Normal file
118
Gui.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
#include "Gui.h"
|
||||
#include "Engine.h"
|
||||
#include "Actor.h"
|
||||
#include "Map.h"
|
||||
#include "Destructible.h"
|
||||
|
||||
static const int PANEL_HEIGHT = 7;
|
||||
static const int BAR_WIDTH = 20;
|
||||
static const int MSG_X = BAR_WIDTH + 2;
|
||||
static const int MSG_HEIGHT = PANEL_HEIGHT - 1;
|
||||
|
||||
Gui::Gui(tcod::Context *ctx, tcod::Console *root) {
|
||||
con = ctx->new_console(engine->screenWidth, PANEL_HEIGHT);
|
||||
this->root = root;
|
||||
}
|
||||
|
||||
Gui::~Gui() {
|
||||
log.clearAndDelete();
|
||||
}
|
||||
|
||||
void Gui::render() {
|
||||
// clear the GUI console
|
||||
con.clear();
|
||||
renderBar(1, 1, BAR_WIDTH, "HP", engine->player->destructible->hp,
|
||||
engine->player->destructible->maxHp,
|
||||
TCOD_ColorRGB(255,100,100), TCOD_ColorRGB(100, 0, 0));
|
||||
|
||||
// draw the message log
|
||||
int y = 1;
|
||||
float colorCoef = 0.4f;
|
||||
for (Message** it = log.begin(); it != log.end(); it++) {
|
||||
Message* message = *it;
|
||||
tcod::print(con, { MSG_X, y }, message->text, TCOD_ColorRGB(message->col.r * colorCoef, message->col.g * colorCoef, message->col.b * colorCoef), std::nullopt);
|
||||
y++;
|
||||
if (colorCoef < 1.0f) {
|
||||
colorCoef += 0.3f;
|
||||
}
|
||||
}
|
||||
renderMouseLook();
|
||||
tcod::blit(*root, con, { 0, engine->screenHeight - PANEL_HEIGHT }, { 0, 0, engine->screenWidth, PANEL_HEIGHT });
|
||||
}
|
||||
|
||||
void Gui::renderBar(int x, int y, int width, std::string name,
|
||||
float value, float maxValue, const TCOD_ColorRGB& barColor,
|
||||
const TCOD_ColorRGB& backColor) {
|
||||
|
||||
tcod::draw_rect(con, { x, y, width, 1 }, ' ', std::nullopt, backColor);
|
||||
|
||||
int barWidth = (int)(value / maxValue * width);
|
||||
if (barWidth > 0) {
|
||||
// draw the bar
|
||||
tcod::draw_rect(con, { x, y, barWidth, 1 }, ' ', std::nullopt, barColor);
|
||||
}
|
||||
|
||||
tcod::print(con, { x + width / 2, y }, name + " : " + std::to_string((int)value) + "/" + std::to_string((int)maxValue), TCOD_ColorRGB(255, 255, 255), std::nullopt);
|
||||
}
|
||||
|
||||
Gui::Message::Message(std::string text, const TCOD_ColorRGB& col) :
|
||||
text(text), col(col) {
|
||||
}
|
||||
|
||||
Gui::Message::~Message() {
|
||||
|
||||
}
|
||||
|
||||
void Gui::message(const TCOD_ColorRGB& col, const char* text, ...) {
|
||||
// build the text
|
||||
va_list ap;
|
||||
char buf[128];
|
||||
va_start(ap, text);
|
||||
vsprintf(buf, text, ap);
|
||||
va_end(ap);
|
||||
|
||||
char* lineBegin = buf;
|
||||
char* lineEnd;
|
||||
|
||||
if (buf[strlen(buf) - 1] == '\n') buf[strlen(buf) - 1] = '\0';
|
||||
|
||||
do {
|
||||
// make room for the new message
|
||||
if (log.size() == MSG_HEIGHT) {
|
||||
Message* toRemove = log.get(0);
|
||||
log.remove(toRemove);
|
||||
delete toRemove;
|
||||
}
|
||||
lineEnd = strchr(lineBegin, '\n');
|
||||
if (lineEnd) {
|
||||
*lineEnd = '\0';
|
||||
}
|
||||
Message* msg = new Message(lineBegin, col);
|
||||
log.push(msg);
|
||||
|
||||
// go to next line
|
||||
lineBegin = lineEnd + 1;
|
||||
} while (lineEnd);
|
||||
}
|
||||
void Gui::renderMouseLook() {
|
||||
if (!engine->map->isInFov(engine->mouse.cx, engine->mouse.cy)) {
|
||||
// if mouse is out of fov, nothing to render
|
||||
return;
|
||||
}
|
||||
char buf[128] = "";
|
||||
bool first = true;
|
||||
for (Actor** it = engine->actors.begin(); it != engine->actors.end(); it++) {
|
||||
Actor* actor = *it;
|
||||
// find actors under the mouse cursor
|
||||
if (actor->x == engine->mouse.cx && actor->y == engine->mouse.cy) {
|
||||
if (!first) {
|
||||
strcat(buf, ", ");
|
||||
}
|
||||
else {
|
||||
first = false;
|
||||
}
|
||||
strcat(buf, actor->name.c_str());
|
||||
}
|
||||
}
|
||||
tcod::print(con, { 1, 0 }, buf, TCOD_ColorRGB(200, 200, 200), std::nullopt);
|
||||
}
|
27
Gui.h
Normal file
27
Gui.h
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include "libtcod.hpp"
|
||||
|
||||
class Gui {
|
||||
public:
|
||||
Gui(tcod::Context *ctx, tcod::Console *root);
|
||||
~Gui();
|
||||
void render();
|
||||
void message(const TCOD_ColorRGB& col, const char* text, ...);
|
||||
|
||||
protected:
|
||||
tcod::Console con;
|
||||
tcod::Console* root;
|
||||
void renderBar(int x, int y, int width, std::string name,
|
||||
float value, float maxValue, const TCOD_ColorRGB& barColor,
|
||||
const TCOD_ColorRGB& backColor);
|
||||
void renderMouseLook();
|
||||
struct Message {
|
||||
std::string text;
|
||||
TCOD_ColorRGB col;
|
||||
Message(std::string text, const TCOD_ColorRGB& col);
|
||||
~Message();
|
||||
};
|
||||
|
||||
TCODList<Message*> log;
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user