void B020612E_Steering::CreateFeelers() { //feeler pointing straight in front _pFeelers[0] = _pTank->GetCentrePosition() + _pWallDetectionFeelerLength * _pTank->GetHeading(); //feeler to left Vector2D temp = _pTank->GetHeading(); Vec2DRotateAroundOrigin(temp, HalfPi * 3.5f); _pFeelers[1] = _pTank->GetCentrePosition() + _pWallDetectionFeelerLength / 2.0f * temp; //feeler to right temp = _pTank->GetHeading(); Vec2DRotateAroundOrigin(temp, HalfPi * 0.5f); _pFeelers[2] = _pTank->GetCentrePosition() + _pWallDetectionFeelerLength / 2.0f * temp; }
std::list<cocos2d::Point> Path::CreateRandomPath(int NumWaypoints, double MinX, double MinY, double MaxX, double MaxY) { m_WayPoints.clear(); double midX = (MaxX+MinX)/2.0; double midY = (MaxY+MinY)/2.0; double smaller = MIN(midX, midY); double spacing = TwoPi/(double)NumWaypoints; for (int i=0; i<NumWaypoints; ++i) { double RadialDist = RandInRange(smaller*0.2f, smaller); cocos2d::Point temp(RadialDist, 0.0f); Vec2DRotateAroundOrigin(temp, i*spacing); temp.x += midX; temp.y += midY; m_WayPoints.push_back(temp); } curWaypoint = m_WayPoints.begin(); return m_WayPoints; }
inline void ShotGun::ShootAt(Vector2D pos) { if (NumRoundsRemaining() > 0 && isReadyForNextShot()) { //a shotgun cartridge contains lots of tiny metal balls called pellets. //Therefore, every time the shotgun is discharged we have to calculate //the spread of the pellets and add one for each trajectory for (int b=0; b<m_iNumBallsInShell; ++b) { //determine deviation from target using a bell curve type distribution double deviation = RandInRange(0, m_dSpread) + RandInRange(0, m_dSpread) - m_dSpread; Vector2D AdjustedTarget = pos - m_pOwner->Pos(); //rotate the target vector by the deviation Vec2DRotateAroundOrigin(AdjustedTarget, deviation); //add a pellet to the game world m_pOwner->GetWorld()->AddShotGunPellet(m_pOwner, AdjustedTarget + m_pOwner->Pos()); } m_iNumRoundsLeft--; UpdateTimeWeaponIsNextAvailable(); //add a trigger to the game so that the other bots can hear this shot //(provided they are within range) m_pOwner->GetWorld()->GetMap()->AddSoundTrigger(m_pOwner, script->GetDouble("ShotGun_SoundRange")); } }
//---------------------------- AddNoiseToAim ---------------------------------- // // adds a random deviation to the firing angle not greater than m_dAimAccuracy // rads //----------------------------------------------------------------------------- void Raven_WeaponSystem::AddNoiseToAim(Vector2D& AimingPos)const { Vector2D toPos = AimingPos - m_pOwner->Pos(); Vec2DRotateAroundOrigin(toPos, RandInRange(-m_dAimAccuracy, m_dAimAccuracy)); AimingPos = toPos + m_pOwner->Pos(); }
//---------------------------- AddFuzzyDeviationToAim ------------------------- // // adds a deviation to the firing angle using fuzzy logic //-------------------------------------- --------------------------------------- void Raven_WeaponSystem::AddFuzzyDeviationToAim(Vector2D& AimingPos) { double distToTarget = Vec2DDistance(m_pOwner->Pos(), m_pOwner->GetTargetSys()->GetTarget()->Pos()); double targetVelocity = m_pOwner->Speed(); double targetVisiblePeriod = m_pOwner->GetTargetSys()->GetTimeTargetHasBeenVisible(); /* Fuzzification */ m_FuzzyModule.Fuzzify("DistToTarget", distToTarget); m_FuzzyModule.Fuzzify("TargetVelocity", targetVelocity); m_FuzzyModule.Fuzzify("TargetVisiblePeriod", targetVisiblePeriod); double derivation = m_FuzzyModule.DeFuzzify("Deviation", FuzzyModule::max_av); bool isDerivationPosition = RandBool(); /* Deviation computing */ Vector2D toPos = AimingPos - m_pOwner->Pos(); if (isDerivationPosition) Vec2DRotateAroundOrigin(toPos, derivation*m_dAimAccuracy); else Vec2DRotateAroundOrigin(toPos, -1 * derivation*m_dAimAccuracy); AimingPos = toPos + m_pOwner->Pos(); }
void Dribble::Execute(FieldPlayer* player) { double dot = player->Team()->HomeGoal()->Facing().Dot(player->Heading()); //if the ball is between the player and the home goal, it needs to swivel // the ball around by doing multiple small kicks and turns until the player //is facing in the correct direction if (dot < 0) { //the player's heading is going to be rotated by a small amount (Pi/4) //and then the ball will be kicked in that direction Vector2D direction = player->Heading(); //calculate the sign (+/-) of the angle between the player heading and the //facing direction of the goal so that the player rotates around in the //correct direction double angle = QuarterPi * -1 * player->Team()->HomeGoal()->Facing().Sign(player->Heading()); Vec2DRotateAroundOrigin(direction, angle); //this value works well whjen the player is attempting to control the //ball and turn at the same time const double KickingForce = 0.8; player->Ball()->Kick(direction, KickingForce); } //kick the ball down the field else { player->Ball()->Kick(player->Team()->HomeGoal()->Facing(), Prm.MaxDribbleForce); } //the player has kicked the ball so he must now change state to follow it player->GetFSM()->ChangeState(ChaseBall::Instance()); return; }
//--------------------------- BoundsAvoidance -------------------------------- // // This returns a steering force that will keep the agent in an area //------------------------------------------------------------------------ Vector2D SteeringBehavior::BoundsAvoidance() { std::vector<Vector2D> m_Feelers(3); const float m_dWallDetectionFeelerLength = 20; //feeler pointing straight in front m_Feelers[0] = m_pMovingEntity->Pos() + m_dWallDetectionFeelerLength * m_pMovingEntity->Heading(); //feeler to left Vector2D temp = m_pMovingEntity->Heading(); Vec2DRotateAroundOrigin(temp, HalfPi * 3.5f); m_Feelers[1] = m_pMovingEntity->Pos() + m_dWallDetectionFeelerLength/2.0f * temp; //feeler to right temp = m_pMovingEntity->Heading(); Vec2DRotateAroundOrigin(temp, HalfPi * 0.5f); m_Feelers[2] = m_pMovingEntity->Pos() + m_dWallDetectionFeelerLength/2.0f * temp; float DistToThisIP = 0.0; float DistToClosestIP = MaxDouble; Vector2D wallsv[5] = {Vector2D(m_bounds.left, m_bounds.top), Vector2D(m_bounds.left, m_bounds.top+m_bounds.height), Vector2D(m_bounds.left+m_bounds.width, m_bounds.top+m_bounds.height), Vector2D(m_bounds.left+m_bounds.width, m_bounds.top), Vector2D(m_bounds.left, m_bounds.top) }; //this will hold an index into the vector of walls int ClosestWall = -1; Vector2D SteeringForce, point, //used for storing temporary info ClosestPoint; //holds the closest intersection point //examine each feeler in turn for (unsigned int flr=0; flr<m_Feelers.size(); ++flr) { //run through each wall checking for any intersection points for (int i = 0; i < 4; i++) { if (LineIntersection2D(m_pMovingEntity->Pos(), m_Feelers[flr], wallsv[i], wallsv[i+1], DistToThisIP, point)) { //is this the closest found so far? If so keep a record if (DistToThisIP < DistToClosestIP) { DistToClosestIP = DistToThisIP; ClosestWall = i; ClosestPoint = point; } } }//next wall //if an intersection point has been detected, calculate a force //that will direct the agent away if (ClosestWall != -1) { //calculate by what distance the projected position of the agent //will overshoot the wall Vector2D OverShoot = m_Feelers[flr] - ClosestPoint; Vector2D temp = Vec2DNormalize(wallsv[ClosestWall] - wallsv[ClosestWall+1]); Vector2D normal (-temp.y,temp.x); //create a force in the direction of the wall normal, with a //magnitude of the overshoot SteeringForce = normal * OverShoot.Length(); } }//next feeler return SteeringForce; }