{"id":15103983,"url":"https://github.com/a327ex/windfield","last_synced_at":"2025-09-27T02:32:15.698Z","repository":{"id":49792274,"uuid":"42110432","full_name":"a327ex/windfield","owner":"a327ex","description":"Physics module for LÖVE","archived":true,"fork":false,"pushed_at":"2020-04-14T23:46:26.000Z","size":3636,"stargazers_count":449,"open_issues_count":11,"forks_count":55,"subscribers_count":14,"default_branch":"master","last_synced_at":"2024-09-26T20:02:13.022Z","etag":null,"topics":["box2d","game-development","love2d","lua","physics"],"latest_commit_sha":null,"homepage":null,"language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/a327ex.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-09-08T12:21:21.000Z","updated_at":"2024-09-23T04:57:57.000Z","dependencies_parsed_at":"2022-09-12T15:22:58.858Z","dependency_job_id":null,"html_url":"https://github.com/a327ex/windfield","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a327ex%2Fwindfield","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a327ex%2Fwindfield/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a327ex%2Fwindfield/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a327ex%2Fwindfield/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/a327ex","download_url":"https://codeload.github.com/a327ex/windfield/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234376916,"owners_count":18822416,"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","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":["box2d","game-development","love2d","lua","physics"],"created_at":"2024-09-25T20:00:19.284Z","updated_at":"2025-09-27T02:32:10.443Z","avatar_url":"https://github.com/a327ex.png","language":"Lua","readme":"**windfield** is a physics module for LÖVE. It wraps LÖVE's physics API so that using box2d becomes as simple as possible.\r\n\r\n# Contents\r\n\r\n* [Quick Start](#quick-start)\r\n   * [Create a world](#create-a-world)\r\n   * [Create colliders](#create-colliders)\r\n   * [Create joints](#create-joints)\r\n   * [Create collision classes](#create-collision-classes)\r\n   * [Capture collision events](#capture-collision-events)\r\n   * [Query the world](#query-the-world)\r\n* [Examples \u0026 Tips](#examples-tips)\r\n   * [Checking collisions between game objects](#checking-collisions-between-game-objects)\r\n   * [One-way Platforms](#one-way-platforms)\r\n* [Documentation](#documentation)\r\n   * [World](#world)\r\n      * [newWorld](#newworldxg-yg-sleep)\r\n      * [update](#updatedt)\r\n      * [draw](#drawalpha)\r\n      * [destroy](#destroy)\r\n      * [addCollisionClass](#addcollisionclasscollision_class_name-collision_class)\r\n      * [newCircleCollider](#newcirclecolliderx-y-r)\r\n      * [newRectangleCollider](#newrectanglecolliderx-y-w-h)\r\n      * [newBSGRectangleCollider](#newbsgrectanglecolliderx-y-w-h-corner_cut_size)\r\n      * [newPolygonCollider](#newpolygoncollidervertices)\r\n      * [newLineCollider](#newlinecolliderx1-y1-x2-y2)\r\n      * [newChainCollider](#newchaincollidervertices-loop)\r\n      * [queryCircleArea](#querycircleareax-y-r-collision_class_name)\r\n      * [queryRectangleArea](#queryrectangleareax-y-w-h-collision_class_names)\r\n      * [queryPolygonArea](#querypolygonareavertices-collision_class_names)\r\n      * [queryLine](#querylinex1-y1-x2-y2-collision_class_names)\r\n      * [addJoint](#addjointjoint_type)\r\n      * [removeJoint](#removejointjoint)\r\n      * [setExplicitCollisionEvents](#setexplicitcollisioneventsvalue)\r\n      * [setQueryDebugDrawing](#setquerydebugdrawingvalue)\r\n   * [Collider](#collider)\r\n      * [destroy](#destroy-1)\r\n      * [setCollisionClass](#setcollisionclasscollision_class_name)\r\n      * [enter](#enterother_collision_class_name)\r\n      * [getEnterCollisionData](#getentercollisiondataother_collision_class_name)\r\n      * [exit](#exitother_collision_class_name)\r\n      * [getExitCollisionData](#getexitcollisiondataother_collision_class_name)\r\n      * [stay](#stayother_collision_class_name)\r\n      * [getStayCollisionData](#getstaycollisiondataother_collision_class_name)\r\n      * [setPreSolve](#setpresolvecallback)\r\n      * [setPostSolve](#setpostsolvecallback)\r\n      * [addShape](#addshapeshape_name-shape_type)\r\n      * [removeShape](#removeshapeshape_name)\r\n      * [setObject](#setobjectobject)\r\n      * [getObject](#getobject)\r\n      \r\n\u003cbr\u003e\r\n\r\n# Quick Start\r\n\r\nPlace the `windfield` folder inside your project and require it:\r\n\r\n```lua\r\nwf = require 'windfield'\r\n```\r\n\r\n\u003cbr\u003e\r\n\r\n## Create a world\r\n\r\nA physics world can be created just like in box2d. The world returned by `wf.newWorld` contains all the functions of a [LÖVE physics World](https://love2d.org/wiki/World) as well as additional ones defined by this library.\r\n\r\n```lua\r\nfunction love.load()\r\n    world = wf.newWorld(0, 0, true)\r\n    world:setGravity(0, 512)\r\nend\r\n\r\nfunction love.update(dt)\r\n    world:update(dt)\r\nend\r\n```\r\n\r\n\u003cbr\u003e\r\n\r\n## Create colliders\r\n\r\nA collider is a composition of a single body, fixture and shape. For most use cases whenever box2d is needed a body will only have one fixture/shape attached to it, so it makes sense to work primarily on that level of abstraction. Colliders contain all the functions of a LÖVE physics [Body](https://love2d.org/wiki/Body), [Fixture](https://love2d.org/wiki/Fixture) and [Shape](https://love2d.org/wiki/Shape) as well as additional ones defined by this library:\r\n\r\n```lua\r\nfunction love.load()\r\n    ...\r\n\r\n    box = world:newRectangleCollider(400 - 50/2, 0, 50, 50)\r\n    box:setRestitution(0.8)\r\n    box:applyAngularImpulse(5000)\r\n\r\n    ground = world:newRectangleCollider(0, 550, 800, 50)\r\n    wall_left = world:newRectangleCollider(0, 0, 50, 600)\r\n    wall_right = world:newRectangleCollider(750, 0, 50, 600)\r\n    ground:setType('static') -- Types can be 'static', 'dynamic' or 'kinematic'. Defaults to 'dynamic'\r\n    wall_left:setType('static')\r\n    wall_right:setType('static')\r\nend\r\n\r\n...\r\n\r\nfunction love.draw()\r\n    world:draw() -- The world can be drawn for debugging purposes\r\nend\r\n```\r\n\r\nAnd that looks like this:\r\n\r\n\u003cp align=\"center\"\u003e\r\n  \u003cimg src=\"http://i.imgur.com/ytfhmjc.gif\"/\u003e\r\n\u003c/p\u003e\r\n\r\n\u003cbr\u003e\r\n\r\n## Create joints\r\n\r\nJoints are mostly unchanged from how they work normally in box2d:\r\n\r\n```lua\r\nfunction love.load()\r\n    ...\r\n\r\n    box_1 = world:newRectangleCollider(400 - 50/2, 0, 50, 50)\r\n    box_1:setRestitution(0.8)\r\n    box_2 = world:newRectangleCollider(400 - 50/2, 50, 50, 50)\r\n    box_2:setRestitution(0.8)\r\n    box_2:applyAngularImpulse(5000)\r\n    joint = world:addJoint('RevoluteJoint', box_1, box_2, 400, 50, true)\r\n\r\n    ...\r\nend\r\n```\r\n\r\nAnd that looks like this:\r\n\r\n\u003cp align=\"center\"\u003e\r\n  \u003cimg src=\"http://i.imgur.com/tSqkxJR.gif\"/\u003e\r\n\u003c/p\u003e\r\n\r\n\u003cbr\u003e\r\n\r\n## Create collision classes\r\n\r\nCollision classes are used to make colliders ignore other colliders of certain classes and to capture collision events between colliders. The same concept goes by the name of 'collision layer' or 'collision tag' in other engines. In the example below we add a Solid and Ghost collision class. The Ghost collision class is set to ignore the Solid collision class.\r\n\r\n```lua\r\nfunction love.load()\r\n    ...\r\n\r\n    world:addCollisionClass('Solid')\r\n    world:addCollisionClass('Ghost', {ignores = {'Solid'}})\r\n\r\n    box_1 = world:newRectangleCollider(400 - 100, 0, 50, 50)\r\n    box_1:setRestitution(0.8)\r\n    box_2 = world:newRectangleCollider(400 + 50, 0, 50, 50)\r\n    box_2:setCollisionClass('Ghost')\r\n\r\n    ground = world:newRectangleCollider(0, 550, 800, 50)\r\n    ground:setType('static')\r\n    ground:setCollisionClass('Solid')\r\n\r\n    ...\r\nend\r\n```\r\n\r\nAnd that looks like this:\r\n\r\n\u003cp align=\"center\"\u003e\r\n  \u003cimg src=\"http://i.imgur.com/j7IhVSe.gif\"/\u003e\r\n\u003c/p\u003e\r\n\r\nThe box that was set be of the Ghost collision class ignored the ground and went right through it, since the ground is set to be of the Solid collision class.\r\n\r\n\u003cbr\u003e\r\n\r\n## Capture collision events\r\n\r\nCollision events can be captured inside the update function by calling the `enter`, `exit` or `stay` functions of a collider. In the example below, whenever the box collider enters contact with another collider of the Solid collision class it will get pushed to the right:\r\n\r\n```lua\r\nfunction love.update(dt)\r\n    ...\r\n    if box:enter('Solid') then\r\n        box:applyLinearImpulse(1000, 0)\r\n        box:applyAngularImpulse(5000)\r\n    end\r\nend\r\n```\r\n\r\nAnd that looks like this:\r\n\r\n\u003cp align=\"center\"\u003e\r\n  \u003cimg src=\"http://i.imgur.com/uF1bqKM.gif\"/\u003e\r\n\u003c/p\u003e\r\n\r\n\u003cbr\u003e\r\n\r\n## Query the world\r\n\r\nThe world can be queried with a few area functions and then all colliders inside that area will be returned. In the example below, the world is queried at position 400, 300 with a circle of radius 100, and then all colliders in that area are pushed to the right and down.\r\n\r\n```lua\r\nfunction love.load()\r\n    world = wf.newWorld(0, 0, true)\r\n    world:setQueryDebugDrawing(true) -- Draws the area of a query for 10 frames\r\n\r\n    colliders = {}\r\n    for i = 1, 200 do\r\n        table.insert(colliders, world:newRectangleCollider(love.math.random(0, 800), love.math.random(0, 600), 25, 25))\r\n    end\r\nend\r\n\r\nfunction love.update(dt)\r\n    world:update(dt)\r\nend\r\n\r\nfunction love.draw()\r\n    world:draw()\r\nend\r\n\r\nfunction love.keypressed(key)\r\n    if key == 'p' then\r\n        local colliders = world:queryCircleArea(400, 300, 100)\r\n        for _, collider in ipairs(colliders) do\r\n            collider:applyLinearImpulse(1000, 1000)\r\n        end\r\n    end\r\nend\r\n```\r\n\r\nAnd that looks like this:\r\n\r\n\u003cp align=\"center\"\u003e\r\n  \u003cimg src=\"http://i.imgur.com/YVxAiuu.gif\"/\u003e\r\n\u003c/p\u003e\r\n\r\n\u003cbr\u003e\r\n\r\n# Examples \u0026 Tips\r\n\r\n## Checking collisions between game objects\r\n\r\nThe most common use case for a physics engine is doing things when things collide. For instance, when the Player collides with an enemy you might want to deal damage to the player. Here's the way to achieve that with this library:\r\n\r\n\r\n```lua\r\n-- in Player.lua\r\nfunction Player:new()\r\n  self.collider = world:newRectangleCollider(...)\r\n  self.collider:setCollisionClass('Player')\r\n  self.collider:setObject(self)\r\nend\r\n\r\n-- in Enemy.lua\r\nfunction Enemy:new()\r\n  self.collider = world:newRectangleCollider(...)\r\n  self.collider:setCollisionClass('Enemy')\r\n  self.collider:setObject(self)\r\nend\r\n```\r\n\r\nFirst we define in the constructor of both classes the collider that should be attached to them. We set their collision classes (Player and Enemy) and then link the object to the colliders with `setObject`. With this, we can capture collision events between both and then do whatever we wish when a collision happens:\r\n\r\n```lua\r\n-- in Player.lua\r\nfunction Player:update(dt)\r\n  if self.collider:enter('Enemy') then\r\n    local collision_data = self.collider:getEnterCollisionData('Enemy')\r\n    local enemy = collision_data.collider:getObject()\r\n    -- Kills the enemy on hit but also take damage\r\n    enemy:die()\r\n    self:takeDamage(10)\r\n  end\r\nend\r\n```\r\n\r\n\u003cbr\u003e\r\n\r\n## One-way Platforms\r\n\r\nA common problem people have with using 2D physics engines seems to be getting one-way platforms to work. Here's one way to achieve this with this library:\r\n\r\n```lua\r\nfunction love.load()\r\n  world = wf.newWorld(0, 512, true)\r\n  world:addCollisionClass('Platform')\r\n  world:addCollisionClass('Player')\r\n  \r\n  ground = world:newRectangleCollider(100, 500, 600, 50)\r\n  ground:setType('static')\r\n  platform = world:newRectangleCollider(350, 400, 100, 20)\r\n  platform:setType('static')\r\n  platform:setCollisionClass('Platform')\r\n  player = world:newRectangleCollider(390, 450, 20, 40)\r\n  player:setCollisionClass('Player')\r\n  \r\n  player:setPreSolve(function(collider_1, collider_2, contact)        \r\n    if collider_1.collision_class == 'Player' and collider_2.collision_class == 'Platform' then\r\n      local px, py = collider_1:getPosition()            \r\n      local pw, ph = 20, 40            \r\n      local tx, ty = collider_2:getPosition() \r\n      local tw, th = 100, 20\r\n      if py + ph/2 \u003e ty - th/2 then contact:setEnabled(false) end\r\n    end   \r\n  end)\r\nend\r\n\r\nfunction love.keypressed(key)\r\n  if key == 'space' then\r\n    player:applyLinearImpulse(0, -1000)\r\n  end\r\nend\r\n```\r\n\r\nAnd that looks like this:\r\n\r\n\u003cp align=\"center\"\u003e\r\n  \u003cimg src=\"http://i.imgur.com/ouwxVRH.gif\"/\u003e\r\n\u003c/p\u003e\r\n\r\nThe way this works is that by disabling the contact before collision response is applied (so in the preSolve callback) we can make a collider ignore another. And then all we do is check to see if the player is below platform, and if he is then we disable the contact.\r\n\r\n\u003cbr\u003e\r\n\r\n# Documentation\r\n\r\n## World\r\n\r\nOn top of containing all functions exposed in this documentation it also contains all functions of a [box2d World](https://love2d.org/wiki/World).\r\n\r\n---\r\n\r\n#### `.newWorld(xg, yg, sleep)`\r\n\r\nCreates a new World.\r\n\r\n```lua\r\nworld = wf.newWorld(0, 0, true)\r\n```\r\n\r\nArguments:\r\n\r\n* `xg` `(number)` - The world's x gravity component\r\n* `yg` `(number)` - The world's y gravity component\r\n* `sleep=true` `(boolean)` - If the world's bodies are allowed to sleep or not\r\n\r\nReturns:\r\n\r\n* `World` `(table)` - the World object, containing all attributes and methods defined below as well as all of a [box2d World](https://love2d.org/wiki/World)\r\n\r\n\r\n---\r\n\r\n#### `:update(dt)`\r\n\r\nUpdates the world.\r\n\r\n```lua\r\nworld:update(dt)\r\n```\r\n\r\nArguments:\r\n\r\n* `dt` `(number)` - The time step delta\r\n\r\n---\r\n\r\n#### `:draw(alpha)`\r\n\r\nDraws the world, drawing all colliders, joints and world queries (for debugging purposes).\r\n\r\n```lua\r\nworld:draw() -- default drawing\r\nworld:draw(128) -- semi transparent drawing\r\n```\r\n\r\nArguments:\r\n\r\n* `alpha=255` `(number)` - The optional alpha value to use when drawing, defaults to 255\r\n\r\n---\r\n\r\n#### `:destroy()`\r\n\r\nDestroys the world and removes all bodies, fixtures, shapes and joints from it. This must be called whenever the World is to discarded otherwise it will result in it not getting collected (and so memory will leak).\r\n\r\n```lua\r\nworld:destroy()\r\n```\r\n\r\n---\r\n\r\n#### `:addCollisionClass(collision_class_name, collision_class)`\r\n\r\nAdds a new collision class to the World. Collision classes are attached to Colliders and defined their behaviors in terms of which ones will physically ignore each other and which ones will generate collision events between each other. All collision classes must be added before any Collider is created. If `world:setExplicitCollisionEvents` is set to false (the default setting) then `enter`, `exit`, `pre` and `post` settings don't need to be specified, otherwise they do.\r\n```lua\r\nworld:addCollisionClass('Player', {ignores = {'NPC', 'Enemy'}})\r\n```\r\n\r\nArguments:\r\n\r\n* `collision_class_name` `(string)` - The unique name of the collision class\r\n* `collision_class` `(table)` - The collision class. This table can contain:\r\n\r\nSettings:\r\n\r\n* `[ignores]` `(table[string])` - The collision classes that will be physically ignored\r\n* `[enter]` `(table[string])` - The collision classes that will generate collision events with the collider of this collision class when they enter contact with each other\r\n* `[exit]` `(table[string])` - The collision classes that will generate collision events with the collider of this collision class when they exit contact with each other\r\n* `[pre]` `(table[string])` - The collision classes that will generate collision events with the collider of this collision class right before collision response is applied\r\n* `[post]` `(table[string])` - The collision classes that will generate collision events with the collider of this collision class right after collision response is applied\r\n\r\n---\r\n\r\n#### `:newCircleCollider(x, y, r)`\r\n\r\nCreates a new CircleCollider.\r\n\r\n```lua\r\ncircle = world:newCircleCollider(100, 100, 30)\r\n```\r\n\r\nArguments:\r\n\r\n* `x` `(number)` - The x position of the circle's center\r\n* `y` `(number)` - The y position of the circle's center\r\n* `r` `(number)` - The radius of the circle\r\n\r\nReturns:\r\n\r\n* `Collider` `(table)` - The newly created CircleCollider\r\n\r\n---\r\n\r\n#### `:newRectangleCollider(x, y, w, h)`\r\n\r\nCreates a new RectangleCollider.\r\n\r\n```lua\r\nrectangle = world:newRectangleCollider(100, 100, 50, 50)\r\n```\r\n\r\nArguments:\r\n\r\n* `x` `(number)` - The x position of the rectangle's top-left corner\r\n* `y` `(number)` - The y position of the rectangle's top-left corner\r\n* `w` `(number)` - The width of the rectangle\r\n* `h` `(number)` - The height of the rectangle\r\n\r\nReturns:\r\n\r\n* `Collider` `(table)` - The newly created RectangleCollider\r\n\r\n---\r\n\r\n#### `:newBSGRectangleCollider(x, y, w, h, corner_cut_size)`\r\n\r\nCreates a new BSGRectangleCollider, which is a rectangle with its corners cut (an octagon).\r\n\r\n```lua\r\nbsg_rectangle = world:newBSGRectangleCollider(100, 100, 50, 50, 5)\r\n```\r\n\r\nArguments:\r\n\r\n* `x` `(number)` - The x position of the rectangle's top-left corner\r\n* `y` `(number)` - The y position of the rectangle's top-left corner\r\n* `w` `(number)` - The width of the rectangle\r\n* `h` `(number)` - The height of the rectangle\r\n* `corner_cut_size` `(number)` - The corner cut size\r\n\r\nReturns:\r\n\r\n* `Collider` `(table)` - The newly created BSGRectangleCollider\r\n\r\n---\r\n\r\n#### `:newPolygonCollider(vertices)`\r\n\r\nCreates a new PolygonCollider.\r\n\r\n```lua\r\npolygon = world:newPolygonCollider({10, 10, 10, 20, 20, 20, 20, 10})\r\n```\r\n\r\nArguments:\r\n\r\n* `vertices` `(table[number])` - The polygon vertices as a table of numbers\r\n\r\nReturns:\r\n\r\n* `Collider` `(table)` - The newly created PolygonCollider\r\n\r\n---\r\n\r\n#### `:newLineCollider(x1, y1, x2, y2)`\r\n\r\nCreates a new LineCollider.\r\n\r\n```lua\r\nline = world:newLineCollider(100, 100, 200, 200)\r\n```\r\n\r\nArguments:\r\n\r\n* `x1` `(number)` - The x position of the first point of the line\r\n* `y1` `(number)` - The y position of the first point of the line\r\n* `x2` `(number)` - The x position of the second point of the line\r\n* `y2` `(number)` - The y position of the second point of the line\r\n\r\nReturns:\r\n\r\n* `Collider` `(table)` - The newly created LineCollider\r\n\r\n---\r\n\r\n#### `:newChainCollider(vertices, loop)`\r\n\r\nCreates a new ChainCollider.\r\n\r\n```lua\r\nchain = world:newChainCollider({10, 10, 10, 20, 20, 20}, true)\r\n```\r\n\r\nArguments:\r\n\r\n* `vertices` `(table[number])` - The chain vertices as a table of numbers\r\n* `loop` `(boolean)` - If the chain should loop back from the last to the first point\r\n\r\nReturns:\r\n\r\n* `Collider` `(table)` - The newly created ChainCollider\r\n\r\n---\r\n\r\n#### `:queryCircleArea(x, y, r, collision_class_names)`\r\n\r\nQueries a circular area around a point for colliders.\r\n\r\n```lua\r\ncolliders_1 = world:queryCircleArea(100, 100, 50, {'Enemy', 'NPC'})\r\ncolliders_2 = world:queryCircleArea(100, 100, 50, {'All', except = {'Player'}})\r\n```\r\n\r\nArguments:\r\n\r\n* `x` `(number)` - The x position of the circle's center\r\n* `y` `(number)` - The y position of the circle's center\r\n* `r` `(number)` - The radius of the circle\r\n* `[collision_class_names='All']` `(table[string])` - A table of strings with collision class names to be queried. The special value `'All'` (default) can be used to query for all existing collision classes. Another special value `except` can be used to exclude some collision classes when `'All'` is used.\r\n\r\nReturns:\r\n\r\n* `table[Collider]` - The table of colliders with the specified collision classes inside the area\r\n\r\n---\r\n\r\n#### `:queryRectangleArea(x, y, w, h, collision_class_names)`\r\n\r\nQueries a rectangular area for colliders.\r\n\r\n```lua\r\ncolliders_1 = world:queryRectangleArea(100, 100, 50, 50, {'Enemy', 'NPC'})\r\ncolliders_2 = world:queryRectangleArea(100, 100, 50, 50, {'All', except = {'Player'}})\r\n```\r\n\r\nArguments:\r\n\r\n* `x` `(number)` - The x position of the rectangle's top-left corner\r\n* `y` `(number)` - The y position of the rectangle's top-left corner\r\n* `w` `(number)` - The width of the rectangle\r\n* `h` `(number)` - The height of the rectangle\r\n* `[collision_class_names='All']` `(table[string])` - A table of strings with collision class names to be queried. The special value `'All'` (default) can be used to query for all existing collision classes. Another special value `except` can be used to exclude some collision classes when `'All'` is used.\r\n\r\nReturns:\r\n\r\n* `table[Collider]` - The table of colliders with the specified collision classes inside the area\r\n\r\n---\r\n\r\n#### `:queryPolygonArea(vertices, collision_class_names)`\r\n\r\nQueries a polygon area for colliders.\r\n\r\n```lua\r\ncolliders_1 = world:queryPolygonArea({10, 10, 20, 10, 20, 20, 10, 20}, {'Enemy'})\r\ncolliders_2 = world:queryPolygonArea({10, 10, 20, 10, 20, 20, 10, 20}, {'All', except = {'Player'}})\r\n```\r\n\r\nArguments:\r\n\r\n* `vertices` `(table[number])` - The polygon vertices as a table of numbers\r\n* `[collision_class_names='All']` `(table[string])` - A table of strings with collision class names to be queried. The special value `'All'` (default) can be used to query for all existing collision classes. Another special value `except` can be used to exclude some collision classes when `'All'` is used.\r\n\r\nReturns:\r\n\r\n* `table[Collider]` - The table of colliders with the specified collision classes inside the area\r\n\r\n---\r\n\r\n#### `:queryLine(x1, y1, x2, y2, collision_class_names)`\r\n\r\nQueries for colliders that intersect with a line.\r\n\r\n```lua\r\ncolliders_1 = world:queryLine(100, 100, 200, 200, {'Enemy', 'NPC', 'Projectile'})\r\ncolliders_2 = world:queryLine(100, 100, 200, 200, {'All', except = {'Player'}})\r\n```\r\n\r\nArguments:\r\n\r\n* `x1` `(number)` - The x position of the first point of the line\r\n* `y1` `(number)` - The y position of the first point of the line\r\n* `x2` `(number)` - The x position of the second point of the line\r\n* `y2` `(number)` - The y position of the second point of the line\r\n* `[collision_class_names='All']` `(table[string])` - A table of strings with collision class names to be queried. The special value `'All'` (default) can be used to query for all existing collision classes. Another special value `except` can be used to exclude some collision classes when `'All'` is used.\r\n\r\nReturns:\r\n\r\n* `table[Collider]` - The table of colliders with the specified collision classes inside the area\r\n\r\n---\r\n\r\n#### `:addJoint(joint_type, ...)`\r\n\r\nAdds a joint to the world.\r\n\r\n```lua\r\njoint = world:addJoint('RevoluteJoint', collider_1, collider_2, 50, 50, true)\r\n```\r\n\r\nArguments:\r\n\r\n* `joint_type` `(string)` - The joint type, it can be `'DistanceJoint'`, `'FrictionJoint'`, `'GearJoint'`, `'MouseJoint'`, `'PrismaticJoint'`, `'PulleyJoint'`, `'RevoluteJoint'`, `'RopeJoint'`, `'WeldJoint'` or `'WheelJoint'`\r\n* `...` `(*)` - The joint creation arguments that are different for each joint type, check [here](https://love2d.org/wiki/Joint) for more details\r\n\r\nReturns:\r\n\r\n* `joint` `(Joint)` - The newly created Joint\r\n\r\n---\r\n\r\n#### `:removeJoint(joint)`\r\n\r\nRemoves a joint from the world.\r\n\r\n```lua\r\njoint = world:addJoint('RevoluteJoint', collider_1, collider_2, 50, 50, true)\r\nworld:removeJoint(joint)\r\n```\r\n\r\nArguments:\r\n\r\n* `joint` `(Joint)` - The joint to be removed\r\n\r\n---\r\n\r\n#### `:setExplicitCollisionEvents(value)`\r\n\r\nSets collision events to be explicit or not. If explicit, then collision events will only be generated between collision classes when they are specified in `addCollisionClasses`. By default this is set to false, meaning that collision events are generated between all collision classes. The main reason why you might want to set this to true is for performance, since not generating collision events between every collision class will require less computation. This function must be called before any collision class is added to the world.\r\n\r\n```lua\r\nworld:setExplicitCollisionEvents(true)\r\n```\r\n\r\nArguments:\r\n\r\n* `value` `(boolean)` - If collision events are explicit or not\r\n\r\n---\r\n\r\n#### `:setQueryDebugDrawing(value)`\r\n\r\nSets query debug drawing to be active or not. If active, then collider queries will be drawn to the screen for 10 frames. This is used for debugging purposes and incurs a performance penalty. Don't forget to turn it off!\r\n\r\n```lua\r\nworld:setQueryDebugDrawing(true)\r\n```\r\n\r\nArguments:\r\n\r\n* `value` `(boolean)` - If query debug drawing is active or not\r\n\r\n---\r\n\r\n## Collider\r\n\r\nOn top of containing all functions exposed in this documentation it also contains all functions of a [Body](https://love2d.org/wiki/Body), [Fixture](https://love2d.org/wiki/Fixture) and [Shape](https://love2d.org/wiki/Shape).\r\n\r\n---\r\n\r\n#### `:destroy()`\r\n\r\nDestroys the collider and removes it from the world. This must be called whenever the Collider is to discarded otherwise it will result in it not getting collected (and so memory will leak).\r\n\r\n```lua\r\ncollider:destroy()\r\n```\r\n\r\n---\r\n\r\n#### `:setCollisionClass(collision_class_name)`\r\n\r\nSets this collider's collision class. The collision class must be a valid one previously added with `world:addCollisionClass`.\r\n\r\n```lua\r\nworld:addCollisionClass('Player')\r\ncollider = world:newRectangleCollider(100, 100, 50, 50)\r\ncollider:setCollisionClass('Player')\r\n```\r\n\r\nArguments:\r\n\r\n* `collision_class_name` `(string)` - The name of the collision class\r\n\r\n---\r\n\r\n#### `:enter(other_collision_class_name)`\r\n\r\nChecks for collision enter events from this collider with another. Enter events are generated on the frame when one collider enters contact with another.\r\n\r\n```lua\r\n-- in some update function\r\nif collider:enter('Enemy') then\r\n    print('Collision entered!')\r\nend\r\n```\r\n\r\nArguments:\r\n\r\n* `other_collision_class_name` `(string)` - The name of the target collision class\r\n\r\nReturns:\r\n\r\n* `boolean` - If the enter collision event between both colliders happened on this frame or not\r\n\r\n---\r\n\r\n#### `:getEnterCollisionData(other_collision_class_name)`\r\n\r\nGets the collision data generated from the last collision enter event\r\n\r\n```lua\r\n-- in some update function\r\nif collider:enter('Enemy') then\r\n    local collision_data = collider:getEnterCollisionData('Enemy')\r\n    print(collision_data.collider, collision_data.contact)\r\nend\r\n```\r\n\r\nArguments:\r\n\r\n* `other_collision_class_name` `(string)` - The name of the target collision class\r\n\r\nReturns:\r\n\r\n* `collision_data` `(table[Collider, Contact])` - A table containing the Collider and the [Contact](https://love2d.org/wiki/Contact) generated from the last enter collision event\r\n\r\n---\r\n\r\n#### `:exit(other_collision_class_name)`\r\n\r\nChecks for collision exit events from this collider with another. Exit events are generated on the frame when one collider exits contact with another.\r\n\r\n```lua\r\n-- in some update function\r\nif collider:exit('Enemy') then\r\n    print('Collision exited!')\r\nend\r\n```\r\n\r\nArguments:\r\n\r\n* `other_collision_class_name` `(string)` - The name of the target collision class\r\n\r\nReturns:\r\n\r\n* `boolean` - If the exit collision event between both colliders happened on this frame or not\r\n\r\n---\r\n\r\n#### `:getExitCollisionData(other_collision_class_name)`\r\n\r\nGets the collision data generated from the last collision exit event\r\n\r\n```lua\r\n-- in some update function\r\nif collider:exit('Enemy') then\r\n    local collision_data = collider:getEnterCollisionData('Enemy')\r\n    print(collision_data.collider, collision_data.contact)\r\nend\r\n```\r\n\r\nArguments:\r\n\r\n* `other_collision_class_name` `(string)` - The name of the target collision class\r\n\r\nReturns:\r\n\r\n* `collision_data` `(table[Collider, Contact])` - A table containing the Collider and the [Contact](https://love2d.org/wiki/Contact) generated from the last exit collision event\r\n\r\n---\r\n\r\n#### `:stay(other_collision_class_name)`\r\n\r\nChecks for collision stay events from this collider with another. Stay events are generated on every frame when one collider is in contact with another.\r\n\r\n```lua\r\n-- in some update function\r\nif collider:stay('Enemy') then\r\n    print('Collision staying!')\r\nend\r\n```\r\n\r\nArguments:\r\n\r\n* `other_collision_class_name` `(string)` - The name of the target collision class\r\n\r\nReturns:\r\n\r\n* `boolean` - If the stay collision event between both colliders is happening on this frame or not\r\n\r\n---\r\n\r\n#### `:getStayCollisionData(other_collision_class_name)`\r\n\r\nGets the collision data generated from the last collision stay event\r\n\r\n```lua\r\n-- in some update function\r\nif collider:stay('Enemy') then\r\n    local collision_data_list = collider:getStayCollisionData('Enemy')\r\n    for _, collision_data in ipairs(collision_data_list) do\r\n        print(collision_data.collider, collision_data.contact)\r\n    end\r\nend\r\n```\r\n\r\nArguments:\r\n\r\n* `other_collision_class_name` `(string)` - The name of the target collision class\r\n\r\nReturns:\r\n\r\n* `collision_data_list` `(table[table[Collider, Contact]])` - A table containing multiple Colliders and [Contacts](https://love2d.org/wiki/Contact) generated from the last stay collision event. Usually this list will be of size 1, but sometimes this collider will be staying in contact with multiple other colliders on the same frame, and so those multiple stay events (with multiple colliders) are returned.\r\n\r\n---\r\n\r\n#### `:setPreSolve(callback)`\r\n\r\nSets the preSolve callback. Unlike with `:enter` or `:exit` that can be delayed and checked after the physics simulation is done for this frame, both preSolve and postSolve must be callbacks that are resolved immediately, since they may change how the rest of the simulation plays out on this frame.\r\n\r\n```lua\r\ncollider:setPreSolve(function(collider_1, collider_2, contact)\r\n    contact:setEnabled(false)\r\nend\r\n```\r\n\r\nArguments:\r\n\r\n* `callback` `(function)` - The preSolve callback. Receives `collider_1`, `collider_2` and `contact` as arguments\r\n\r\n---\r\n\r\n#### `:setPostSolve(callback)`\r\n\r\nSets the postSolve callback. Unlike with `:enter` or `:exit` that can be delayed and checked after the physics simulation is done for this frame, both preSolve and postSolve must be callbacks that are resolved immediately, since they may change how the rest of the simulation plays out on this frame.\r\n\r\n```lua\r\ncollider:setPostSolve(function(collider_1, collider_2, contact, ni1, ti1, ni2, ti2)\r\n    contact:setEnabled(false)\r\nend\r\n```\r\n\r\nArguments:\r\n\r\n* `callback` `(function)` - The postSolve callback. Receives `collider_1`, `collider_2`, `contact`, `normal_impulse1`, `tangent_impulse1`, `normal_impulse2` and `tangent_impulse2` as arguments\r\n\r\n---\r\n\r\n#### `:addShape(shape_name, shape_type, ...)`\r\n\r\nAdds a shape to the collider. A shape can be accessed via collider.shapes[shape_name]. A fixture of the same name is also added to attach the shape to the collider body. A fixture can be accessed via collider.fixtures[fixture_name].\r\n\r\nArguments:\r\n\r\n* `shape_name` `(string)` - The unique name of the shape\r\n* `shape_type` `(string)` - The shape type, can be `'ChainShape'`, `'CircleShape'`, `'EdgeShape'`, `'PolygonShape'` or `'RectangleShape'`\r\n* `...` `(*)` - The shape creation arguments that are different for each shape. Check [here](https://love2d.org/wiki/Shape) for more details\r\n\r\n---\r\n\r\n#### `:removeShape(shape_name)`\r\n\r\nRemoves a shape from the collider (also removes the accompanying fixture).\r\n\r\nArguments:\r\n\r\n* `shape_name` `(string)` - The unique name of the shape to be removed. Must be a name previously added with `:addShape`\r\n\r\n---\r\n\r\n#### `:setObject(object)`\r\n\r\nSets the collider's object. This is useful to set to the object the collider belongs to, so that when a query call is made and colliders are returned you can immediately get the pertinent object.\r\n\r\n```lua\r\n-- in the constructor of some object\r\nself.collider = world:newRectangleCollider(...)\r\nself.collider:setObject(self)\r\n```\r\n\r\nArguments:\r\n\r\n* `object` `(*)` - The object that this collider belongs to\r\n\r\n---\r\n\r\n#### `:getObject()`\r\n\r\nGets the object a collider belongs to.\r\n\r\n```lua\r\n-- in an update function\r\nif self.collider:enter('Enemy') then\r\n    local collision_data = self.collider:getEnterCollisionData('SomeTag')\r\n    -- gets the reference to the enemy object, the enemy object must have used :setObject(self) to attach itself to the collider otherwise this wouldn't work\r\n    local enemy = collision_data.collider:getObject()\r\nend\r\n```\r\n\r\nReturns:\r\n\r\n* `object` `(*)` - The object that is attached to this collider\r\n\r\n---\r\n\r\n# LICENSE\r\n\r\nYou can do whatever you want with this. See the license at the top of the main file.\r\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fa327ex%2Fwindfield","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fa327ex%2Fwindfield","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fa327ex%2Fwindfield/lists"}