
 --------------------------------------------------------------------
    The Non-Graphic Game Programming Tutorials
    vol 1. simple object physics

    jdindi01@hills.ccsf.cc.ca.us
    copyright (c) march 27, 1997 John Paul D'India
 --------------------------------------------------------------------

 -------------------
 ABOUT THE TUTORIALS
 -------------------

     This set of tutorials on non-graphic concepts was started because of
 a lack of information in the area.  Every tutorial out there shows off
 graphics tricks, but never mentions anything about physics, AI, file
 management, object management, etc.  Graphics routines are only a small
 percentage of a serious game project.  Much more important and time
 consuming are all the other 'little' things.  This series of tutorials
 will hopefully help increase your productivity in general game
 programming.

    This may be the first of many or the last of one tutorial, so keep your
 eye's open.  This document may contain errors.

 ----------------
 ABOUT THE AUTHOR
 ----------------

     John Paul D'India has been programming for 5 years and has worked on
 many shareware games: ZM3, ZipFire II, Aro, and the Fourth Generation (to
 name a few).  He is a student and not a professional game programmer.

 --------------
 SHAMELESS PLUG
 --------------

     Go download and register Aro and The Fourth Generation (4gen)!

 ------------------
 COMPILER SPECIFICS
 ------------------

     This code was written and compiled under Watcom C/C++ 10.0a.  Your C
 compiler may reject the code, however changes should be obvious and
 fixable (like outp() instead of outport()).  This program was written for
 DOS as I'm less familiar with windows and I also feel the basic structure
 is easier to understand without windows clutter.

     This is C code with an object oriented style.  I have no real
 preference, so future tutorials may be in C or C++.  This tutorial and all
 subsequent tutorials require thorough knowledge of C (or C++).  The
 purpose of this tutorial is NOT to teach you C (or C++), rather it is
 to teach simple approaches to non-graphic game programming problems and
 issues.  If you do not know C/C++, then go and purchase a book on the
 subject.

 --------------
 SIMPLE PHYSICS
 --------------

     A simple high school physics course has all the information you will
 need to do simple physics in your game, so purchasing a high school physics
 book is highly recommended.  To simplify this discussion, we will limit
 ourselves to 2 dimensions, however, the principles apply to 3 dimensions
 as well.  The first few chapters of a physics book talk about 3 things:
 location, velocity, and acceleration.

    Location is a 2 component quantity (x,y) which represents the position
 of a particular object on a cartesian coordinate system.  Our video screen
 is 320x200 pixels, so we will define our world to be (320*8,200*8) units
 or (2560,1600) units.  For every pixel, we have 8 possible locations, thus
 greater precision and smoother movement.  It is worth noting that this
 extra precision is NOT graphic's precision; the display cannot turn on
 1/8th of a pixel.  Extra precision can make a big difference in the
 jerkiness of an objects movement and is WELL worth the extra effort.  You
 may even want to choose a higher precision.

    Velocity is a 2 component (velx,vely) vector quantity which is the
 derivative of location, or the rate at which the location changes (I hope
 I'm getting my math terms right here).  In english, velocity is the speed
 AND direction of an object.

    Acceleration is a 2 component (accx,accy) vector quantity which is the
 derivative of velocity, or the rate at which the velocity changes.
 Acceleration is a bit harder to define in plain english, so I'll just say
 that acceleration is the rate at which the velocity changes.  When you
 apply the gas pedal in your car, your car 'accelerates' or increases its
 velocity.  When you apply the brake, your car 'deccelarates', 'accelerates
 in the negative direction', or decreases its velocity.

    Location, velocity, and acceleration are vector quantities, so you can
 break them up into their separate parts.  In other words,
 velx+vely = (velx,vely)
 or more graphically:

              A
              |   C
              |  /
              | /
              |/
              +---- B

 A + B = C
 This means we can talk about and treat x and y separately.  They are
 independent of each other.  As an example, suppose I have a velocity vector
 A(3,4) and I want to change that vector by adding another velocity vector
 to it B(-2,2).  I can simply add each component to get a new velocity
 vector C(3-2,2+2) or C(1,4).

    Gravity is basically acceleration along the y axis.  Gravity is a
 constant acceleration (g=9.8m/(s*s)).  Since our world doesn't have real
 world units like meters and inches, we'll simply define our gravitational
 constant as something that looks good in our own units (ie 2 units/sec^2).

 -------------
 SHORT EXAMPLE
 -------------

     If I define my object as a structure:

  struct TBall
  {
      int x, y;
      int velx, vely;
  } ball;

  where (x,y) is my location and (velx,vely) is my velocity, then each
  'frame' or unit of time, I would update my object as follows:

  ball.x += ball.velx;
  ball.y += ball.vely;

  To add acceleration, I simply change the velocity each frame.  In the case
  of gravitational acceleration, which is a constant, I add to the y
  component of velocity:

  ball.vely += GRAVITATIONAL_CONSTANT;

  If I were to horizontally push or pull on the object, I would give it
  some horizontal acceleration.  For example, a push in the positive
  direction for each time unit pushing:

  ball.velx += PUSH_CONSTANT;

  Since we are not taking into account friction, it is usefull to declare
  a maximum velocity (especially in the horizontal direction).  Thus, you
  will often write:

  if (ball.velx > MAXIMUM_VELX)
     ball.velx = MAXIMUM_VELX;
  else if (ball.velx < -MAXIMUM_VELX)
     ball.velx = -MAXIMUM_VELX;

  the end.
