--- a/src/Config.hh Tue Jan 13 21:36:43 2009 +0200
+++ b/src/Config.hh Tue Jan 13 23:15:47 2009 +0200
@@ -119,6 +119,10 @@
const uint16_t GRAPHICS_UPDATE_INTERVAL_MS = 20;
const bool GRAPHICS_FULLSCREEN = false;
+/**
+ * Number of pixels between lines
+ */
+const PixelDimension GRAPHICS_INFO_TEXT_LINE_OFFSET = 5;
// Filesystem paths
const std::string PLAYER_SKIN_PATH = (PROJECT_DATA_DIR "/skin.png");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/GameMessageView.cc Tue Jan 13 23:15:47 2009 +0200
@@ -0,0 +1,56 @@
+
+#include "GameMessageView.hh"
+#include "Graphics.hh"
+#include "Engine.hh"
+
+GameMessageView::GameMessageView (PixelArea area) :
+ area(area), messages()
+{
+
+}
+
+void GameMessageView::add_message (CL_Color color, std::string message) {
+ GameMessage msg (color, message);
+
+ messages.push_back(msg);
+}
+
+void GameMessageView::draw (Graphics *g) {
+ // get font
+ CL_Font &font = g->getSimpleFont();
+
+ // remember color
+ CL_Color font_color = font.get_color();
+
+ // maximum width
+ CL_Size max_size = CL_Size(area.right - area.left, 0);
+
+ // starting point for drawing
+ PixelDimension offset_prev = area.bottom;
+
+ // render messages, bottom up
+ for (std::vector<GameMessage>::reverse_iterator it = messages.rbegin(); it != messages.rend(); it++) {
+ // set message color
+ font.set_color(it->color);
+
+ // calculate height
+ PixelDimension height = font.get_height(it->message, max_size) + GRAPHICS_INFO_TEXT_LINE_OFFSET;
+
+ // new draw_point
+ PixelDimension offset_this = offset_prev - height;
+
+ // break if it doesn't fit anymore
+ if (offset_this < area.top)
+ break;
+
+ // draw text
+ font.draw(CL_Rect(area.left, offset_this, area.right, offset_prev), it->message, g->get_gc());
+
+ // advance offset
+ offset_prev = offset_this;
+ }
+
+ // restore font color
+ font.set_color(font_color);
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/GameMessageView.hh Tue Jan 13 23:15:47 2009 +0200
@@ -0,0 +1,42 @@
+#ifndef GRAPHICS_INFO_TEXT_HH
+#define GRAPHICS_INFO_TEXT_HH
+
+#include "GraphicsPointer.hh"
+#include "Types.hh"
+
+#include <string>
+#include <vector>
+#include <ClanLib/display.h>
+
+struct GameMessage {
+ CL_Color color;
+ std::string message;
+
+ GameMessage (CL_Color color, std::string message) : color(color), message(message) { }
+ GameMessage (const GameMessage ©) : color(copy.color), message(copy.message) { }
+ GameMessage &operator= (const GameMessage ©) { color = copy.color; message = copy.message; return *this; }
+};
+
+class GameMessageView {
+ protected:
+ PixelArea area;
+ std::vector<GameMessage> messages;
+
+ public:
+ /**
+ * Define the area where messages are drawn
+ */
+ GameMessageView (PixelArea area);
+
+ /**
+ * Add a message to the list of messages displayed
+ */
+ void add_message (CL_Color color, std::string message);
+
+ /**
+ * Draw as many messages as fits
+ */
+ void draw (Graphics *g);
+};
+
+#endif
--- a/src/GameState.cc Tue Jan 13 21:36:43 2009 +0200
+++ b/src/GameState.cc Tue Jan 13 23:15:47 2009 +0200
@@ -4,10 +4,17 @@
#include "Config.hh"
GameState::GameState (void) :
- world(Vector(0, MAP_GRAVITY), Vector(MAP_WIDTH, MAP_HEIGHT)), local_player(NULL)
+ world(Vector(0, MAP_GRAVITY), Vector(MAP_WIDTH, MAP_HEIGHT)), local_player(NULL), event_handler(NULL)
{
}
+
+void GameState::setEventHandler (GameStateEventHandler *handler) {
+ if (handler && event_handler != NULL)
+ throw Error("event_handler already set");
+
+ event_handler = handler;
+}
void GameState::addProjectile (Projectile *projectile) {
projectiles.push_back(projectile);
@@ -26,6 +33,9 @@
void GameState::addPlayer (Player *player) {
player_list.push_back(player);
+
+ if (event_handler)
+ event_handler->on_player_joined(player);
}
void GameState::removePlayer (Player *player) {
@@ -33,6 +43,9 @@
local_player = NULL;
player_list.remove(player);
+
+ if (event_handler)
+ event_handler->on_player_left(player);
}
void GameState::draw(Graphics *g, PixelCoordinate camera, bool displayWeapon) {
--- a/src/GameState.hh Tue Jan 13 21:36:43 2009 +0200
+++ b/src/GameState.hh Tue Jan 13 23:15:47 2009 +0200
@@ -15,6 +15,14 @@
#include <stdexcept>
#include <cmath>
+class GameStateEventHandler {
+ friend class GameState;
+
+ protected:
+ virtual void on_player_joined (Player *p) = 0;
+ virtual void on_player_left (Player *p) = 0;
+};
+
class GameState {
public:
std::list<Player*> player_list;
@@ -26,12 +34,24 @@
*/
LocalPlayer *local_player;
+protected:
+ /**
+ * Notify someone about events?
+ */
+ GameStateEventHandler *event_handler;
+
+public:
/**
* ...
*
* This should take some arguments
*/
GameState (void);
+
+ /**
+ * Set event handler, only one can be set
+ */
+ void setEventHandler (GameStateEventHandler *handler);
/**
* Adds projectile to our list of projectiles to draw
--- a/src/Graphics.cc Tue Jan 13 21:36:43 2009 +0200
+++ b/src/Graphics.cc Tue Jan 13 23:15:47 2009 +0200
@@ -4,6 +4,18 @@
#include <cmath>
#include <sstream>
+/*
+ * XXX: until we figure out a better way to layout stuff
+ */
+static PixelArea getMessageViewArea (PixelCoordinate resolution) {
+ return PixelArea(
+ 400,
+ resolution.y - 100,
+ resolution.x,
+ resolution.y
+ );
+}
+
Graphics::Graphics (Engine &engine, GameState &state, PixelCoordinate resolution, bool fullscreen) :
CL_DisplayWindow(GRAPHICS_WINDOW_TITLE, resolution.x, resolution.y, fullscreen),
engine(engine),
@@ -11,7 +23,8 @@
resolution(resolution),
update_timer(GRAPHICS_UPDATE_INTERVAL_MS),
input(get_ic()->get_keyboard()),
- simple_font("Font2", engine.getResourceManager())
+ simple_font("Font2", engine.getResourceManager()),
+ message_view(getMessageViewArea(resolution))
{
// connect timer signal
@@ -19,6 +32,12 @@
// enable
update_timer.start();
+
+ // push something to message_view
+ message_view.add_message(CL_Color::white, "Hello World");
+
+ // GameState events....
+ state.setEventHandler(this);
}
const std::vector<CL_DisplayMode> & Graphics::getDisplayModes (void) {
@@ -75,8 +94,11 @@
}
// dump player debug info on stderr
- if ((flags & GUI_INPUT_DEBUG_PLAYER) && state.getLocalPlayer())
+ if ((flags & GUI_INPUT_DEBUG_PLAYER) && state.getLocalPlayer()) {
state.getLocalPlayer()->printDebugInfo();
+
+ message_view.add_message(CL_Color::green, "...");
+ }
// toggle fullscreen?
if (flags & GUI_INPUT_TOGGLE_FULLSCREEN) {
@@ -128,11 +150,14 @@
// Draw the game
state.draw(this, camera, flags & GUI_INPUT_DISPLAY_WEAPON);
-
+
+ // draw player info box
if (player != NULL) {
- // draw player info box
draw_player_info(gc, player);
}
+
+ // draw messages
+ message_view.draw(this);
// Flip window buffer, sync
flip(1);
@@ -261,5 +286,14 @@
p->getCurrentWeapon()->getName(),
get_gc()
);
+
}
+
+void Graphics::on_player_joined (Player *p) {
+ message_view.add_message(CL_Color::white, " *** Player joined");
+}
+
+void Graphics::on_player_left (Player *p) {
+ message_view.add_message(CL_Color::white, " *** Player left");
+}
--- a/src/Graphics.hh Tue Jan 13 21:36:43 2009 +0200
+++ b/src/Graphics.hh Tue Jan 13 23:15:47 2009 +0200
@@ -9,6 +9,8 @@
#include "Engine.hh"
#include "Config.hh"
+#include "GameMessageView.hh"
+
#include <ClanLib/core.h>
#include <ClanLib/gl.h>
#include <ClanLib/display.h>
@@ -17,7 +19,7 @@
* This handles drawing the GameState with an appropriate camera view each frame, loading fonts, and currently,
* handling the input from Input to GameState.
*/
-class Graphics : public CL_DisplayWindow {
+class Graphics : public GameStateEventHandler, public CL_DisplayWindow {
private:
Engine &engine;
GameState &state;
@@ -36,6 +38,9 @@
// basic fonts
CL_Font simple_font;
+ // view components
+ GameMessageView message_view;
+
public:
Graphics (Engine &engine, GameState &state, PixelCoordinate resolution, bool fullscreen);
@@ -73,6 +78,11 @@
void on_update (TimeMS tick_length);
void draw_player_info(CL_GraphicContext *gc, Player *p);
+
+protected:
+ /* GameStateEventHandler */
+ virtual void on_player_joined (Player *p);
+ virtual void on_player_left (Player *p);
};
#endif /* GRAPHICS_HH */
--- a/src/Player.hh Tue Jan 13 21:36:43 2009 +0200
+++ b/src/Player.hh Tue Jan 13 23:15:47 2009 +0200
@@ -45,7 +45,7 @@
Timer respawn_timer;
CL_Slot respawn_slot;
- // XXX: hmm... updated where?
+ // XXX: updated where?
int animation_step;
//Player stats
--- a/src/Types.hh Tue Jan 13 21:36:43 2009 +0200
+++ b/src/Types.hh Tue Jan 13 23:15:47 2009 +0200
@@ -30,6 +30,17 @@
typedef VectorType<PixelDimension> PixelCoordinate;
/**
+ * A rectangular area of pixels
+ */
+struct PixelArea {
+ PixelDimension left, top, right, bottom;
+
+ PixelArea (PixelDimension left, PixelDimension top, PixelDimension right, PixelDimension bottom) :
+ left(left), top(top), right(right), bottom(bottom)
+ { }
+};
+
+/**
* A time interval, measured in real milliseconds
*/
typedef signed long TimeMS;