summaryrefslogtreecommitdiff
path: root/source/presentation/GamePanel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/presentation/GamePanel.cpp')
-rw-r--r--source/presentation/GamePanel.cpp133
1 files changed, 133 insertions, 0 deletions
diff --git a/source/presentation/GamePanel.cpp b/source/presentation/GamePanel.cpp
new file mode 100644
index 0000000..71ef290
--- /dev/null
+++ b/source/presentation/GamePanel.cpp
@@ -0,0 +1,133 @@
+#include "GamePanel.h"
+
+GamePanel::GamePanel(ALLEGRO_BITMAP* back, ALLEGRO_BITMAP* front, int x, int y, int width, int height)
+ :ScreenPanel(back, front, x, y, width, height),
+ _mazeblockWidth(_width/BLOCKS_PER_ROW),
+ _offsetX(0),
+ _offsetY(0),
+ _bitmapStore(_mazeblockWidth)
+{
+}
+
+void GamePanel::draw(const Maze& maze, const list<PlayerCar>& players, const list<EnemyCar>& enemies, const list<Checkpoint>& checkpoints, const list<Rock>& rocks, const list<Smokescreen>& smokescreens, const list<DestroyedObjectPopup>& popups)
+{
+ ALLEGRO_BITMAP* prev_draw = al_get_target_bitmap();
+ al_set_target_bitmap(_back);
+
+ al_clear_to_color(BLANK);
+
+ float _maxOffsetX = getPanelX(maze.width()) - _width;
+ float _maxOffsetY = getPanelY(maze.height()) - _height;
+
+ if (!players.empty())
+ {
+ _offsetX = getPanelX(players.front().x()) - _width/2;
+ if (_offsetX < 0) _offsetX = 0;
+ else if (_offsetX > _maxOffsetX) _offsetX = _maxOffsetX;
+
+ _offsetY = getPanelY(players.front().y()) - _height/2;
+ if (_offsetY < 0) _offsetY = 0;
+ else if (_offsetY > _maxOffsetY) _offsetY = _maxOffsetY;
+ }
+
+ draw(maze);
+
+ for (list<PlayerCar>::const_iterator iter = players.begin(); iter != players.end(); ++iter)
+ {
+ draw(*iter);
+ }
+ for (list<EnemyCar>::const_iterator iter = enemies.begin(); iter != enemies.end(); ++iter)
+ {
+ draw(*iter);
+ }
+ for (list<Checkpoint>::const_iterator iter = checkpoints.begin(); iter != checkpoints.end(); ++iter)
+ {
+ draw(*iter);
+ }
+ for (list<Rock>::const_iterator iter = rocks.begin(); iter != rocks.end(); ++iter)
+ {
+ draw(*iter);
+ }
+ for (list<Smokescreen>::const_iterator iter = smokescreens.begin(); iter != smokescreens.end(); ++iter)
+ {
+ draw(*iter);
+ }
+ for (list<DestroyedObjectPopup>::const_iterator iter = popups.begin(); iter != popups.end(); ++iter)
+ {
+ draw(*iter);
+ }
+
+ al_set_target_bitmap(prev_draw);
+}
+
+void GamePanel::draw(const Maze& maze)
+{
+ //only draws a parts of the maze that would appear on the screen
+ int minX = floor((_offsetX-_mazeblockWidth)/_mazeblockWidth);
+ int maxX = ceil((_offsetX+_width)/_mazeblockWidth);
+ int minY = floor((_offsetY-_mazeblockWidth)/_mazeblockWidth);
+ int maxY = ceil((_offsetY+_height)/_mazeblockWidth);
+
+ ALLEGRO_BITMAP* wallBitmap = _bitmapStore.getBitmap(BitmapStore::MAZE_WALL);
+ ALLEGRO_BITMAP* floorBitmap = _bitmapStore.getBitmap(BitmapStore::MAZE_FLOOR);
+ //used to only have one al_draw_bitmap command
+ ALLEGRO_BITMAP* currentBitmap = floorBitmap;
+ for (int x=minX; x<maxX&&x<maze.width(); ++x)
+ {
+ for (int y=minY; y<maxY&&y<maze.height(); ++y)
+ {
+ if (maze.getSolid(x,y))
+ {
+ currentBitmap = wallBitmap;
+ }
+ else
+ {
+ currentBitmap = floorBitmap;
+ }
+ al_draw_bitmap(currentBitmap, getPanelX(x)-_offsetX, getPanelY(y)-_offsetY, 0);
+ }
+ }
+}
+
+void GamePanel::draw(const GameObject& object)
+{
+ //only draws a gameobject if it would appear on the screen
+ if (object.x() < (_offsetX-_mazeblockWidth)/_mazeblockWidth) return;
+ if (object.x() > (_offsetX+_width)/_mazeblockWidth) return;
+ if (object.y() < (_offsetY-_mazeblockWidth)/_mazeblockWidth) return;
+ if (object.y() > (_offsetY+_height)/_mazeblockWidth) return;
+
+ ALLEGRO_BITMAP* bitmap = _bitmapStore.getBitmap(object.image());
+
+ float angle = 0;
+ switch(object.facing())
+ {
+ case Maze::UP:
+ angle = 0;
+ break;
+ case Maze::RIGHT:
+ angle = ALLEGRO_PI/2;
+ break;
+ case Maze::DOWN:
+ angle = ALLEGRO_PI;
+ break;
+ case Maze::LEFT:
+ angle = 3*ALLEGRO_PI/2;
+ break;
+ }
+
+ float objectX = getPanelX(object.x());
+ float objectY = getPanelY(object.y());
+ float center = _mazeblockWidth/2;
+
+ al_draw_rotated_bitmap(bitmap, center , center , objectX+center-_offsetX, objectY+center-_offsetY, angle, 0);
+}
+
+float GamePanel::getPanelX(const double& x) const
+{
+ return static_cast<float>(x*_mazeblockWidth);
+}
+float GamePanel::getPanelY(const double& y) const
+{
+ return static_cast<float>(y*_mazeblockWidth);
+}