⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cboid.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 3 页
字号:

#ifdef BOID_DEBUG
      myprintf("   too close!\n");
#endif
      
      // too close...move away from our neighbor

      change.SetMagnitudeOfVector (-ratio);

   } else if (m_dist_to_nearest_flockmate > m_preferred_separation) {

#ifdef BOID_DEBUG
      myprintf("   too far away!\n");
#endif

      // too far away...move towards our neighbor

      change.SetMagnitudeOfVector (ratio);

   } else {

#ifdef BOID_DEBUG
      myprintf("   just right!\n");
#endif

      // in the UNLIKELY event we're exactly the right distance away, do nothing

      change.SetMagnitudeOfVector (0.0);
   }

   // return change vector

#ifdef BOID_DEBUG
   myprintf("   final change vector from KeepDistance = %f %f %f\n",change.x, change.y, change.z);
#endif

   return (change);
}

// MatchHeading.
// Generates a vector for a flock boid to try
// to match the heading of its nearest flockmate.

vector CBoid::MatchHeading (void)
{

   // copy the heading of our nearest buddy

   vector change = m_nearest_flockmate->m_vel;

#ifdef BOID_DEBUG
   myprintf("\nInside MatchHeading\n");
#endif

   // normalize and then scale our vector change a bit...after
   // all we can't instantly snap to a new heading, can we?

   change.SetMagnitudeOfVector (MinUrgency);

   // return change vector

#ifdef BOID_DEBUG
   myprintf("   final change vector from MatchHeading = %f %f %f\n",change.x, change.y, change.z);
#endif

   return (change);

}

// SeePredators.
// Determines which predator boids a given flock boid can see.

int CBoid::SeePredators (int flock_id)
{

   float dist;

   CBoid *predator;

#ifdef BOID_DEBUG
   myprintf("\nInside SeePredators\n");
#endif

   // initialize predator data

   m_num_predators_seen       = 0;
   m_nearest_predator         = NULL;
   m_dist_to_nearest_predator = INFINITY;

   // loop over each flock and determine the closest one we can see

   for (int i = 0; i < CFlock::FlockCount; i++) {

      // test:  if this is OUR flock, skip it

      if (i == flock_id) continue;

#ifdef VISIBILITY_DEBUG
   myprintf("   \nTesting to see if %s can see anybody in flock %d\n",m_id,i);
#endif

      // not our flock, so check it out

      predator = CFlock::ListOfFlocks[i]->GetFirstMember();

      // is this flock a predator of our boid?

#ifdef VISIBILITY_DEBUG
      myprintf("   my type = %d  his type = %d\n",m_type,predator->GetType());
#endif

      if (predator != NULL) {

         if (IsPredator(predator)) {

            // it sure is....find the closest one

            while (predator != NULL) {
      
   #ifdef VISIBILITY_DEBUG
         myprintf("   looking at %x\n",predator);
   #endif

               // if this predator is visible...

               if ((dist = CanISee(predator)) != INFINITY) {

   #ifdef VISIBILITY_DEBUG
                  myprintf("   Yep,  I see him!\n");
   #endif

                  // I can see it..increment counter

                  m_num_predators_seen++;

                  // Test:  Closest predator?

                  if (dist < m_dist_to_nearest_predator) {
               
                     // yes...save it off

                     m_dist_to_nearest_predator = dist;
                     m_nearest_predator = predator;
                  }
               }

               // get next predator in flock

               predator = predator->GetNext();
            }
         }
      }
   }

#ifdef VISIBILITY_DEBUG
   myprintf("\n");
   myprintf("   total predators seen = %d\n",m_num_predators_seen);
   myprintf("   nearest predator is %x at %f\n",
      m_nearest_predator,m_dist_to_nearest_predator);
#endif

   return (m_num_predators_seen);

}

// 3.
// Determines which prey boids a given flock boid can see.

int CBoid::SeePrey (int flock_id)
{

   float dist;

   CBoid *prey;

#ifdef BOID_DEBUG
   myprintf("\nInside SeePrey\n");
#endif

   // initialize prey data

   m_num_prey_seen        = 0;
   m_nearest_prey         = NULL;
   m_dist_to_nearest_prey = INFINITY;

   // loop over each flock and determine the closest one we can see

   for (int i = 0; i < CFlock::FlockCount; i++) {

      // test:  if this is OUR flock, skip it

      if (i == flock_id) continue;

#ifdef VISIBILITY_DEBUG
   myprintf("   \nTesting to see if %s can see anybody in flock %d\n",m_id,i);
#endif

      // not our flock, so check it out

      prey = CFlock::ListOfFlocks[i]->GetFirstMember();

      // is this flock prey for our boid?

#ifdef VISIBILITY_DEBUG
      myprintf("   my type = %d  his type = %d\n",m_type,prey->GetType());
#endif

      if (prey != NULL) {

         if (IsPrey(prey)) {

            // it sure is....find the closest one

            while (prey != NULL) {
      
   #ifdef VISIBILITY_DEBUG
         myprintf("   looking at %s\n",prey->GetID());
   #endif

               // if this prey is visible...

               if ((dist = CanISee(prey)) != INFINITY) {

   #ifdef VISIBILITY_DEBUG
                  myprintf("   Yep,  I see him!\n");
   #endif

                  // I can see it..increment counter

                  m_num_prey_seen++;

                  // Test:  Closest prey?

                  if (dist < m_dist_to_nearest_prey) {
               
                     // yes...save it off

                     m_dist_to_nearest_prey = dist;
                     m_nearest_prey         = prey;
                     m_preys_flock          = CFlock::ListOfFlocks[i];
                  }

               }

               // get next prey in flock

               prey = prey->GetNext();

            }
         }
      }
   }

#ifdef VISIBILITY_DEBUG
   myprintf("\n");
   myprintf("   total prey seen = %d\n",m_num_prey_seen);
   myprintf("   nearest prey is %x at %f\n",m_nearest_prey,m_dist_to_nearest_prey);
#endif

   return (m_num_prey_seen);

}

// SeeFriends.
// Determines which flockmates a given flock boid can see.

int CBoid::SeeFriends (CBoid *first_boid)
{

   float dist;

   CBoid *flockmate = first_boid;

#ifdef BOID_DEBUG
   myprintf("\nInside SeeFriends\n");
#endif

#ifdef VISIBILITY_DEBUG
   myprintf("   Building visibilty list for %x...\n",this);
#endif

   // clear the existing visibility list of any holdover from last round

   ClearVisibleList();

   // now figure out who we can see

   while (flockmate != NULL) {

      // Test:  Within sight of this boid?

#ifdef VISIBILITY_DEBUG
      myprintf("   looking at %x\n",flockmate);
#endif

      if ((dist = CanISee(flockmate)) != INFINITY) {

         // add it to the list

         AddToVisibleList(flockmate);

         // Test:  If this guy is closer than the current
         // closest, make him the current closest

         if (dist < m_dist_to_nearest_flockmate) {
            m_dist_to_nearest_flockmate = dist;
            m_nearest_flockmate = flockmate;
         }
      }

      // next flockmate

      flockmate = flockmate->GetNext();
   }

#ifdef VISIBILITY_DEBUG
   myprintf("\n");
   myprintf("   total flockmates seen = %d\n",m_num_flockmates_seen);
   myprintf("   nearest flockmate is %x at %f\n",
      m_nearest_flockmate, m_dist_to_nearest_flockmate);
#endif

   return (m_num_flockmates_seen);

}

// SeeObstacles.
// Determines if a given boid sees any obstacles near him.
// Returns the number of obstacles seen if it does.

int CBoid::SeeObstacles (void)
{

   float dist;

   CObstacle *obstacle;

#ifdef VISIBILITY_DEBUG
   myprintf("\nInside SeeObstacles with boid %s\n",m_id);
#endif

   // initialize obstacle data

   m_num_obstacles_seen       = 0;
   m_nearest_obstacle         = NULL;
   m_dist_to_nearest_obstacle = INFINITY;

   // loop over every obstacle and determine the closest one we can see

   for (int i = 0; i < CObstacle::ObstacleCount; i++) {

#ifdef VISIBILITY_DEBUG
      myprintf("   Testing to see if boid %x can see obstacle %d\n",
         this,CObstacle::ListOfObstacles[i]->GetID());
#endif

      // not our flock, so check it out

      obstacle = CObstacle::ListOfObstacles[i];

      // if this obstacle is visible...

      if ((dist = CanISeeObstacle(obstacle)) != INFINITY) {

         // I can see it..increment counter

         m_num_obstacles_seen++;

         // Test:  Closest enemy?

         if (dist < m_dist_to_nearest_obstacle) {
            
            // yes...save it off

            m_dist_to_nearest_obstacle = dist;
            m_nearest_obstacle = obstacle;
         }
      }
   }

#ifdef VISIBILITY_DEBUG
   myprintf("\n");
   myprintf("   total obstacles seen = %d\n",m_num_obstacles_seen);
   myprintf("   nearest obstacle is %x at a distance of %f\n",
      m_nearest_obstacle,m_dist_to_nearest_obstacle);
#endif

   return (m_num_obstacles_seen);

}

// SteerToCenter.
// Generates a vector to guide a flock boid towards
// the "center of mass" of the flockmates he can see.

vector CBoid::SteerToCenter (void)
{

   vector center, change;

#ifdef BOID_DEBUG
   myprintf("\nInside SteerToCenter\n");
#endif

   // walk down the visibility list and sum up their position vectors

   for (int i = 0; i < m_num_flockmates_seen; i++) {
      if (VisibleFriendsList[i] != NULL) center += VisibleFriendsList[i]->m_pos;
   }

#ifdef BOID_DEBUG
   myprintf("   perceived center before averaging = %f %f %f\n",center.x, center.y, center.z);
   myprintf("   num_flockmates_seen = %d\n",m_num_flockmates_seen);
#endif

   // average the positions to get the perceived center of the flock

   center /= m_num_flockmates_seen;

#ifdef BOID_DEBUG
   myprintf("   perceived center after averaging = %f %f %f\n",center.x, center.y, center.z);
#endif

   // now that we have the perceived center, computer a vector towards it

   change = center - m_pos;

   // Scale the change vector so we don't turn on a dime..

   change.SetMagnitudeOfVector (MinUrgency);

#ifdef BOID_DEBUG
   myprintf("   final change vector from SteerToCenter = %f %f %f\n",
      change.x, change.y, change.z);
#endif

   // return change vector

   return (change);
}

// WorldBound.
// Implements a world boundary so that flocks don't fly
// infinitely far away from the camera, instead remaining 
// in a nice viewable area.  It does this by wrapping flock
// boids around to the other side of the world, so (for example)
// they move out the right and return on the left.
// Returns:  nothing.

void CBoid::WorldBound (void)
{

   float maxX = CBox::WorldPtr->GetBoxWidth()/2;
   float maxY = CBox::WorldPtr->GetBoxHeight()/2;
   float maxZ = CBox::WorldPtr->GetBoxLength()/2;

   float minX = -maxX;
   float minY = -maxY;
   float minZ = -maxZ;

#ifdef BOID_DEBUG
   myprintf("\nInside Worldbound\n");
#endif

   // test position of flock boid and 
   // 'warp' if they've strayed out of bounds

   if (m_pos.x > maxX) {
      m_pos.x = minX;
   } else if (m_pos.x < minX) {
      m_pos.x = maxX;
   
   } else if (m_pos.y > maxY) {
      m_pos.y = minY;
   } else if (m_pos.y < minY) {
      m_pos.y = maxY;
   
   } else if (m_pos.z > maxZ) {
      m_pos.z = minZ;
   } else if (m_pos.z < minZ) {
      m_pos.z = maxZ;
   }

}

////////////////////////
// predator/prey methods
////////////////////////

// SetAlive.
// Sets the alive/dead flag on this boid.

void CBoid::SetAlive (bool flag_v)
{

   m_alive = flag_v;

}

// IsPredator.
// Determines whether or not the boid in question is
// a predator of the boid making the inquiry.

bool CBoid::IsPredator (CBoid *ptr)
{

   return (ptr->GetType() == m_my_predator);

}

// IsPrey.
// Determines whether or not the boid in question is prey
// for the boid making the inquiry.

bool CBoid::IsPrey (CBoid *ptr)
{

   return (ptr->GetType() == m_my_prey);

}

// GetType.
// Gets the type of the boid in question.

BoidTypes CBoid::GetType (void)
{

   return (m_type);

}

// SetType.
// Sets the type of the boid in question.

void CBoid::SetType (BoidTypes type_v)
{

   m_type = type_v;

   // adjust personal max speed based on type (so predators are faster than prey)

   m_max_speed *= m_type;

}

// GetHunger.
// Returns the hunger level of the boid in question.

float CBoid::GetHunger (void)
{

   return (m_hunger);

}

// SetHunger.
// Changes the hunger level of the boid in question by the value supplied.

void CBoid::SetHunger (float inc_v)
{

   m_hunger += inc_v;

}

// GetPreyOf.
// Returns the type of boid (if any) which is the prey of the
// boid making the inquiry.

BoidTypes CBoid::GetPreyOf (void)
{

	return (m_my_prey);

}

// GetPreyPtr.
// Returns a pointer to the boid (if any) which is the prey of the
// boid making the inquiry.

CBoid * CBoid::GetPreyPtr (void)
{

	return (m_nearest_prey);

}

// GetPreyVector.
// Returns a vector the the prey (if any) of the current boid.

vector * CBoid::GetPreyVector (void)
{

   return (&m_prey_vector);

}

// SetPreyOf.
// Sets the prey type of the boid making the call.

void CBoid::SetPreyOf (BoidTypes type_v)
{

	m_my_prey = type_v;

}

// GetPredatorOf.
// Returns the type of boid (if any) which is the predator of
// the boid making the inquiry.

BoidTypes CBoid::GetPredatorOf (void)
{

   return (m_my_predator);

}

// GetPredatorPtr.
// Returns the type of boid (if any) which is the predator of
// the boid making the inquiry.

CBoid * CBoid::GetPredatorPtr (void)
{

   return (m_nearest_predator);

}

// SetPredatorOf.
// Sets the predator type of the boid making the call.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -