Rally X
ELEN3009 Project by Justin Wernick and David Schneider
|
00001 #include "EnemyCar.h" 00002 00003 EnemyCar::EnemyCar(double x, double y) 00004 :Car(x,y,BitmapStore::ENEMY,Maze::UP), 00005 _state(CHASING), 00006 _targetX(x), 00007 _targetY(y) 00008 { 00009 } 00010 00011 void EnemyCar::update(const Maze& maze, const list<PlayerCar>& players, const list<Rock>& rocks) 00012 { 00013 if (!players.empty()) checkFacing(maze, players.front().x(), players.front().y(), rocks); 00014 00015 if (_state!=BLINDED) 00016 { 00017 move(maze); 00018 } 00019 else 00020 { 00021 _state = CHASING; 00022 _speed = _baseSpeed; 00023 } 00024 } 00025 00026 void EnemyCar::checkFacing(const Maze& maze, double chasingX, double chasingY, const list<Rock>& rocks) 00027 { 00028 if (abs(_x - _targetX)>_speed || abs(_y - _targetY)>_speed) return; 00029 00030 map<Maze::Direction, pair<double, double> > adjacentBlocks; 00031 pair<double, double> evaluatingTarget; 00032 00033 adjacentBlocks[Maze::LEFT] = make_pair(MazeMath::round(_x-1), MazeMath::round(_y)); 00034 adjacentBlocks[Maze::RIGHT] = make_pair(MazeMath::round(_x+1), MazeMath::round(_y)); 00035 adjacentBlocks[Maze::UP] = make_pair(MazeMath::round(_x), MazeMath::round(_y-1)); 00036 adjacentBlocks[Maze::DOWN] = make_pair(MazeMath::round(_x), MazeMath::round(_y+1)); 00037 00038 //remove adjacent blocks that would result in crashing into a rock or a wall 00039 for (map<Maze::Direction, pair<double, double> >::iterator iter=adjacentBlocks.begin(); iter!=adjacentBlocks.end(); ) 00040 { 00041 if (rockAtLocation(iter->second.first, iter->second.second, rocks) || maze.getSolid(static_cast<int>(iter->second.first),static_cast<int>(iter->second.second))) 00042 { 00043 adjacentBlocks.erase(iter); 00044 iter = adjacentBlocks.begin(); 00045 } 00046 else 00047 { 00048 ++iter; 00049 } 00050 } 00051 00052 if (adjacentBlocks.empty()) 00053 { 00054 _speed = 0; 00055 return; 00056 } 00057 else 00058 { 00059 _speed = _baseSpeed; 00060 } 00061 00062 map<Maze::Direction, pair<double, double> >::iterator reverseFacing = adjacentBlocks.find(Maze::backwards(_facing)); 00063 if ((reverseFacing != adjacentBlocks.end()) && (adjacentBlocks.size()>1)) 00064 { 00065 adjacentBlocks.erase(reverseFacing); 00066 } 00067 00068 map<Maze::Direction, pair<double, double> >::const_iterator closestAdjacent = adjacentBlocks.begin(); 00069 double closestDistance = MazeMath::distance(closestAdjacent->second.first, closestAdjacent->second.second, chasingX, chasingY); 00070 00071 for (map<Maze::Direction, pair<double, double> >::const_iterator iter = ++adjacentBlocks.begin(); iter!=adjacentBlocks.end(); ++iter) 00072 { 00073 double newDistance = MazeMath::distance(iter->second.first, iter->second.second, chasingX, chasingY); 00074 if (newDistance < closestDistance) 00075 { 00076 closestDistance = newDistance; 00077 closestAdjacent = iter; 00078 } 00079 } 00080 00081 _targetX = closestAdjacent->second.first; 00082 _targetY = closestAdjacent->second.second; 00083 _facing = closestAdjacent->first; 00084 } 00085 00086 bool EnemyCar::rockAtLocation(double x, double y, const list<Rock>& rocks) 00087 { 00088 for (list<Rock>::const_iterator iter = rocks.begin(); iter!=rocks.end(); ++iter) 00089 { 00090 if (abs(x - iter->x())<1 && abs(y - iter->y())<1) return true; 00091 } 00092 return false; 00093 } 00094 00095 void EnemyCar::crash() 00096 { 00097 _destroyed = true; 00098 } 00099 00100 void EnemyCar::blind() 00101 { 00102 _state = BLINDED; 00103 _speed = 0; 00104 }