Module windfield

windfield is a physics module for LÖVE.

It wraps LÖVE's physics API so that using box2d becomes as simple as possible.

Functions

wf.newWorld (xg, yg, sleep) Creates a new World.
World:update (dt) Updates the world to allow bodies to continue their motion and starts a new frame for collision events.
World:draw (alpha) Draws the world visualizing colliders, joints, and world queries (for debugging purposes).
World:setQueryDebugDrawing (value) Sets query debug drawing to be active or not.
World:setExplicitCollisionEvents (value) Sets collision events to be explicit or not.
World:addCollisionClass (collision_class_name, collision_class) Adds a new collision class to the World.
World:addCollisionClassTable (definition_map) Adds multiple new collision classes to the World.
World:newCircleCollider (x, y, r) Creates a new CircleCollider.
World:newRectangleCollider (x, y, w, h) Creates a new RectangleCollider.
World:newBSGRectangleCollider (x, y, w, h, corner_cut_size) Creates a new BSGRectangleCollider, which is a rectangle with its corners cut (an octagon).
World:newPolygonCollider (vertices) Creates a new PolygonCollider.
World:newLineCollider (x1, y1, x2, y2) Creates a new LineCollider.
World:newChainCollider (vertices, loop) Creates a new ChainCollider.
World:queryCircleArea (x, y, radius, collision_class_names) Queries a circular area around a point for colliders.
World:queryRectangleArea (x, y, w, h, collision_class_names) Queries a rectangular area for colliders.
World:queryPolygonArea (vertices, collision_class_names) Queries a polygon area for colliders.
World:queryLine (x1, y1, x2, y2, collision_class_names) Queries for colliders that intersect with a line.
World:addJoint (joint_type, ...) Adds a joint to the world.
World:removeJoint (joint) Removes a joint from the world.
World:destroy () Destroys the collider and removes it from the world.
Collider:setCollisionClass (collision_class_name) Sets this collider's collision class.
Collider:enter (other_collision_class_name) Checks for collision enter events from this collider with another.
Collider:getEnterCollisionData (other_collision_class_name) Gets the collision data generated from the last collision enter event.
Collider:exit (other_collision_class_name) Checks for collision exit events from this collider with another.
Collider:getExitCollisionData (other_collision_class_name) Gets the collision data generated from the last collision exit event.
Collider:stay (other_collision_class_name) Checks for collision stay events from this collider with another.
Collider:getStayCollisionData (other_collision_class_name) Gets the collision data generated from the last collision stay event Only valid after calling Collider:stay.
Collider:setPreSolve (callback) Sets the preSolve callback.
Collider:setPostSolve (callback) Sets the postSolve callback.
Collider:setObject (object) Sets the collider's object.
Collider:getObject () Gets the object that a collider belongs to.
Collider:addShape (shape_name, shape_type, ...) Adds a shape to the collider.
Collider:removeShape (shape_name) Removes a shape from the collider (also removes the accompanying fixture).
Collider:destroy () Destroys the collider and removes it from the world.


Functions

wf.newWorld (xg, yg, sleep)
Creates a new World.

newWorld(number, number, boolean) -> table

Parameters:

  • xg number The world's x gravity component
  • yg number The world's y gravity component
  • sleep bool =true Whether the world's bodies are allowed to sleep

Returns:

    table: World the World object, containing all attributes and methods defined below as well as all of a box2d World

Usage:

    world = wf.newWorld(0, 0, true)
World:update (dt)
Updates the world to allow bodies to continue their motion and starts a new frame for collision events.

update(number) -> nil

Parameters:

  • dt number The time step delta

Usage:

    world:update(dt)
World:draw (alpha)
Draws the world visualizing colliders, joints, and world queries (for debugging purposes).

draw(number) -> nil

Parameters:

  • alpha number =1 The optional alpha value to use when drawing, defaults to 1.

Usage:

    world:draw() -- default drawing
    world:draw(128) -- semi transparent drawing
World:setQueryDebugDrawing (value)
Sets 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!

setQueryDebugDrawing(boolean) -> nil

Parameters:

  • value bool Whether query debug drawing is active

Usage:

    world:setQueryDebugDrawing(true)
World:setExplicitCollisionEvents (value)
Sets 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.

setExplicitCollisionEvents(boolean) -> nil

Parameters:

  • value bool Whether collision events are explicit

Usage:

    world:setExplicitCollisionEvents(true)
World:addCollisionClass (collision_class_name, collision_class)
Adds 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.

addCollisionClass(string, table) -> nil

Parameters:

  • collision_class_name string The unique name of the collision class
  • collision_class {[string]={}}

    The collision class definition. Mostly specifying collision class names that should generate collision events with the collider of this collision class at different points in time.

     collision_class = {
          ignores = {}, -- physically ignore
          enter = {}, -- collision events when they *enter* contact with each other
          exit = {}, -- collision events when they *exit* contact with each other
          pre = {}, -- collision events *just before* collision response is applied
          post = {}, -- collision events *right after* collision response is applied
     }
    

Usage:

    world:addCollisionClass('Player', {ignores = {'NPC', 'Enemy'}})
World:addCollisionClassTable (definition_map)
Adds multiple new collision classes to the World.

Allows you to add multiple collision classes that ignore each other without worrying about specifying them in a specific order.

@see World:addCollisionClass

addCollisionClassTable(table) -> nil

Parameters:

  • definition_map {[string]={[string]={}}} A map of collision class names to their definitions. Definitions are the same as collision_class in World:addCollisionClass.

Usage:

    world:addCollisionClassTable({
        Player = {ignores = {'NPC', 'Enemy'}},
        NPC = {},
        Enemy = {ignores = {'NPC'}},
    })
    
World:newCircleCollider (x, y, r)
Creates a new CircleCollider.

newCircleCollider(number, number, number) -> table

Parameters:

  • x number The x position of the circle's center
  • y number The y position of the circle's center
  • r number The radius of the circle

Returns:

    table: Collider The created CircleCollider

Usage:

    circle = world:newCircleCollider(100, 100, 30)
World:newRectangleCollider (x, y, w, h)
Creates a new RectangleCollider.

newRectangleCollider(number, number, number, number) -> table

Parameters:

  • x number The x position of the rectangle's top-left corner
  • y number The y position of the rectangle's top-left corner
  • w number The width of the rectangle
  • h number The height of the rectangle

Returns:

    table: Collider The created RectangleCollider

Usage:

    rectangle = world:newRectangleCollider(100, 100, 50, 50)
World:newBSGRectangleCollider (x, y, w, h, corner_cut_size)
Creates a new BSGRectangleCollider, which is a rectangle with its corners cut (an octagon).

newBSGRectangleCollider(number, number, number, number, number) -> table

Parameters:

  • x number The x position of the rectangle's top-left corner
  • y number The y position of the rectangle's top-left corner
  • w number The width of the rectangle
  • h number The height of the rectangle
  • corner_cut_size number The corner cut size

Returns:

    table: Collider The created BSGRectangleCollider

Usage:

    bsg_rectangle = world:newBSGRectangleCollider(100, 100, 50, 50, 5)
World:newPolygonCollider (vertices)
Creates a new PolygonCollider.

newPolygonCollider({number}) -> table

Parameters:

  • vertices {number} The polygon vertices as a table of numbers

Returns:

    table: Collider The created PolygonCollider

Usage:

    polygon = world:newPolygonCollider({10, 10, 10, 20, 20, 20, 20, 10})
World:newLineCollider (x1, y1, x2, y2)
Creates a new LineCollider.

newLineCollider(number, number, number, number) -> table

Parameters:

  • x1 number The x position of the first point of the line
  • y1 number The y position of the first point of the line
  • x2 number The x position of the second point of the line
  • y2 number The y position of the second point of the line

Returns:

    table: Collider The created LineCollider

Usage:

    line = world:newLineCollider(100, 100, 200, 200)
World:newChainCollider (vertices, loop)
Creates a new ChainCollider.

newChainCollider({number}, boolean) -> table

Parameters:

  • vertices {number} The chain vertices as a table of numbers
  • loop bool If the chain should loop back from the last to the first point

Returns:

    table: Collider The created ChainCollider

Usage:

    chain = world:newChainCollider({10, 10, 10, 20, 20, 20}, true)
World:queryCircleArea (x, y, radius, collision_class_names)
Queries a circular area around a point for colliders.

queryCircleArea(number, number, number, {string}) -> {Collider}

Parameters:

  • x number The x position of the circle's center
  • y number The y position of the circle's center
  • radius number The radius of the circle
  • collision_class_names {string} ='All'] 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.

Returns:

    {Collider}: The table of colliders with the specified collision classes inside the area

Usage:

    colliders_1 = world:queryCircleArea(100, 100, 50, {'Enemy', 'NPC'})
    colliders_2 = world:queryCircleArea(100, 100, 50, {'All', except = {'Player'}})
    
World:queryRectangleArea (x, y, w, h, collision_class_names)
Queries a rectangular area for colliders.

queryRectangleArea(number, number, number, number, {string}) -> {Collider}

Parameters:

  • x number The x position of the rectangle's top-left corner
  • y number The y position of the rectangle's top-left corner
  • w number The width of the rectangle
  • h number The height of the rectangle
  • collision_class_names {string} ='All'] 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.

Returns:

    {Collider}: The table of colliders with the specified collision classes inside the area

Usage:

    colliders_1 = world:queryRectangleArea(100, 100, 50, 50, {'Enemy', 'NPC'})
    colliders_2 = world:queryRectangleArea(100, 100, 50, 50, {'All', except = {'Player'}})
    
World:queryPolygonArea (vertices, collision_class_names)
Queries a polygon area for colliders.

queryPolygonArea({number}, {string}) -> {Collider}

Parameters:

  • vertices {number} The polygon vertices as a table of numbers
  • collision_class_names {string} ='All'] 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.

Returns:

    {Collider}: The table of colliders with the specified collision classes inside the area

Usage:

    colliders_1 = world:queryPolygonArea({10, 10, 20, 10, 20, 20, 10, 20}, {'Enemy'})
    colliders_2 = world:queryPolygonArea({10, 10, 20, 10, 20, 20, 10, 20}, {'All', except = {'Player'}})
    
World:queryLine (x1, y1, x2, y2, collision_class_names)
Queries for colliders that intersect with a line.

queryLine(number, number, number, number, {string}) -> {Collider}

Parameters:

  • x1 number The x position of the first point of the line
  • y1 number The y position of the first point of the line
  • x2 number The x position of the second point of the line
  • y2 number The y position of the second point of the line
  • collision_class_names {string} ='All'] 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.

Returns:

    {Collider}: The table of colliders with the specified collision classes inside the area

Usage:

    colliders_1 = world:queryLine(100, 100, 200, 200, {'Enemy', 'NPC', 'Projectile'})
    colliders_2 = world:queryLine(100, 100, 200, 200, {'All', except = {'Player'}})
    
World:addJoint (joint_type, ...)
Adds a joint to the world.

addJoint(string, any) -> Joint

Parameters:

  • joint_type string The joint type, it can be 'DistanceJoint', 'FrictionJoint', 'GearJoint', 'MouseJoint', 'PrismaticJoint', 'PulleyJoint', 'RevoluteJoint', 'RopeJoint', 'WeldJoint' or 'WheelJoint'
  • ... any The joint creation arguments that are different for each joint type, check Joint for more details

Returns:

    Joint: joint The created Joint

Usage:

    joint = world:addJoint('RevoluteJoint', collider_1, collider_2, 50, 50, true)
World:removeJoint (joint)
Removes a joint from the world.

removeJoint(Joint) -> nil

Parameters:

  • joint Joint The joint to be removed

Usage:

    joint = world:addJoint('RevoluteJoint', collider_1, collider_2, 50, 50, true)
    world:removeJoint(joint)
    
World:destroy ()
Destroys 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).

destroy() -> nil

Usage:

    collider:destroy()
Collider:setCollisionClass (collision_class_name)
Sets this collider's collision class. The collision class must be a valid one previously added with world:addCollisionClass.

setCollisionClass(string) -> nil

Parameters:

  • collision_class_name string The name of the collision class

Usage:

    world:addCollisionClass('Player')
    collider = world:newRectangleCollider(100, 100, 50, 50)
    collider:setCollisionClass('Player')
    
Collider:enter (other_collision_class_name)
Checks for collision enter events from this collider with another. Enter events are generated on the frame when one collider enters contact with another.

enter(string) -> boolean

Parameters:

  • other_collision_class_name string The name of the target collision class

Returns:

    boolean: If the enter collision event between both colliders happened on this frame or not

Usage:

    -- in some update function
    if collider:enter('Enemy') then
        print('Collision entered!')
    end
    
Collider:getEnterCollisionData (other_collision_class_name)
Gets the collision data generated from the last collision enter event. Only valid after calling Collider:enter.

getEnterCollisionData(string) -> {Collider, Contact}

Parameters:

  • other_collision_class_name string The name of the target collision class

Returns:

    {Collider, Contact}: collision_data A table containing the Collider and the Contact generated from the last enter collision event. The Contact is read-only (only get* and is* methods exist) and will become invalid on the next call to World:update, but you can use contact:clone() to create a permanent copy.

Usage:

    -- in some update function
    if collider:enter('Enemy') then
        local collision_data = collider:getEnterCollisionData('Enemy')
        print(collision_data.collider, collision_data.contact)
    end
    
Collider:exit (other_collision_class_name)
Checks for collision exit events from this collider with another. Exit events are generated on the frame when one collider exits contact with another.

exit(string) -> boolean

Parameters:

  • other_collision_class_name string The name of the target collision class

Returns:

    boolean: If the exit collision event between both colliders happened on this frame or not

Usage:

    -- in some update function
    if collider:exit('Enemy') then
        print('Collision exited!')
    end
    
Collider:getExitCollisionData (other_collision_class_name)
Gets the collision data generated from the last collision exit event. Only valid after calling Collider:exit.

getExitCollisionData(string) -> {Collider, Contact}

Parameters:

  • other_collision_class_name string The name of the target collision class

Returns:

    {Collider, Contact}: collision_data A table containing the Collider and the Contact generated from the last exit collision event. The Contact is read-only (only get* and is* methods exist) and will become invalid on the next call to World:update, but you can use contact:clone() to create a permanent copy.

Usage:

    -- in some update function
    if collider:exit('Enemy') then
        local collision_data = collider:getExitCollisionData('Enemy')
        print(collision_data.collider, collision_data.contact)
    end
    
Collider:stay (other_collision_class_name)
Checks for collision stay events from this collider with another. Stay events are generated on every frame when one collider is in contact with another.

stay(string) -> boolean

Parameters:

  • other_collision_class_name string The name of the target collision class

Returns:

    boolean: Whether the stay collision event between both colliders is happening on this frame

Usage:

    -- in some update function
    if collider:stay('Enemy') then
        print('Collision staying!')
    end
    
Collider:getStayCollisionData (other_collision_class_name)
Gets the collision data generated from the last collision stay event Only valid after calling Collider:stay.

getStayCollisionData(string) -> {{Collider, Contact}}

Parameters:

  • other_collision_class_name string The name of the target collision class

Returns:

    {{Collider, Contact}}: collisiondatalist A table containing multiple Colliders and Contacts 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. The Contact is read-only (only get* and is* methods exist) and will become invalid on the next call to World:update, but you can use contact:clone() to create a permanent copy.

Usage:

    -- in some update function
    if collider:stay('Enemy') then
        local collision_data_list = collider:getStayCollisionData('Enemy')
        for _, collision_data in ipairs(collision_data_list) do
            print(collision_data.collider, collision_data.contact)
        end
    end
    
Collider:setPreSolve (callback)
Sets the preSolve callback. Unlike :enter or :exit, which 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.

You cannot modify the World inside of the preSolve callback because the underlying Box2D world will be locked. See also World:setCallbacks.

setPreSolve(function) -> nil

Parameters:

  • callback func The preSolve callback. Receives collider_1, collider_2, and contact as arguments

Usage:

    collider:setPreSolve(function(collider_1, collider_2, contact)
        contact:setEnabled(false)
    end
    
Collider:setPostSolve (callback)
Sets the postSolve callback. Unlike :enter or :exit, which 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.

You cannot modify the World inside of the postSolve callback because the underlying Box2D world will be locked. See also World:setCallbacks.

setPostSolve(function) -> nil

Parameters:

  • callback func The postSolve callback. Receives collider_1, collider_2, contact, normal_impulse1, tangent_impulse1, normal_impulse2, and tangent_impulse2 as arguments

Usage:

    collider:setPostSolve(function(collider_1, collider_2, contact, ni1, ti1, ni2, ti2)
        contact:setEnabled(false)
    end
    
Collider:setObject (object)
Sets the collider's object. This is useful to set the object that the collider belongs to, so that when a query call is made and colliders are returned you can immediately get the pertinent object.

setObject(any) -> nil

Parameters:

  • object any The object that this collider belongs to

Usage:

    -- in the constructor of some object
    self.collider = world:newRectangleCollider(...)
    self.collider:setObject(self)
    
Collider:getObject ()
Gets the object that a collider belongs to.

getObject() -> any

Returns:

    any: object The object that is attached to this collider

Usage:

    -- in an update function
    if self.collider:enter('Enemy') then
        local collision_data = self.collider:getEnterCollisionData('SomeTag')
        -- 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
        local enemy = collision_data.collider:getObject()
    end
    
Collider:addShape (shape_name, shape_type, ...)
Adds a shape to the collider. A shape can be accessed via collider.shapes[shapename]. 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[fixturename].

addShape(string, string, any) -> nil

Parameters:

  • shape_name string The unique name of the shape
  • shape_type string The shape type, can be 'ChainShape', 'CircleShape', 'EdgeShape', 'PolygonShape' or 'RectangleShape'
  • ... any The shape creation arguments that are different for each shape. Check Shape for more details
Collider:removeShape (shape_name)
Removes a shape from the collider (also removes the accompanying fixture).

removeShape(string) -> nil

Parameters:

  • shape_name string The unique name of the shape to be removed. Must be a name previously added with :addShape
Collider:destroy ()
Destroys 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).

destroy() -> nil

Usage:

    collider:destroy()
generated by LDoc 1.4.6 Last updated 2021-07-03 22:22:13