1. with Entities;                          use Entities; 
  2. with Objects;                           use Objects; 
  3. with Physics.Clip_Maps;                 use Physics.Clip_Maps; 
  4.  
  5. limited with Physics.Managers; 
  6.  
  7. private with Ada.Containers.Ordered_Maps; 
  8.  
  9. package Physics.Bodies is 
  10.  
  11.     -- A physical representation of an entity, used by a Phsyics_Manager. 
  12.     type Corpus is new Object with private; 
  13.     type A_Corpus is access all Corpus'Class; 
  14.  
  15.     -- Creates a new corpus representing entity 'id', for use by 'manager'. 
  16.     function Create_Corpus( id       : Entity_Id; 
  17.                             width, 
  18.                             height   : Natural; 
  19.                             physical : Boolean; 
  20.                             clipped  : Boolean; 
  21.                             manager  : access Physics.Managers.Physics_Manager'Class 
  22.                           ) return A_Corpus; 
  23.  
  24.     -- Performs collision detection and returns True if this corpus is touching 
  25.      -- 'that' corpus. The objects are not modified. 
  26.     function Detect_Collision( this : not null access Corpus'Class; 
  27.                                that : not null A_Corpus ) return Boolean; 
  28.  
  29.     -- Returns the entity id the corpus represents. 
  30.     function Get_Id( this : not null access Corpus'Class ) return Entity_Id; 
  31.  
  32.     -- Returns True if 'that' corpus is in this corpus' touch list. No collision 
  33.     -- detection is performed. 
  34.     function Is_Touching( this : not null access Corpus'Class; 
  35.                           that : not null A_Corpus ) return Boolean; 
  36.  
  37.     -- Marks the contact state between this corpus and 'that'. The corpus' touch 
  38.     -- list will be updated. Set 'inContact' to true if the two corps are in 
  39.     -- contact with each other. Corpus 'that' is not modified. 
  40.     procedure Mark_Contact( this      : not null access Corpus'Class; 
  41.                             that      : not null A_Corpus; 
  42.                             inContact : Boolean ); 
  43.  
  44.     -- Moves the entity to the given location. An Entity_Moved event is queued. 
  45.     -- Clipping is performed so an Entity_Grounded event may also be queued. 
  46.     procedure Move_To( this : not null access Corpus'Class; 
  47.                        map  : not null A_Clip_Map; 
  48.                        x, y : Float ); 
  49.  
  50.     -- Sets the acceleration in the X axis. 
  51.     procedure Set_AX( this : not null access Corpus'Class; ax : Float ); 
  52.  
  53.     -- Sets the acceleration in the Y axis. 
  54.     procedure Set_AY( this : not null access Corpus'Class; ay : Float ); 
  55.  
  56.     -- Sets the clipped attribute of the Corpus. Clipped corps are bounded by 
  57.     -- the wall tiles of the map. 
  58.     procedure Set_Clipped( this    : not null access Corpus'Class; 
  59.                            clipped : Boolean ); 
  60.  
  61.     -- Sets the Corpus' location. No event is queued. 
  62.     procedure Set_Location( this : not null access Corpus'Class; 
  63.                             map  : not null A_Clip_Map; 
  64.                             x, y : Float ); 
  65.  
  66.     -- Sets the physical attribute of the Corpus. Physical corps are affected by 
  67.     -- the forces of gravity and friction. 
  68.     procedure Set_Physical( this     : not null access Corpus'Class; 
  69.                             physical : Boolean ); 
  70.  
  71.     -- Sets the physical size of the Corpus. The Corpus is clipped to 'map' 
  72.     -- immediately. An Entity_Resized event is queued. 
  73.     procedure Set_Size( this   : not null access Corpus'Class; 
  74.                         map    : not null A_Clip_Map; 
  75.                         width, 
  76.                         height : Natural ); 
  77.  
  78.     -- Sets the target velocity in the X axis to accelerate toward. This does 
  79.     -- not have an immediate effect on the velocity. 
  80.     procedure Set_Target_VX( this : not null access Corpus'Class; vx : Float ); 
  81.  
  82.     -- Sets the target velocity in the Y axis to accelerate toward. This does 
  83.     -- not have an immediate effect on the velocity. 
  84.     procedure Set_Target_VY( this : not null access Corpus'Class; vy : Float ); 
  85.  
  86.     -- Sets the Corpus' velocity. 
  87.     procedure Set_Velocity( this : not null access Corpus'Class; vx, vy : Float ); 
  88.  
  89.     -- Ticks the Corpus' changes in velocity and position and performs clipping. 
  90.     -- If 'collide' is returned True then the Corpus location changed and 
  91.     -- collision detection needs to be performed on it. 
  92.     procedure Tick( this    : not null access Corpus'Class; 
  93.                     map     : not null A_Clip_Map; 
  94.                     dt      : Float; 
  95.                     collide : out Boolean ); 
  96.  
  97.     -- Returns a string representation of the Corpus. 
  98.     function To_String( this : access Corpus'Class ) return String; 
  99.  
  100.     -- Deletes the Corpus. 
  101.     procedure Delete( this : in out A_Corpus ); 
  102.     pragma Postcondition( this = null ); 
  103.  
  104. private 
  105.  
  106.     package Corps_Maps is new Ada.Containers.Ordered_Maps( Entity_Id, A_Corpus, "<", "=" ); 
  107.  
  108.     type Corpus is new Object with 
  109.         record 
  110.             manager    : access Physics.Managers.Physics_Manager'Class := null; 
  111.             eid        : Entity_Id := INVALID_ID; 
  112.             width, 
  113.             height     : Natural := 0; 
  114.             width_2, 
  115.             height_2   : Natural := 0; 
  116.             physical   : Boolean := True;    -- apply gravity and friction 
  117.             clipped    : Boolean := True;    -- collide with the world 
  118.             collide    : Boolean := True;    -- need to check for collisions with other corps 
  119.  
  120.             x, y, 
  121.             oldX, oldY : Float := 0.0;       -- old x,y used only during a Tick 
  122.             vx, vy, 
  123.             tvx, tvy, 
  124.             ax, ay     : Float := 0.0; 
  125.             standing   : Boolean := False; 
  126.             touching   : Corps_Maps.Map; 
  127.         end record; 
  128.  
  129.     -- Updates the Corpus' velocity by applying all acting forces, including 
  130.     -- gravity, friction, and target acceleration. 
  131.     procedure Apply_Forces( this : not null access Corpus'Class; dt : Float ); 
  132.  
  133.     -- Clips the Corpus to the solid tile types in 'map', updating the Corpus 
  134.     -- location and zeroing its velocity as necessary. Collision-related events 
  135.     -- will be queued as they are detected. 
  136.     procedure Clip( this : not null access Corpus'Class; map : not null A_Clip_Map ); 
  137.  
  138.     procedure Construct( this     : access Corpus; 
  139.                          id       : Entity_Id; 
  140.                          width, 
  141.                          height   : Natural; 
  142.                          physical : Boolean; 
  143.                          clipped  : Boolean; 
  144.                          manager  : access Physics.Managers.Physics_Manager'Class ); 
  145.  
  146.     procedure Delete( this : in out Corpus ); 
  147.  
  148. end Physics.Bodies;