home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / More Source / C⁄C++ / Peter's Final Project / src / computer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-10  |  4.5 KB  |  158 lines  |  [TEXT/KAHL]

  1. /*
  2.  *  Peter's Final Project -- A texture mapping demonstration
  3.  *  © 1995, Peter Mattis
  4.  *
  5.  *  E-mail:
  6.  *  petm@soda.csua.berkeley.edu
  7.  *
  8.  *  Snail-mail:
  9.  *   Peter Mattis
  10.  *   557 Fort Laramie Dr.
  11.  *   Sunnyvale, CA 94087
  12.  *
  13.  *  Avaible from:
  14.  *  http://www.csua.berkeley.edu/~petm/final.html
  15.  *
  16.  *  This program is free software; you can redistribute it and/or modify
  17.  *  it under the terms of the GNU General Public License as published by
  18.  *  the Free Software Foundation; either version 2 of the License, or
  19.  *  (at your option) any later version.
  20.  *
  21.  *  This program is distributed in the hope that it will be useful,
  22.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  23.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  24.  *  GNU General Public License for more details.
  25.  *
  26.  *  You should have received a copy of the GNU General Public License
  27.  *  along with this program; if not, write to the Free Software
  28.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  29.  */
  30.  
  31. #include <assert.h>
  32. #include <math.h>
  33.  
  34. #include "computer.h"
  35. #include "matrix.vector.h"
  36. #include "object.h"
  37. #include "point.h"
  38. #include "sys.stuff.h"
  39.  
  40. /*
  41.  * Define some movement and distance constants for
  42.  *  the computer to use in moving. (I know, some of
  43.  *  these are duplicated in "engine.c". Bad Peter...bad.)
  44.  */
  45.  
  46. static const NUM TURN_STEP = NUM_ONE * 0.07;
  47. static const NUM MOVE_STEP = NUM_ONE * 0.10;
  48. static const NUM MOVE_FAST = NUM_ONE * 0.15;
  49.  
  50. static const NUM TURN_HALF_STEP = NUM_ONE * 0.035;
  51. static const NUM TURN_DOUBLE_STEP = NUM_ONE * 0.14;
  52. static const NUM MOVE_HALF_STEP = NUM_ONE * 0.05;
  53.  
  54. static const NUM DISTANCE_FAR = NUM_ONE * 3.0;
  55. static const NUM DISTANCE_NORM = NUM_ONE * 1.5;
  56. static const NUM DISTANCE_NEAR = NUM_ONE * 1.0;
  57.  
  58. /*
  59.  * Let the computer decide how to move. The current
  60.  *  movement function basically follows a certain object.
  61.  */
  62.  
  63. void 
  64. computer_move (o)
  65.     OBJECT o;
  66. {
  67.     OBJECT you;
  68.     VECTOR v;
  69.     VECTOR cross;
  70.     NUM turn_angle;
  71.     NUM distance;
  72.  
  73.     /*
  74.      * This is the object we follow.
  75.      */
  76.     you = object_data (o);
  77.  
  78.     /*
  79.      * First, get the vector describing the distance between
  80.      *  me and you.
  81.      */
  82.     vector_sub (object_pos (you), object_pos (o), v);
  83.     distance = vector_magnitude (v);
  84.     
  85.     /*
  86.      * Normalize the vector so we can use it in cross product
  87.      *  calculations correctly.
  88.      */
  89.     vector_normalize (v);
  90.     vector_cross (object_dir (o), v, cross);
  91.  
  92.     /*
  93.      * The dot product between "v" and my direction is the cosine
  94.      *  of the angle between those two vectors. Take the acos to
  95.      *  find the angle to turn so I'd be facing you.
  96.      * Note: This angle is always positive.
  97.      */
  98.     turn_angle = my_float_to_num (acos (my_num_to_float (vector_dot (object_dir (o), v))));
  99.     if (turn_angle > TURN_DOUBLE_STEP)
  100.     {
  101.         /*
  102.          * I'm not even close to looking at you, so let's use
  103.          *  the cross product I calculated earlier to determine
  104.          *  which direction to turn. Remember, the cross product
  105.          *  is proportional to the sine of the angle between to
  106.          *  vectors.
  107.          */
  108.         if (vector_y (cross) > 0)
  109.             set_object_dir_vel (o, object_dir_vel (o) + TURN_STEP);
  110.         else
  111.             set_object_dir_vel (o, object_dir_vel (o) - TURN_STEP);
  112.  
  113.         /*
  114.          * Let's move slowly, since I'm not necessarily looking
  115.          *  at you.
  116.          */
  117.         if (distance > DISTANCE_NORM)
  118.             set_object_pos_vel (o, object_pos_vel (o) + MOVE_HALF_STEP);
  119.         else if (distance < DISTANCE_NEAR)
  120.             set_object_pos_vel (o, object_pos_vel (o) - MOVE_HALF_STEP);
  121.     }
  122.     else if (turn_angle > TURN_STEP)
  123.     {
  124.         /*
  125.          * I'm almost looking at you, so I'll turn more slowly now.
  126.          */
  127.         if (vector_y (cross) > 0)
  128.             set_object_dir_vel (o, object_dir_vel (o) + TURN_HALF_STEP);
  129.         else
  130.             set_object_dir_vel (o, object_dir_vel (o) - TURN_HALF_STEP);
  131.  
  132.         /*
  133.          * Let's move a little faster now if you are far away.
  134.          */
  135.         if (distance > DISTANCE_FAR)
  136.             set_object_pos_vel (o, object_pos_vel (o) + MOVE_STEP);
  137.         else if (distance > DISTANCE_NORM)
  138.             set_object_pos_vel (o, object_pos_vel (o) + MOVE_HALF_STEP);
  139.         else if (distance < DISTANCE_NEAR)
  140.             set_object_pos_vel (o, object_pos_vel (o) - MOVE_HALF_STEP);
  141.     }
  142.     else
  143.     {
  144.         /*
  145.          * Well, I'm basically looking at you, so we'll move
  146.          *  as fast as possible if you are far and at normal
  147.          *  speed to keep up if you are closer. (Hey, don't
  148.          *  get to close).
  149.          */
  150.         if (distance > DISTANCE_FAR)
  151.             set_object_pos_vel (o, object_pos_vel (o) + MOVE_FAST);
  152.         else if (distance > DISTANCE_NORM)
  153.             set_object_pos_vel (o, object_pos_vel (o) + MOVE_STEP);
  154.         else if (distance < DISTANCE_NEAR)
  155.             set_object_pos_vel (o, object_pos_vel (o) - MOVE_STEP);
  156.     }
  157. }
  158.