Advertisement
RefresherTowel

GMS2 AABB Collision Resolution

Oct 30th, 2022
2,168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ///***** Cloned from badwrong: https://pastebin.com/RFmzHY0Z ******
  2. // ******************* CREATE *************************************** //
  3.  
  4. on_ground   = 0;
  5. facing      = 1;
  6. speed_max   = 20;
  7. speed_accel = 5;
  8.  
  9. friction = 4;
  10. gravity  = 6;
  11.  
  12. // You must set the mask_index of the object to something or use the following line:
  13. if (!mask_index) mask_index = sprite_index;
  14.  
  15.  
  16. // ******************* STEP ***************************************** //
  17.  
  18. // Counters
  19. on_ground = on_ground >> 1;
  20.  
  21. // Inputs
  22. var _x_axis = keyboard_check(ord("D")) - keyboard_check(ord("A")),
  23.     _jump   = keyboard_check_pressed(vk_space);
  24.  
  25. // Horizontal movement
  26. if (_x_axis != 0)
  27. {
  28.     facing = sign(_x_axis);
  29.     motion_add(darccos(_x_axis), speed_accel);
  30.    
  31.     // Use motion_set() and no accel value if you want instant movement
  32.     // then add and else branch with hspeed = 0;
  33. }
  34.  
  35. // Set sprite and check for jump
  36. if (on_ground)
  37. {
  38.     if (_jump)
  39.     {
  40.         on_ground = 0;
  41.         motion_add(-gravity_direction, 200);  // Or jump power variable
  42.         image_index  = 0;
  43.     }
  44.     // Here is where you set run or idle sprite (hspeed == 0 ? idle : run )
  45. }
  46. else if (!_jump) vspeed = max(vspeed, vspeed * 0.5);   
  47. /* Here you would add full else { } block of code where you set jump sprite
  48.  * This is one way to stop the jump sprite at the end
  49.  * image_index = min(image_index, image_number - 1);
  50.  */
  51.    
  52.    
  53. // Clamp speeds and set left/right facing direction
  54. image_xscale = facing;
  55. hspeed = clamp(hspeed, -speed_max, speed_max);
  56. vspeed = clamp(vspeed, -200, 200);  // Or some terminal velocity macro
  57. // Adding delta time should be done on the above few lines with hspeed and vspeed
  58. // Multiply them by the change in delta time, i.e., no difference would be 1
  59.  
  60.  
  61.  
  62. // ********** COLLISION EVENT WITH STATIC COLLISION OBJECT ********** //
  63.  
  64. /* General AABB collision algorithm: Move back and resolve collisions per axis.
  65.  *
  66.  * By placing this solution in an actual "collision event" it automatically
  67.  * provides information about each specific collision, as if instance_place_list()
  68.  * were being used.  However, as an internally triggered event the extra overhead and
  69.  * cost of manually checking is eliminated.
  70.  *
  71.  * This solution uses built-in vspeed and hspeed, along with setting the instance
  72.  * variables for gravity and friction.  Note, built-in movement occurs between step and
  73.  * end-step events.  There is no loss of control or scary "black box" to worry about when
  74.  * using such a solution.  This also means automatic acceleration and deceleration if desired.
  75.  */
  76.  
  77. // First store the vector that caused the collision
  78. var _vx = x - xprevious,
  79.     _vy = y - yprevious;
  80. x = xprevious;
  81. y = yprevious;
  82.  
  83. /*
  84.  * With static objects many of the values below can be precomputed on create and assigned to variables.
  85.  * We find exact centers based on bbox and not instance x/y, and
  86.  * collisions are then resolved through the mask offsets
  87.  *
  88.  * This solution does allow for non-centered origins, although it is recommended in most cases.
  89.  * If image_xscale is used to mirror a sprite, then the x-axis should be centered at least.
  90.  */
  91.  
  92. // Horizontal
  93. if place_meeting(x + _vx, y, other)
  94. {
  95.     // Offset by exact values from centers
  96.     if (x < other.x) x = other.bbox_left - sprite_get_width(mask_index) + sprite_get_xoffset(mask_index);
  97.     else x = other.bbox_right + sprite_get_xoffset(mask_index);
  98.    
  99.     // If you want wall jumping an on_wall variable with a sign +/- is appropriate here
  100.    
  101. } else x += _vx;
  102.  
  103. // Vertical
  104. if place_meeting(x, y + _vy, other)
  105. {
  106.     // Same as horizontal but with the y-axis
  107.     if (y < other.y)
  108.     {
  109.         y = other.bbox_top - sprite_get_height(mask_index) + sprite_get_yoffset(mask_index);
  110.         vspeed = 0;
  111.         on_ground = 10; // Or some variable or macro for "coyote frames"
  112.     }
  113.     else
  114.     {
  115.         y = other.bbox_bottom + sprite_get_yoffset(mask_index);
  116.         vspeed *= 0.9; // Don't stop instantly when hitting ceiling
  117.     }
  118.    
  119. } else y += _vy;
  120.  
  121. // And ya, that's like 90% comments and very little code.
  122.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement