diff options
Diffstat (limited to 'source/presentation/GamePanel.cpp')
-rw-r--r-- | source/presentation/GamePanel.cpp | 133 |
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); +} |