Rally X
ELEN3009 Project by Justin Wernick and David Schneider
|
00001 #include "GamePanel.h" 00002 00003 GamePanel::GamePanel(ALLEGRO_BITMAP* back, ALLEGRO_BITMAP* front, int x, int y, int width, int height) 00004 :ScreenPanel(back, front, x, y, width, height), 00005 _mazeblockWidth(_width/BLOCKS_PER_ROW), 00006 _offsetX(0), 00007 _offsetY(0), 00008 _bitmapStore(_mazeblockWidth) 00009 { 00010 } 00011 00012 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) 00013 { 00014 ALLEGRO_BITMAP* prev_draw = al_get_target_bitmap(); 00015 al_set_target_bitmap(_back); 00016 00017 al_clear_to_color(BLANK); 00018 00019 float _maxOffsetX = getPanelX(maze.width()) - _width; 00020 float _maxOffsetY = getPanelY(maze.height()) - _height; 00021 00022 if (!players.empty()) 00023 { 00024 _offsetX = getPanelX(players.front().x()) - _width/2; 00025 if (_offsetX < 0) _offsetX = 0; 00026 else if (_offsetX > _maxOffsetX) _offsetX = _maxOffsetX; 00027 00028 _offsetY = getPanelY(players.front().y()) - _height/2; 00029 if (_offsetY < 0) _offsetY = 0; 00030 else if (_offsetY > _maxOffsetY) _offsetY = _maxOffsetY; 00031 } 00032 00033 draw(maze); 00034 00035 for (list<PlayerCar>::const_iterator iter = players.begin(); iter != players.end(); ++iter) 00036 { 00037 draw(*iter); 00038 } 00039 for (list<EnemyCar>::const_iterator iter = enemies.begin(); iter != enemies.end(); ++iter) 00040 { 00041 draw(*iter); 00042 } 00043 for (list<Checkpoint>::const_iterator iter = checkpoints.begin(); iter != checkpoints.end(); ++iter) 00044 { 00045 draw(*iter); 00046 } 00047 for (list<Rock>::const_iterator iter = rocks.begin(); iter != rocks.end(); ++iter) 00048 { 00049 draw(*iter); 00050 } 00051 for (list<Smokescreen>::const_iterator iter = smokescreens.begin(); iter != smokescreens.end(); ++iter) 00052 { 00053 draw(*iter); 00054 } 00055 for (list<DestroyedObjectPopup>::const_iterator iter = popups.begin(); iter != popups.end(); ++iter) 00056 { 00057 draw(*iter); 00058 } 00059 00060 al_set_target_bitmap(prev_draw); 00061 } 00062 00063 void GamePanel::draw(const Maze& maze) 00064 { 00065 //only draws a parts of the maze that would appear on the screen 00066 int minX = floor((_offsetX-_mazeblockWidth)/_mazeblockWidth); 00067 int maxX = ceil((_offsetX+_width)/_mazeblockWidth); 00068 int minY = floor((_offsetY-_mazeblockWidth)/_mazeblockWidth); 00069 int maxY = ceil((_offsetY+_height)/_mazeblockWidth); 00070 00071 ALLEGRO_BITMAP* wallBitmap = _bitmapStore.getBitmap(BitmapStore::MAZE_WALL); 00072 ALLEGRO_BITMAP* floorBitmap = _bitmapStore.getBitmap(BitmapStore::MAZE_FLOOR); 00073 //used to only have one al_draw_bitmap command 00074 ALLEGRO_BITMAP* currentBitmap = floorBitmap; 00075 for (int x=minX; x<maxX&&x<maze.width(); ++x) 00076 { 00077 for (int y=minY; y<maxY&&y<maze.height(); ++y) 00078 { 00079 if (maze.getSolid(x,y)) 00080 { 00081 currentBitmap = wallBitmap; 00082 } 00083 else 00084 { 00085 currentBitmap = floorBitmap; 00086 } 00087 al_draw_bitmap(currentBitmap, getPanelX(x)-_offsetX, getPanelY(y)-_offsetY, 0); 00088 } 00089 } 00090 } 00091 00092 void GamePanel::draw(const GameObject& object) 00093 { 00094 //only draws a gameobject if it would appear on the screen 00095 if (object.x() < (_offsetX-_mazeblockWidth)/_mazeblockWidth) return; 00096 if (object.x() > (_offsetX+_width)/_mazeblockWidth) return; 00097 if (object.y() < (_offsetY-_mazeblockWidth)/_mazeblockWidth) return; 00098 if (object.y() > (_offsetY+_height)/_mazeblockWidth) return; 00099 00100 ALLEGRO_BITMAP* bitmap = _bitmapStore.getBitmap(object.image()); 00101 00102 float angle = 0; 00103 switch(object.facing()) 00104 { 00105 case Maze::UP: 00106 angle = 0; 00107 break; 00108 case Maze::RIGHT: 00109 angle = ALLEGRO_PI/2; 00110 break; 00111 case Maze::DOWN: 00112 angle = ALLEGRO_PI; 00113 break; 00114 case Maze::LEFT: 00115 angle = 3*ALLEGRO_PI/2; 00116 break; 00117 } 00118 00119 float objectX = getPanelX(object.x()); 00120 float objectY = getPanelY(object.y()); 00121 float center = _mazeblockWidth/2; 00122 00123 al_draw_rotated_bitmap(bitmap, center , center , objectX+center-_offsetX, objectY+center-_offsetY, angle, 0); 00124 } 00125 00126 float GamePanel::getPanelX(const double& x) const 00127 { 00128 return static_cast<float>(x*_mazeblockWidth); 00129 } 00130 float GamePanel::getPanelY(const double& y) const 00131 { 00132 return static_cast<float>(y*_mazeblockWidth); 00133 }