void CPlayer::Update(float dt) { CIwFVec2 path = MovePos - ControlledObject->getPos(); if(path.GetLengthSquared() > (cachesSquaredSize / 2) ) { ControlledObject->setDir(path); ControlledObject->setSpeed(50); } else { ControlledObject->setSpeed(0); } }
void AI::path(Unit& unit){ float rad = unit.getR(); float theta = unit.getTheta(); float speed = unit.getSpeed(); float range = unit.getRange(); if(unit.attacking()) attack(unit); if(unit.pursuing()){ Unit *pursuing = unit.getPursuing(); CIwFVec2 pursuingPos = pursuing->getPosition(); CIwFVec2 pursuitVector = pursuingPos - unit.getPosition(); CIwSVec2 tempPos; if (pursuitVector.GetLength()<range) attack(unit); tempPos = (pursuitVector/speed)+unit.getPosition(); unit.setVelocity(tempPos-unit.getPosition()); std::list<Unit*> *tempArray = collisionDetection(unit, unit.getGame()->getUnits()); if (tempArray == NULL || !tempArray->empty()) unit.setVelocity(CIwFVec2::g_Zero); delete tempArray; } else { Unit *Enemy = detectEnemy(unit, unit.getGame()->getUnits()); float thetaChange = speed/rad; float tempTheta = thetaChange + theta; unit.setRTheta(rad, tempTheta); CIwFVec2 tempPos = unit.getPosition(); unit.setRTheta(rad, theta); unit.setVelocity(tempPos-unit.getPosition()); std::list<Unit*> *tempArray = collisionDetection(unit, unit.getGame()->getUnits()); if (tempArray == NULL || !tempArray->empty()) { unit.setVelocity(CIwFVec2::g_Zero); } delete tempArray; } }
void Unit::path(std::list<Unit*>::iterator itr) { CIwFVec2 force = CIwFVec2::g_Zero; std::list<Unit*>* units = game->getUnits(); float theta = getTheta(); CIwFVec2 dirToward = CIwFVec2::g_Zero; Unit* curUnit; //brute force - need to take advantage of theta sorting for (itr = units->begin() ; itr != units->end(); ++itr) { curUnit = *(itr); if ((*itr) != this && THETA_DIFF(curUnit->getTheta(), theta) < PATH_THETA_RANGE) { dirToward = position - curUnit->getPosition(); float dist = dirToward.GetLengthSquared(); force += dirToward.GetNormalised() * (curUnit->getSize()*REPEL_FACTOR / pow(dist, 1.875)); // We can tweak bottom factor later, this seems to work fine: ^ } } //attractive force for opponent leader Player* opponent = game->getLocalPlayer() != owner ? owner : game->getOpponentPlayer(); dirToward = ((Unit*)(opponent->getLeader()))->getPosition() - position; float dist = dirToward.GetLength(); if(dist > 0) force += dirToward.GetNormalised() * (LEADER_ATTRACTION / dist); //"spring" force to motivate circular pathing float centerR = (game->getWorldRadius().y + game->getWorldRadius().x)/2.0; float rDiff = centerR - r; force += position * ((rDiff < 0 ? -1 : 1) * WALL_REPEL * SQ(rDiff)); // Ternary is experimentally faster velocity = speed*force.GetNormalised(); setPosition(position + velocity); }
void polarize(CIwFVec2& v){ float r = v.GetLength(); v.y = atan2(v.y, v.x); v.x = r; }