#include "Graphics.hh"
#include "GameState.hh"
#include <cmath>
#include <sstream>
Graphics::Graphics (Engine &engine, GameState &state) :
CL_DisplayWindow(GRAPHICS_WINDOW_TITLE, GRAPHICS_RESOLUTION_WIDTH, GRAPHICS_RESOLUTION_HEIGHT),
engine(engine),
state(state),
resolution(GRAPHICS_RESOLUTION_WIDTH, GRAPHICS_RESOLUTION_HEIGHT),
update_timer(GRAPHICS_UPDATE_INTERVAL_MS),
input(get_ic()->get_keyboard()),
simple_font("Font2", engine.getResourceManager())
{
// connect timer signal
slots.connect(update_timer.sig_tick(), this, &Graphics::on_update);
// enable
update_timer.start();
}
void Graphics::check_input (void) {
LocalPlayer *player;
PlayerInput input_mask;
TimeMS input_dt;
// update gui flags
this->flags = input.readGuiInput();
// quit?
if (flags & GUI_INPUT_QUIT) {
engine.stop();
return;
}
// stop here if we don't have a local player
if ((player = state.getLocalPlayer()) == NULL)
return;
// dump debug info on stderr
if (flags & GUI_INPUT_DEBUG_PLAYER)
player->printDebugInfo();
// build input_mask
input.readPlayerInput(input_mask, input_dt);
// apply input if there was any
if (input_mask)
player->handleInput(input_mask, input_dt);
}
static PixelDimension value_between (PixelDimension low, PixelDimension value, PixelDimension high) {
if (high < low)
return (high + low) / 2;
else if (value < low)
return low;
else if (value > high)
return high;
else
return value;
}
void Graphics::do_redraw (void) {
CL_GraphicContext *gc = get_gc();
LocalPlayer *player;
// calculate camera
PixelCoordinate camera(0, 0);
// ...to track our local player
if ((player = state.getLocalPlayer()) != NULL) {
PixelCoordinate target = player->getCoordinate() - PixelCoordinate(resolution.x / 2, (resolution.y - 100) / 2);
PixelCoordinate max = state.world.getDimensions() - resolution + PixelCoordinate(0, 100);
// keep the terrain in view
camera = PixelCoordinate(
value_between(0, target.x, max.x),
value_between(0, target.y, max.y)
);
}
// Black background
gc->clear(CL_Color::black);
// Draw the game
state.draw(this, camera, flags & GUI_INPUT_DISPLAY_WEAPON);
// Draw box for player information
if (player != NULL) {
draw_player_info(gc, (Player*)player);
}
// Flip window buffer, sync
flip(1);
}
void Graphics::on_update (TimeMS tick_length) {
(void) tick_length;
// check keyboard input
check_input();
// redraw display
do_redraw();
}
void Graphics::draw_player_info(CL_GraphicContext *gc, Player *p) {
int box_top = GRAPHICS_RESOLUTION_HEIGHT - 100;
int box_left = 0;
int box_right = GRAPHICS_RESOLUTION_WIDTH;
int box_bottom = GRAPHICS_RESOLUTION_HEIGHT;
int bar_length = 3; // *100
// draw status info at bottom of display
gc->fill_rect(
CL_Rect(
box_left,
box_top,
box_right,
box_bottom
),
CL_Gradient(
CL_Color(0, 0, 0),
CL_Color(50, 50, 50),
CL_Color(50, 50, 50, 150),
CL_Color(100, 100, 100, 200)
)
);
// Lifebar
gc->draw_rect(
CL_Rect(
box_left + 9,
box_top + 9,
box_left + 11 + 100 * bar_length,
box_top + 31
),
CL_Color(150, 150, 150)
);
gc->fill_rect(
CL_Rect(
box_left + 10,
box_top + 10,
box_left + 10 + (int) (p->getHealthPercent() * bar_length),
box_top + 30
),
CL_Gradient(
CL_Color(200, 0, 0),
CL_Color(200 - (int)(p->getHealthPercent() * 2), (int)(p->getHealthPercent() * 2), 0),
CL_Color(200, 0, 0),
CL_Color(200 - (int)(p->getHealthPercent() * 2), (int)(p->getHealthPercent() * 2), 0)
)
);
std::stringstream sskills;
sskills << "Kills: " << p->getKills();
getSimpleFont().draw(
box_left + 20 + 100 * bar_length,
box_top + 10,
sskills.str(),
get_gc()
);
std::stringstream ssdeaths;
ssdeaths << "Deaths: " << p->getDeaths();
getSimpleFont().draw(
box_left + 20 + 100 * bar_length,
box_top + 30,
ssdeaths.str(),
get_gc()
);
std::stringstream ssratio;
ssratio << "Ratio: " << (p->getKills()+1) / (p->getDeaths()+1);
getSimpleFont().draw(
box_left + 20 + 100 * bar_length,
box_top + 50,
ssratio.str(),
get_gc()
);
// Ammobar
gc->draw_rect(
CL_Rect(
box_left + 9,
box_top + 69,
box_left + 11 + 100 * bar_length,
box_top + 91
),
CL_Color(150, 150, 150)
);
gc->fill_rect(
CL_Rect(
box_left + 10,
box_top + 70,
box_left + 10 + (100 - (int) (p->getCurrentWeapon()->getReloadTimer() * 100 / p->getCurrentWeapon()->getReloadTime())) * bar_length,
box_top + 90
),
CL_Gradient(
CL_Color(100, 100, 0),
CL_Color(100, 100, 0),
CL_Color(100, 100, 0),
CL_Color(100, 100, 100)
)
);
getSimpleFont().draw(
box_left + 20 + 100 * bar_length,
box_top + 70,
p->getCurrentWeapon()->getName(),
get_gc()
);
}