Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add object collision classification and resolution functions #197

Open
wants to merge 26 commits into
base: develop
Choose a base branch
from

Conversation

matt439
Copy link
Contributor

@matt439 matt439 commented Dec 13, 2024

Description

While there are numerous functions to detect collisions in the SplashKit library, there are none which classify and resolve collisions between sprites, rectangles, circles, triangles, and quads. I have added two functions to the library: calculate_collision_direction and resolve_collision.

calculate_collision_direction

calculate_collision_direction takes two objects and returns the enumeration collision_direction, indicating what part of the colliding object is being overlapped by the collidee object. It is not entirely accurate as it relies on sprite_collision_rectangle and rectangle_around. This is particularly true with rotated sprites and those using pixel collisions. However, it is robust and will handle any situation, including if one object is enclosed by the other.

resolve_collision

resolve_collision takes two objects and moves the collider so that they are no longer overlapping, without altering their velocities. The direction of collision is passed into the function. Student's are free to use calculate_collision_direction to obtain a direction, or their own methods. The function handles both AABB and pixel collisions. Pixel collisions are resolved iteratively, with the number of iterations being set by BRACKET_ITERATIONS. A possible change would be to allow students to control the number of iterations, emphasizing the precision/performance tradeoff.

Overloads

Both calculate_collision_direction and resolve_collision have 24 overloads each, covering all combinations of sprite, rectangle, circle, triangle, and quad. The number of overloads is necessary as both calculate_collision_direction and resolve_collision are unidirectional functions where the order of the arguments is critical.

Private Functions

I created many helper functions and an enumeration which are not included in collisions.h, as they should not be exposed to students.

Code Duplication

With a large number of overloads, my goal was to minimise duplicated code. This proved difficult as there is no relationship between the object types such as rectangle and circle. It would have been much simpler if they all inherited from IShape and included some member functions. Instead, I made use of void pointers and downcasting to reduce duplicated code. This approach is not ideal as it is more complex and makes debugging more difficult. However, without major changes to the core SplashKit types, I believe it is the best approach.

Additional Intersection Functions

I have added 3 new intersection functions to facilitate all collision combinations: circle_quad_intersect, rectangle_circle_intersect, and triangle_quad_intersect.

Bug Fix in line_intersects_rect

line_intersects_rect returns false when the line is contained within the rectangle. This bug has been rectified.

Type of change

  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

I altered test_sprites.cpp to include two more sprites in the basic test: s3 uses pixel-based collision and s4 uses AABB collision. When the player-controlled sprite collides with s3 or s4, classify_collision_direction and resolve_collision will be called to resolve the collision. In addition, the collision_direction is graphically shown on the player-controlled sprite as a red outline.

I have also added a second sprite test to test_sprites.cpp which allows for complete testing of all 25 overloads.

Keys 1 to 5 change the collider object:

  1. Sprite using pixel collisions
  2. Rectangle
  3. Circle
  4. Triangle
  5. Quad

Keys 6 to - change the environment:
6. Default environment where classify_collision_direction is called before resolve_collision.
7. The collision_direction is fixed for each sprite in the cardinal directions.
8. The collision_direction is fixed for each rectangle in the cardinal directions.
9. The collision_direction is fixed for each circle in the cardinal directions.
0. The collision_direction is fixed for each triangle in the cardinal directions.
-. The collision_direction is fixed for each quad in the cardinal directions.

The 3 new intersection functions and line_intersects_rect have been tested with unit tests. The tests are contained within unit_tests_geometry.cpp. Adding the new tests was achieved by running cmake -G "Unix Makefiles" . followed by make when in the /splashkit-core/projects/cmake directory. These additional tests will be merged with the other geometry unit tests in #196 as they use the same formatting.

Testing Checklist

  • Tested with sktest
  • Tested with skunit_tests

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code in hard-to-understand areas
  • My changes generate no new warnings

@matt439 matt439 changed the title Collision resolver Add object collision classification and resolution functions Dec 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant