{"id":29891221,"url":"https://github.com/dotnet-ad/humper","last_synced_at":"2025-08-01T00:38:06.781Z","repository":{"id":81440686,"uuid":"67285375","full_name":"dotnet-ad/Humper","owner":"dotnet-ad","description":"Collision detection for Axis-Aligned-Bounding-Boxes (aka AABB) in C#.","archived":false,"fork":false,"pushed_at":"2024-01-18T09:24:14.000Z","size":3385,"stargazers_count":115,"open_issues_count":7,"forks_count":19,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-07-19T23:58:26.203Z","etag":null,"topics":["aabb","game","physics"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dotnet-ad.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-09-03T10:51:01.000Z","updated_at":"2025-06-26T22:09:52.000Z","dependencies_parsed_at":null,"dependency_job_id":"a8e0a609-2b53-4fec-b457-f95ea30b6ff4","html_url":"https://github.com/dotnet-ad/Humper","commit_stats":null,"previous_names":["aloisdeniel/humper"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dotnet-ad/Humper","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dotnet-ad%2FHumper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dotnet-ad%2FHumper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dotnet-ad%2FHumper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dotnet-ad%2FHumper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dotnet-ad","download_url":"https://codeload.github.com/dotnet-ad/Humper/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dotnet-ad%2FHumper/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268147524,"owners_count":24203281,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-31T02:00:08.723Z","response_time":66,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aabb","game","physics"],"created_at":"2025-08-01T00:38:04.463Z","updated_at":"2025-08-01T00:38:06.766Z","avatar_url":"https://github.com/dotnet-ad.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Humper\n\nCollision detection only for **Axis-Aligned-Bounding-Boxes** (*aka AABB*).\n\nThis library isn't a fully featured physics engine : don't expect a realistic physics simulation but it could be enough for basic game physics (platformer games, top-down games, shoot-em-ups). Though, Humper has spatial hashing for better performances and all the necessary moving and collision test tools needed for building a 2D game.\n\nThe library doesn't rely on any particular framework, its pure C# with all needed types included. It is fairly easy to integrate with existing frameworks like [Monogame](http://www.monogame.net/).\n\n## Install\n\nAvailable on NuGet\n\n[![NuGet](https://img.shields.io/nuget/v/Humper.svg?label=NuGet)](https://www.nuget.org/packages/Humper/)\n\n## Quickstart\n\n![Schema](./Documentation/Quickstart.png)\n\n```csharp\nvar world = new World(500, 300);\n\n// Create a box of size (20,20) at position (100,100)\nvar body = world.Create(100, 100, 20, 20);\n\n// Create a second box\nworld.Create(50, 150, 100, 100);\n\n// Try to move the box to (100,200) with a slide movement for every other collided body of the world\nvar result = body.Move(170,200, (collision) =\u003e CollisionResponses.Slide);\n\n// React to collisions\nif(result.HasCollided)\n{\n\tDebug.WriteLine(\"Body collided!\");\n}\n```\n\n## Basic APIs\n\n### IWorld\n\nThe world is a virtual representation of your physics environnement. It manages all bodies and have a given size.\n\nThe world is subdivided in cells of `64` by default to faster collision calculation, but you can also change this parameter at instanciation.\n\n#### `IBox Create(float x, float y, float width, float height)`\n\nCreate a new box in the world.\n\n#### `bool Remove(IBox box)`\n\nRemove the specified box from the world.\n\n#### `IBox Find(float x, float y, float width, float height)`\n\nFind the boxes contained in the given area of the world.\n\n#### `IHit Hit(Vector2 point, IEnumerable\u003cIBox\u003e ignoring = null)`\n\nQueries the world to find the nearest colliding point from a given position.\n\n#### `IHit Hit(Vector2 origin, Vector2 destination, IEnumerable\u003cIBox\u003e ignoring = null)`\n\nQueries the world to find the nearest colliding position from an oriented segment.\n\n#### `IHit Hit(RectangleF origin, RectangleF destination, IEnumerable\u003cIBox\u003e ignoring = null)`\n\nQueries the world to find the nearest colliding position from a moving rectangle.\n \n### IBox\n\nA box represents any object of your physical world as an Axis-Aligned-Bounding-Boxes (*a rectangle that cannot be rotated*).\n\n#### `float X { get; }`\n\nThe top left corner X coordinate of the box.\n\n#### `float Y { get; }`\n\nThe top left corner Y coordinate of the box.\n\n#### `float Height { get; }`\n\nThe height of the box.\n\n#### `float Width { get; }`\n\nThe width of the box.\n\n#### `IMovement Move(float x, float y, Func\u003cICollision, CollisionResponses\u003e filter)`\n\nTriggers a movement of the box in the physical world from its current position to the given one. The filters should indicate how the box reacts when colliding with another box of the world (see `Responses` section for more info).\n\n#### `IMovement Simulate(float x, float y, Func\u003cICollision, ICollisionResponse\u003e filter)`\n\nSimulates the move of the box to the specified coordinates with collisition simulation (the boxe's position isn't altered at all).\n\n#### `IBox AddTags(params Enum[] newTags)`\n\nAdd enumeration flags to the box.\n\n#### `bool HasTag(params Enum[] values)`\n\nIndicates whether the box has at least one of the given tags.\n\n#### `bool HasTags(params Enum[] values)`\n\nIndicates whether the box has all of the given tags.\n\n#### `object Data { get; set; }`\n\nCustom user data that can be attached to the box.\n\n### ICollision\n\nA collision represents the result of a movement query that resulted in a collision and that need to be resolved to a response.\n\n#### `IBox Box { get; }`\n\nThe box that moved.\n\n#### `IBox Other { get; }`\n\nThe other box than being collided by the moving box.\n\n#### `RectangleF Origin { get; }`\n\nThe starting position of the moving box.\n\n#### `RectangleF Goal { get; }`\n\nThe intialy requested goal destination for the moving box.\n\n#### `Hit Hit { get; }`\n\nGets information about the impact point.\n\n### IHit\n\nAn hit point represents the impact with a box of the world.\n\n#### `IBox Box { get; }`\n\t\t\nGets the collided box.\n\n#### `Vector2 Normal { get; set; }`\n\nThe normal vector of the collided box side.\n\n#### `float Amount { get; set; }`\n\nThe amount of movement needed from origin to get the impact position.\n\n#### `RectangleF Position { get; set; }`\n\nThe impact position.\n\n#### `float Remaining { get; }`\n\nThe amount of movement needed from impact position to get the requested initial goal position.\n\n### Responses\n\nWhen moving a box, a response should be returned through a filter to indicate how this box should react to a collision with another box.\n\nSeveral `CollisionResponses` are included :\n\n#### `None`\n\n![Schema](./Documentation/None.png)\n\nAll collisions are ignored.\n\n#### `Touch`\n\n![Schema](./Documentation/Touch.png)\n\nThe box moves to the collision impact position.\n\n#### `Cross`\n\n![Schema](./Documentation/Cross.png)\n\nThe box moves through and ignore collision.\n\n#### `Slide`\n\n![Schema](./Documentation/Slide.png)\n\nThe box slides on the collided side of the other box.\n\n#### `Bounce`\n\n![Schema](./Documentation/Bounce.png)\n\nThe box is reflected from the side of the other box.\n\n#### `Custom`\n\nA custom implementation of `ICollisionResponse` can also be provided if needed.\n\n### Debug layer\n\nA debug layer is provided if you want to draw the boxes : you only have to provide basic drawing functions to the world `DrawDebug` method.\n\nAn example [Monogame](http://www.monogame.net/) implementation : \n\n```csharp\nprivate void DrawCell(int x, int y, int w, int h, float alpha)\n{\n\tspriteBatch.Draw(pixelTexture, pixelTexture.Bounds, new Rectangle(x,y,w,h), new Color(Color.White,alpha));\n}\n\nprivate void DrawBox(IBox box)\n{\n\tspriteBatch.Draw(pixelTexture, pixelTexture.Bounds, box.Bounds.ToRectangle(), Color.Green);\n}\n\nprivate void DrawString(string message, int x, int y, float alpha)\n{\n\tvar size = this.font.MeasureString(message);\n\tspriteBatch.DrawString(this.font, message, new Vector2( x - size.X / 2, y - size.Y / 2), new Color(Color.White, alpha));\n}\n```\n\n```csharp\nprotected override void Draw(GameTime gameTime)\n{\n\tgraphics.GraphicsDevice.Clear(Color.Black);\n\tspriteBatch.Begin(blendState: BlendState.NonPremultiplied);\n\tvar b = world.Bounds;\n\tworld.DrawDebug((int)b.X, (int)b.Y, (int)b.Width, (int)b.Height, DrawCell, DrawBox, DrawString);\n\tspriteBatch.End();\n\tbase.Draw(gameTime);\n}\n```\n\n## Samples\n\n![Video](./Documentation/Samples.gif)\n\nCheck the samples if you wish to implement a :\n\n* `Top-down`\n* `Platformer`\n\n## Ideas / Roadmap\n\n* Add resizing\n* Improve documentation\n* Optimize code\n\n## Thanks\n\n* [gamedev.net-SweptAABB](http://www.gamedev.net/page/resources/_/technical/game-programming/swept-aabb-collision-detection-and-response-r3084)\n* [bump.lua](https://github.com/kikito/bump.lua)\n\n## Contributions\n\nContributions are welcome! If you find a bug please report it and if you want a feature please report it.\n\nIf you want to contribute code please file an issue and create a branch off of the current dev branch and file a pull request.\n\n### License\n\nMIT © [Aloïs Deniel](http://aloisdeniel.github.io)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdotnet-ad%2Fhumper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdotnet-ad%2Fhumper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdotnet-ad%2Fhumper/lists"}