diff --git a/doc.lua b/doc.lua index 5c4fc7d..0282058 100644 --- a/doc.lua +++ b/doc.lua @@ -4,32 +4,32 @@ Module { name = "hump.gamestate", long = [===[ A gamestate encapsulates independent data an behaviour into a single entity. - A typical game could consist of a {** menu-state}, a {** level-state} and a {** game-over-state}.]===], + A typical game could consist of a {*menu-state}, a {*level-state} and a {*game-over-state}.]===], Section { name = "callbacks", title = "Gamestate Callbacks", content = [===[ - A gamestate can define (nearly) all callbacks that LÖVE defines. In addition, + A gamestate can define (nearly) all callbacks that LÖVE defines. In addition, there are callbacks for entering and leaving a state.: [| - {# init()} | Called once before entering the state. See {# switch()}. - {# enter(previous, ...)} | Called when entering the state. See {# switch()}. - {# leave()} | Called when leaving a state. See {# switch()}. - {# update()} | Update the game state. Called every frame. - {# draw()} | Draw on the screen. Called every frame. - {# focus()} | Called if the window gets or looses focus. - {# keypressed()} | Triggered when a key is pressed. - {# keyreleased()} | Triggered when a key is released. - {# mousepressed()} | Triggered when a mouse button is pressed. - {# mousereleased()} | Triggered when a mouse button is released. - {# joystickpressed()} | Triggered when a joystick button is pressed. - {# joystickreleased()} | Triggered when a joystick button is released. - {# quit()} | Called on quitting the game. Only called on the active gamestate. - |] + {#init()} :Called once before entering the state. See {#switch()}. + {#enter(previous, ...)} :Called when entering the state. See {#switch()}. + {#leave()} :Called when leaving a state. See {#switch()}. + {#update()} :Update the game state. Called every frame. + {#draw()} :Draw on the screen. Called every frame. + {#focus()} :Called if the window gets or looses focus. + {#keypressed()} :Triggered when a key is pressed. + {#keyreleased()} :Triggered when a key is released. + {#mousepressed()} :Triggered when a mouse button is pressed. + {#mousereleased()} :Triggered when a mouse button is released. + {#joystickpressed()} :Triggered when a joystick button is pressed. + {#joystickreleased()} :Triggered when a joystick button is released. + {#quit()} :Called on quitting the game. Only called on the active gamestate. + ] - When using {# registerEvents()}, all these callbacks will receive the same - arguments as the [[http://love2d.org/wiki/love|LÖVE callbacks]] do.]===], + When using {#registerEvents()}, all these callbacks will receive the same + arguments as the [^http://love2d.org/wiki/love LÖVE callbacks] do.]===], example = [===[ menu = Gamestate.new() function menu:init() -- run only once @@ -73,7 +73,7 @@ end]===] Function { name = "new", short = "Create a new gamestate.", - long = "Declare a new gamestate. A gamestate can define several [[callbacks]]", + long = "Declare a new gamestate. A gamestate can define several [^#{{MODULE}}-callbacks callbacks].", params = {}, returns = { {"Gamestate", "The new gamestate."} @@ -86,9 +86,9 @@ end]===] long = [===[ Switch to a gamestate, with any additional arguments passed to the new state. - Switching a gamestate will call the leave() callback on the current gamestate, - replace the current gamestate with to, call the init() function if the state - was not yet inialized and finally call enter(old_state, ...) on the new gamestate.]===], + Switching a gamestate will call the {#leave()} callback on the current gamestate, + replace the current gamestate with to, call the {#init()} function if the state + was not yet inialized and finally call {#enter(old_state, ...)} on the new gamestate.]===], params = { {"Gamestate", "to", "Target gamestate."}, {"mixed", "...", "Additional arguments to pass to to:enter()."} @@ -124,11 +124,11 @@ end]===] "Inform current gamestate of a quit event.", }, long = [===[ - Calls the corresponding function on the current gamestate (see [[callbacks]]). + Calls the corresponding function on the current gamestate (see [^#{{MODULE}}-callbacks callbacks]). Only needed when not using registerEvents().]===], params = { - {"mixed", "...", "Arguments to pass to the corresponding [[callbacks|callback]]."}, + {"mixed", "...", "Arguments to pass to the corresponding [^#{{MODULE}}-callbacks callback]."}, }, returns = { {"mixed", "The results of the callback function."}, @@ -154,13 +154,13 @@ end]===], Register all love callbacks to call Gamestate.update(), Gamestate.draw(), etc. automatically. This is by done by overwriting the love callbacks, e.g.: - {## local old_update = love.update + {%local old_update = love.update function love.update(dt) old_update(dt) Gamestate.current:update(dt) end} -{!! Note:} Only works when called in {# love.load()} or any other function that is executed + {!Note:} Only works when called in {#love.load()} or any other function that is executed after the whole file is loaded.]===], params = {}, returns = {}, @@ -187,16 +187,16 @@ Module { name = "hump.timer", Function { name = "add", short = "Add a timed function.", long = [===[ - Add a timed function. The function will be executed after {# delay} seconds + Add a timed function. The function will be executed after {#delay} seconds have elapsed, given that update() is called every frame. Note that there is no guarantee that the delay will not be exceeded, it is - only guaranteed that the function will not be executed {** before} the delay + only guaranteed that the function will not be executed {*before} the delay has passed. It is an error to schedule a function again if it is not yet finished or canceled. - {# func} will receive itself as only parameter. This is useful to implement + {#func} will receive itself as only parameter. This is useful to implement periodic behavior (see the example).]===], params = { {"number", "delay", "Number of seconds the function will be delayed."}, @@ -219,9 +219,9 @@ Timer.add(1, function(func) print("foo") Timer.add(1, func) end)]===] Function { name = "addPeriodic", short = "Add a periodic function.", long = [===[ - Add a function that will be called {# count} times every {# delay} seconds. + Add a function that will be called {#count} times every {#delay} seconds. - If {# count} is omitted, the function will be called until it returns {# false} + If {#count} is omitted, the function will be called until it returns {#false} or clear() is called.]===], params = { {"number", "delay", "Number of seconds between two consecutive function calls."}, @@ -246,9 +246,9 @@ end)]===], short = "Cancel a scheduled function.", long = [===[Prevent a timer from being executed in the future. - {** Always} use the function handle returned by add()/addPeriodic() to cancel a timer. + {*Always} use the function handle returned by add()/addPeriodic() to cancel a timer. - {** Never} use this in another timer.]===], + {*Never} use this in another timer.]===], params = { {"function", "func", "The function to be canceled."}, }, @@ -292,16 +292,16 @@ end]===], depending on how much time has passed. The wrapper will have the prototype: - {## function wrapper(dt, ...) } - where {# dt} is the time that has passed since the last call of the wrapper - and {# ...} are arguments passed to the interpolating function. It will return + {%function wrapper(dt, ...) } + where {#dt} is the time that has passed since the last call of the wrapper + and {#...} are arguments passed to the interpolating function. It will return whatever the interpolating functions returns if the interpolation is not yet finished or nil if the interpolation is done. The prototype of the interpolating function is: - {## function interpolator(fraction, ...) } - where {# fraction} is a number between 0 and 1 depending on how much time has - passed and {# ...} are additional arguments supplied to the wrapper.]===], + {%function interpolator(fraction, ...) } + where {#fraction} is a number between 0 and 1 depending on how much time has + passed and {#...} are additional arguments supplied to the wrapper.]===], params = { {"number", "length", "Interpolation length in seconds."}, {"function", "func", "Interpolating function."}, @@ -326,10 +326,10 @@ end]===], interpolating function. The function prototypes are the same as with Interpolator(): - {## function wrapper(dt, ...) } - {## function oscillator(fraction, ...) } + {%function wrapper(dt, ...) } + {%function oscillator(fraction, ...) } - As with Interpolator, the wrapper will return whatever {# oscillator()} returns.]===], + As with Interpolator, the wrapper will return whatever {#oscillator()} returns.]===], params = { {"number", "length", "Length of one interpolation period."}, {"function", "func", "Oscillating function."}, @@ -355,33 +355,33 @@ end]===], Module { name = "hump.vector", title = "vector", - short = "2D vector math", + short = "2D vector math.", long = [===[ A handy 2D vector class providing most of the things you do with vectors. - You can access the individual coordinates by using {# vec.x} and {# vec.y}.]===], + You can access the individual coordinates by using {#vec.x} and {#vec.y}.]===], Section { name = "operators", title = "Arithmetics and relations", content = [===[ - Vector arithmetic is implemented by using {# __add}, {# __mul} and other metamethods: + Vector arithmetic is implemented by using {#__add}, {#__mul} and other metamethods: [| - {# vector + vector = vector} | Component wise sum. - {# vector - vector = vector} | Component wise difference. - {# vector * vector = number} | [[http://en.wikipedia.org/wiki/Dot_product|Dot product]]. - {# number * vector = vector} | Vector scaling ([[http://en.wikipedia.org/wiki/Scalar_multiplication|scalar multiplication]]). - {# vector * number = vector} | Vector scaling. - {# vector / number = vector} | Vector scaling. - |] + {#vector + vector = vector} :Component wise sum. + {#vector - vector = vector} :Component wise difference. + {#vector * vector = number} :[^http://en.wikipedia.org/wiki/Dot_product Dot product]. + {#number * vector = vector} :Vector scaling ([^http://en.wikipedia.org/wiki/Scalar_multiplication scalar multiplication]). + {#vector * number = vector} :Vector scaling. + {#vector / number = vector} :Vector scaling. + ] Relational operators are defined, too: [| - a == b | {# true}, if {# a.x == b.x} and {# a.y == b.y}. - a <= b | {# true}, if {# a.x <= b.x} and {# a.y <= b.y}. - a < b | Lexical sort: {# true}, if {# a.x < b.x} or {# a.x == b.x} and {# a.y < b.y}. - |]]===], + a == b :{#true}, if {#a.x == b.x} and {#a.y == b.y}. + a <= b :{#true}, if {#a.x <= b.x} and {#a.y <= b.y}. + a < b :Lexical sort: {#true}, if {#a.x < b.x} or {#a.x == b.x} and {#a.y < b.y}. + ]]===], example = [===[ -- acceleration, player.velocity and player.position are vectors acceleration = vector(0,-9) @@ -413,7 +413,7 @@ a = vector(10,10)]===], {"mixed", "v", "The variable to test."} }, returns = { - {"boolean", "{# true} if {# v} is a vector, {# false} otherwise"} + {"boolean", "{#true} if {#v} is a vector, {#false} otherwise"} }, example = [===[ if not vector.isvector(v) then @@ -427,7 +427,7 @@ end]===], Copy a vector. Simply assigning a vector a vector to a variable will create a reference, so when modifying the vector referenced by the new variable would also change the old one: - {## a = vector(1,1) -- create vector + {%a = vector(1,1) -- create vector b = a -- b references a c = a:clone() -- c is a copy of a b.x = 0 -- changes a,b and c @@ -455,7 +455,7 @@ print(a,b,c) -- prints '(1,0), (1,0), (1,1)'}]===], Function { name = "vector:permul", short = "Per element multiplication.", long = [===[ - Multiplies vectors coordinate wise, i.e. {# result = vector(a.x * b.x, a.y * b.y)}. + Multiplies vectors coordinate wise, i.e. {#result = vector(a.x * b.x, a.y * b.y)}. This does not change either argument vectors, but creates a new one.]===], params = { @@ -469,7 +469,7 @@ print(a,b,c) -- prints '(1,0), (1,0), (1,1)'}]===], Function { name = "vector:len", short = "Get length.", - long = "Get length of a vector, i.e. {# math.sqrt(vec.x * vec.x + vec.y * vec.y)}.", + long = "Get length of a vector, i.e. {#math.sqrt(vec.x * vec.x + vec.y * vec.y)}.", params = {}, returns = { {"number", "Length of the vector."} @@ -479,7 +479,7 @@ print(a,b,c) -- prints '(1,0), (1,0), (1,1)'}]===], Function { name = "vector:len2", short = "Get squared length.", - long = "Get squared length of a vector, i.e. {# vec.x * vec.x + vec.y * vec.y}.", + long = "Get squared length of a vector, i.e. {#vec.x * vec.x + vec.y * vec.y}.", params = {}, returns = { {"number", "Squared length of the vector."} @@ -497,7 +497,7 @@ end]===], Function { name = "vector:dist", short = "Distance to other vector.", - long = "Get distance of two vectors. The same as {# (a - b):len()}.", + long = "Get distance of two vectors. The same as {#(a - b):len()}.", params = { {"vector", "other", "Other vector to measure the distance to."}, }, @@ -536,7 +536,7 @@ end]===], Normalize a vector, i.e. make the vector unit length. Great to use on intermediate results. - {!! This modifies the vector. If in doubt, use {# vector:normalized()}.}]===], + {!This modifies the vector. If in doubt, use {#vector:normalized()}.}]===], params = {}, returns = { {"vector", "Itself - the normalized vector"} @@ -551,7 +551,7 @@ end]===], This does not change the input vector, but creates a new vector.]===], params = { - {"number", "phi", "Rotation angle in [[http://en.wikipedia.org/wiki/Radians|radians]]."} + {"number", "phi", "Rotation angle in [^http://en.wikipedia.org/wiki/Radians radians]."} }, returns = { {"vector", "The rotated vector"} @@ -573,9 +573,9 @@ end]===], long = [===[ Rotate a vector in-place. Great to use on intermediate results. - {!! This modifies the vector. If in doubt, use {# vector:rotate()}}]===], + {!This modifies the vector. If in doubt, use {#vector:rotate()}}]===], params = { - {"number", "phi", "Rotation angle in [[http://en.wikipedia.org/wiki/Radians|radians]]."} + {"number", "phi", "Rotation angle in [^http://en.wikipedia.org/wiki/Radians radians]."} }, returns = { {"vector", "Itself - the rotated vector"} @@ -589,7 +589,7 @@ spawner.direction:rotate_inplace(dt)]===], short = "Get perpendicular vector.", long = [===[ Quick rotation by 90°. Creates a new vector. The same as (but faster): - {## vec:rotate(math.pi/2)}]===], + {%vec:rotate(math.pi/2)}]===], params = {}, returns = { {"vector", "A vector perpendicular to the input vector"} @@ -648,6 +648,252 @@ spawner.direction:rotate_inplace(dt)]===], }, } + +Module { name = "hump.vector-light", + title = "vector-light", + short = "Lightweight 2D vector math.", + long = [===[ + An table-free version of {#hump.vector}. Instead of a vector class, {#hump.vector-light} provides functions that operate on numbers. + + Using this module instead of {#vector} might result in faster code, but does so at the expense of readability. Unless you are sure that it causes a significant performance penalty, I recommend to use {#hump.vector}.]===], + + + Function { name = "str", + short = "String representation.", + long = "Transforms a vector to a string of the form {#(x,y)}.", + params = { + {"numbers", "x,y", "The vector"} + }, + returns = { + {"string", "The string representation"} + }, + example = { + "print(vector.str(love.mouse.getPosition()))", + } + }, + + Function { name = { "mul", "div" }, + short = { + "Product of a vector and a scalar.", + "Product of a vector and the inverse of a scalar.", + }, + long = "Computes {#x*s, y*s} and {#x/s, y/s}. The order of arguments is chosen so that you can chain multiple operations (see example).", + params = { + {"number", "s", "The scalar."}, + {"numbers", "x,y", "The vector."}, + }, + returns = { + {"numbers", "The result of the operation."} + }, + example = { + "velx,vely = vec.mul(dt, vec.add(velx,vely, accx,accy))", + "x,y = vec.div(self.zoom, x-w/2, y-h/2)", + }, + }, + + Function { name = { "add", "sub" }, + short = { + "Sum of two vectors.", + "Difference of two vectors.", + }, + long = "Computes the sum/difference of vectors. Same as {#x1+x2, y1+y2} or {#x1-x2, y1-y2} respectively. Meant to be used in conjunction with other functions.", + params = { + {"numbers", "x1,y1", "First vector."}, + {"numbers", "x2,y2", "Second vector."}, + }, + returns = { + {"numbers", "The result of the operation."} + }, + example = { + "player.x,player.y = vector.add(player.x,player.y, vector.mul(dt, dx,dy))", + "dx,dy = vector.sub(400,300, love.mouse.getPosition())", + }, + }, + + Function { name = "permul", + short = "Per element multiplication.", + long = [===[ + Multiplies vectors coordinate wise, i.e. {#x1*x2, y1*y2)}.]===], + params = { + {"numbers", "x1,y1", "First vector."}, + {"numbers", "x2,y2", "Second vector."}, + }, + returns = { + {"numbers", "The result of the operation."} + }, + example = "x,y = vector.permul(x,y, 1,1.5)", + }, + + Function { name = "dot", + short = "[^http://en.wikipedia.org/wiki/Dot_product Dot product]", + long = "Computes the [^http://en.wikipedia.org/wiki/Dot_product dot product] of two vectors, {#x1*x2 + y1*y2}.", + params = { + {"numbers", "x1,y1", "First vector."}, + {"numbers", "x2,y2", "Second vector."}, + }, + returns = { + {"number", "The dot product."} + }, + example = "cosphi = vector.dot(rx,ry, vx,vy)" + }, + + Function { name = {"det", "cross"}, + short = { "Cross product", "Cross product", }, + long = "Computes the cross product/determinant of two vectors, {#x1*y2 - y1*x2}.", + params = { + {"numbers", "x1,y1", "First vector."}, + {"numbers", "x2,y2", "Second vector."}, + }, + returns = { + {"number", "The cross product."} + }, + example = "parallelogram_area = vector.det(ax,ay, bx,by)" + }, + + Function { name = {"eq", "le", "lt"}, + short = { "Equality.", "Partial lexical order.", "Strict lexical order." }, + long = [===[Compares two vectors according to [| + {#vector.eq(x1,y1, x2,y2)} :{#x1 == x2 and y1 == y2} + {#vector.le(x1,y1, x2,y2)} :{#x1 <= x2 and y1 <= y2} + {#vector.lt(x1,y1, x2,y2)} :{#x1 < x2 or (x1 == x2) and y1 <= y2} + ] + ]===], + params = { + {"numbers", "x1,y1", "First vector."}, + {"numbers", "x2,y2", "Second vector."}, + }, + returns = { + {"boolean", "The result of the operation."} + }, + example = "..." + }, + + Function { name = "len", + short = "Get length.", + long = "Get length of a vector, i.e. {#math.sqrt(x*x + y*y)}.", + params = { + {"numbers", "x,y", "The vector."} + }, + returns = { + {"number", "Length of the vector."} + }, + example = "distance = vector.len(love.mouse.getPosition())", + }, + + Function { name = "len2", + short = "Get squared length.", + long = "Get squared length of a vector, i.e. {#x*x + y*y}.", + params = { + {"numbers", "x,y", "The vector."} + }, + returns = { + {"number", "Squared length of the vector."} + }, + example = [===[ +-- get closest vertex to a given vector +closest, dsq = vertices[1], vector.len2(px-vertices[1].x, py-vertices[1].y) +for i = 2,#vertices do + local temp = vector.len2(px-vertices[i].x, py-vertices[i].y) + if temp < dsq then + closest, dsq = vertices[i], temp + end +end]===], + }, + + Function { name = "dist", + short = "Distance of two points.", + long = "Get distance of two points. The same as {#vector.len(x1-x2, y1-y2)}.", + params = { + {"numbers", "x1,y1", "First vector."}, + {"numbers", "x2,y2", "Second vector."}, + }, + returns = { + {"number", "The distance of the points."} + }, + example = [===[ +-- get closest vertex to a given vector +-- slightly slower than the example using len2() +closest, dist = vertices[1], vector.dist(px,py, vertices[1].x,vertices[1].y) +for i = 2,#vertices do + local temp = vector.dist(px,py, vertices[i].x,vertices[i].y) + if temp < dist then + closest, dist = vertices[i], temp + end +end]===], + }, + + Function { name = "normalize", + short = "Normalize vector.", + long = [===[ + Get normalized vector, i.e. a vector with the same direction as the input + vector, but with length 1.]===], + params = { + {"numbers", "x,y", "The vector."}, + }, + returns = { + {"numbers", "Vector with same direction as the input vector, but length 1."} + }, + example = "dx,dy = vector.normalize(vx,vy)" + }, + + Function { name = "rotate", + short = "Rotate vector.", + long = "Get a rotated vector.", + params = { + {"number", "phi", "Rotation angle in [^http://en.wikipedia.org/wiki/Radians radians]."}, + {"numbers", "x,y", "The vector."}, + }, + returns = { + {"numbers", "The rotated vector"} + }, + example = [===[ +-- approximate a circle +circle = {} +for i = 1,30 do + local phi = 2 * math.pi * i / 30 + circle[i*2-1], circle[i*2] = vector.rotate(phi, 0,1) +end]===], + }, + + Function { name = "perpendicular", + short = "Get perpendicular vector.", + long = "Quick rotation by 90°. The same as (but faster) {%vector.rotate(math.pi/2, x,y)}", + params = { + {"numbers", "x,y", "The vector."}, + }, + returns = { + {"numbers", "A vector perpendicular to the input vector"} + }, + example = "nx,ny = vector.normalize(vector.perpendicular(bx-ax, by-ay))", + }, + + Function { name = "project", + short = "Project projection onto another vector.", + long = "Project vector onto another vector.", + params = { + {"numbers", "x,y", "The vector to project."}, + {"numbers", "u,v", "The vector to project onto."}, + }, + returns = { + {"numbers", "The projected vector."} + }, + example = "vx_p,vy_p = vector.project(vx,vy, ax,ay)", + }, + + Function { name = "mirror", + short = "Mirrors vector on other vector.", + long = "Mirrors vector on the axis defined by the other vector.", + params = { + {"numbers", "x,y", "The vector to mirror."}, + {"numbers", "u,v", "The vector defining the axis."}, + }, + returns = { + {"numbers", "The mirrored vector."} + }, + example = "vx,vy = vector.mirror(vx,vy, surface.x,surface.y)", + }, +} + Module { name = "hump.class", title = "Class", short = "Class-based object orientated programming for Lua", @@ -660,13 +906,13 @@ Module { name = "hump.class", The constructor will receive the newly create object as first argument. - You can check if an object is an instance of a class using {# object:is_a()}. + You can check if an object is an instance of a class using {#object:is_a()}. The name of the variable that holds the module can be used as a shortcut to - {# new()} (see example).]===], + {#new()} (see example).]===], params = { table_argument = true, - {"function", "constructor", "Class constructor. Can be accessed with {# theclass.construct(object, ...)}", optional = true}, - {"string", "the_name", "Class name (used only to make the class compliant to {# tostring()}.", name = "name", optional = true}, + {"function", "constructor", "Class constructor. Can be accessed with {#theclass.construct(object, ...)}", optional = true}, + {"string", "the_name", "Class name (used only to make the class compliant to {#tostring()}.", name = "name", optional = true}, {"class or table of classes", "super", "Classes to inherit from. Can either be a single class or a table of classes", name = "inherits", optional = true}, }, returns = { @@ -740,7 +986,7 @@ instance:bar() -- prints 'bar' Derived classes use this function their constructors to initialize the parent class(es) portions of the object.]===], params = { - {"Object", "object", "The object. Usually {# self}."}, + {"Object", "object", "The object. Usually {#self}."}, {"mixed", "...", "Arguments to pass to the constructor"}, }, returns = { @@ -810,14 +1056,14 @@ end} variables over to the subclass. The Lua rules for copying apply (i.e. tables are referenced, functions and primitive types are copied by value). - {!! Be careful with changing table values in a subclass: This will change the + {!Be careful with changing table values in a subclass: This will change the value in the parent class too.} If more than one parent class is specified, inherit from all of these, in order of occurrence. That means that when two parent classes define the same method, the one from the first class will be inherited. - Note: {# class:inherit()} doesn't actually care if the arguments supplied are + Note: {#class:inherit()} doesn't actually care if the arguments supplied are hump classes. Just any table will work.]===], params = { {"tables", "...", "Parent classes to inherit from"} @@ -859,10 +1105,10 @@ end short = "Test object's type.", long = "Tests whether an object is an instance of a class.", params = { - {"class", "cls", "Class to test. Note: this is the class itself, {** not} the name of the class."} + {"class", "cls", "Class to test. Note: this is the class itself, {*not} the name of the class."} }, returns = { - {"Boolean", "{# true} if the object is an instance of the class, {# false} otherwise"} + {"Boolean", "{#true} if the object is an instance of the class, {#false} otherwise"} }, example = [===[ Class = require 'hump.class' @@ -886,10 +1132,10 @@ print(e:is_a(A), e:is_a(B), e:is_a(D)) --> true true true Section { name = "caveats", title = "Caveats", content = [===[ - Be careful when using metamethods like {# __add} or {# __mul}: If subclass + Be careful when using metamethods like {#__add} or {#__mul}: If subclass inherits those methods from a superclass, but does not overwrite them, the result of the operation may be of the type superclass. Consider the following: - {## Class = require 'hump.class' + {%Class = require 'hump.class' A = Class{function(self, x) self.x = x end} function A:__add(other) return A(self.x + other.x) end @@ -904,11 +1150,11 @@ result = one + two result:show() -- prints "A: 4" result:foo() -- error: method does not exist} - Note that while you can define the {# __index} metamethod of the class, this + Note that while you can define the {#__index} metamethod of the class, this is not a good idea: It will break the class. To add a custom __index metamethod without breaking the class system, you have to use rawget(). But beware that this won't affect subclasses: - {## Class = require 'hump.class' + {%Class = require 'hump.class' A = Class{} function A:foo() print('bar') end @@ -929,11 +1175,11 @@ instance:foo() -- prints only foo}]===], Module { name = "hump.camera", title = "Camera", - short = "A camera for LÖVE", + short = "A camera for LÖVE", long = [===[ - {!! Depends on hump.vector} + {!Depends on hump.vector-light} - A camera utility for LÖVE. A camera can "look" at a position. It can zoom in and + A camera utility for LÖVE. A camera can "look" at a position. It can zoom in and out and it can rotate it's view. In the background, this is done by actually moving, scaling and rotating everything in the game world. But don't worry about that.]===], @@ -942,13 +1188,13 @@ Module { name = "hump.camera", short = "Create a new camera object.", long = [===[ Creates a new camera object. You can access the camera position using - {# camera.pos}, the zoom using {# camera.zoom} and the rotation using - {# camera.rot}. + {#camera.x, camera.y}, the zoom using {#camera.zoom} and the rotation using + {#camera.rot}. - The module variable name can be used at a shortcut to {# new()}.]===], + The module variable name can be used at a shortcut to {#new()}.]===], params = { - {"vector", "pos", "Point for the camera to look at.", default = "screen center"}, + {"numbers", "x,y", "Point for the camera to look at.", default = "screen center"}, {"number", "zoom", "Camera zoom.", default = "1"}, {"number", "rot", "Camera rotation in radians.", default = "0"}, }, @@ -959,20 +1205,19 @@ Module { name = "hump.camera", example = [===[ camera = require 'hump.camera' -vector = require 'hump.vector' -- camera looking at (100,100) with zoom 2 and rotated by 45 degrees -cam = camera(vector(100,100), 2, math.pi/2) +cam = camera(100,100, 2, math.pi/2) ]===] }, Function { name = "camera:rotate", short = "Rotate camera object.", long = [===[ - Rotate the camera {** by} some angle. To {** set} the angle use - {# camera.rot = new_angle}. + Rotate the camera {*by} some angle. To {*set} the angle use + {#camera.rot = new_angle}. - This function is shortcut to {# camera.rot = camera.rot + angle}.]===], + This function is shortcut to {#camera.rot = camera.rot + angle}.]===], params = { {"number", "angle", "Rotation angle in radians"} @@ -984,21 +1229,19 @@ cam = camera(vector(100,100), 2, math.pi/2) example = { "function love.update(dt)\n camera:rotate(dt)\nend", - "function love.update(dt)\n camera:rotate(dt):move(dt)\nend" + "function love.update(dt)\n camera:rotate(dt):move(dt,dt)\nend" }, }, Function { name = "camera:move", short = "Move camera object.", long = [===[ - {** Move} the camera {** by} some vector. To {** set} the position, use - {# camera.pos = some_vector} or {# camera.pos.x, camera.pos.y = new_x, new_y}. + {*Move} the camera {*by} some vector. To {*set} the position, use {#camera.x,camera.y = new_x,new_y}. - This function is shortcut to {# camera.pos = camera.pos + v}.]===], + This function is shortcut to {#camera.x,camera.y = camera.x+dx, camera.y+dy}.]===], params = { - { {"vector", "v", "Direction to move the camera."} }, - { {"numbers", "x, y", "Direction to move the camera."} }, + {"numbers", "dx,dy", "Direction to move the camera."}, }, returns = { @@ -1006,7 +1249,6 @@ cam = camera(vector(100,100), 2, math.pi/2) }, example = { - "function love.update(dt)\n camera:move(dt * velocity)\nend", "function love.update(dt)\n camera:move(dt * 5, dt * 6):rotate(dt)\nend" }, }, @@ -1017,7 +1259,7 @@ cam = camera(vector(100,100), 2, math.pi/2) Start looking through the camera. Apply camera transformations, i.e. move, scale and rotate everything until - {# camera:detach()} as if looking through the camera.]===], + {#camera:detach()} as if looking through the camera.]===], params = {}, returns = {}, @@ -1052,8 +1294,8 @@ end]===] Function { name = "camera:draw", short = "Attach, draw and detach.", long = [===[ - Wrap a function between a {# camera:attach()}/{# camera:detach()} pair: - {## cam:attach() + Wrap a function between a {#camera:attach()}/{#camera:detach()} pair: + {%cam:attach() func() cam:detach()}]===], @@ -1083,7 +1325,7 @@ end]===] defines a coordinate system. A point now has two sets of coordinates: One defines where the point is to be found in the game world, and the other describes the position on the computer screen. The first set of coordinates - is called {** world coordinates}, the second one {** camera coordinates}. + is called {*world coordinates}, the second one {*camera coordinates}. Sometimes it is needed to convert between the two coordinate systems, for example to get the position of a mouse click in the game world in a strategy @@ -1092,35 +1334,34 @@ end]===] These two functions convert a point between these two coordinate systems.]===], params = { - { {"vector", "v", "Point to transform."} }, - { {"numbers", "x, y", "Point to transform."} }, + {"numbers", "x, y", "Point to transform."}, }, returns = { - {"vector", "Transformed point."}, + {"numbers", "Transformed point."}, }, example = { [===[ -target = camera:worldCoords( vector(love.mouse.getPosition()) ) -selectedUnit:plotPath(target) +x,y = camera:worldCoords(love.mouse.getPosition()) +selectedUnit:plotPath(x,y) ]===], [===[ -pos = cam:toCameraCoords(player.pos) -love.graphics.line(pos.x, pos.y, love.mouse.getPosition()) +x,y = cam:toCameraCoords(player.pos) +love.graphics.line(x, y, love.mouse.getPosition()) ]===] }, }, Function { name = "camera:mousepos", short = "Get mouse position in world coordinates.", - long = "Shortcut to {# camera:worldCoords(vector(love.mouse.getPosition()))}.", + long = "Shortcut to {#camera:worldCoords(vector(love.mouse.getPosition()))}.", params = {}, returns = { - {"vector", "Mouse position in world coordinates."}, + {"numbers", "Mouse position in world coordinates."}, }, example = [===[ -target = camera:mousepos() -selectedUnit:plotPath(target) +x,y = camera:mousepos() +selectedUnit:plotPath(x,y) ]===], }, } @@ -1130,11 +1371,11 @@ Module { name = "hump.ringbuffer", short = "A data structure that wraps around itself.", long = [===[ A ring-buffer is a circular array: It does not have a first nor a last item, - but it has a {** selected} or {** current} element. + but it has a {*selected} or {*current} element. - A ring-buffer can be used to implement {** Tomb Raider} style inventories, looping + A ring-buffer can be used to implement {*Tomb Raider} style inventories, looping play-lists, recurring dialogs (like a unit's answers when selecting it multiple - times in {** Warcraft}) and generally everything that has a circular or looping + times in {*Warcraft}) and generally everything that has a circular or looping structure.]===], Function { name = "new", diff --git a/index.html b/index.html index e8cd1fb..6e18a19 100644 --- a/index.html +++ b/index.html @@ -1,94 +1,6 @@ - - - -
- -Helper Utilities for a Multitude of Problems is a set of lightweight - helpers for the awesome - LÖVE Engine.
- -It features -
hump differs from other libraries in that every component is - independent of the remaining ones (apart from camera.lua, which does depends on - vector.lua). hump's footprint is very small and thus should fit nicely - into your projects.
-Below is the documentation of the various modules. You can directly jump to a - module by clicking these:
-hump.gamestate = require "Gamestate"
A gamestate encapsulates independent data an behaviour into a single entity.A typical game could consist of a menu-state, a level-state and a game-over-state.
A gamestate can define (nearly) all callbacks that LÖVE defines. In addition, - there are callbacks for entering and leaving a state.:
init()
switch()
.
-enter(previous, ...)
switch()
.
-leave()
switch()
.
-update()
draw()
focus()
keypressed()
keyreleased()
mousepressed()
mousereleased()
joystickpressed()
joystickreleased()
quit()
When using registerEvents()
, all these callbacks will receive the same
- arguments as the LÖVE callbacks do.
menu = Gamestate.new()
+hump - LÖVE Helper Utilities for More Productivity hump Helper Utilities for More Productivity
Introduction^ top
Helper Utilities for a Multitude of Problems is a set of lightweight helpers for the awesome LÖVE Engine.
It features
- gamestate.lua: a gamestate system.
- timer.lua: timed function calling and interpolating functions,
- vector.lua: a mature vector type,
- vector-light.lua: lightweight vector math,
- class.lua: a simple and easy class system,
- camera.lua: a move-, zoom- and rotatable camera and
- ringbuffer.lua: a circular container.
hump differs from other libraries in that every component is independent of the remaining ones (apart from camera.lua, which does depends on vector.lua). hump's footprint is very small and thus should fit nicely into your projects.
Documentation^ top
- hump.gamestate
- A gamestate system
- hump.timer
- Delayed function calls and helpers for interpolating functions.
- hump.vector
- 2D vector math.
- hump.vector-light
- Lightweight 2D vector math.
- hump.class
- Class-based object orientated programming for Lua
- hump.camera
- A camera for LÖVE
- hump.ringbuffer
- A data structure that wraps around itself.
hump.gamestate^ top
Gamestate = require "hump.gamestate"
A gamestate encapsulates independent data an behaviour into a single entity.
A typical game could consist of a menu-state, a level-state and a game-over-state.
Module overview
- callbacks
- Gamestate Callbacks
- new()
- Create a new gamestate.
- switch()
- Switch to gamestate.
- update()
- Update current gamestate.
- draw()
- Draw the current gamestate.
- focus()
- Inform current gamestate of a focus event.
- keypressed()
- Inform current gamestate of a keypressed event.
- keyreleased()
- Inform current gamestate of a keyreleased event.
- mousepressed()
- Inform current gamestate of a mousepressed event.
- mousereleased()
- Inform current gamestate of a mousereleased event.
- joystickpressed()
- Inform current gamestate of a joystickpressed event.
- joystickreleased()
- Inform current gamestate of a joystickreleased event.
- quit()
- Inform current gamestate of a quit event.
- registerEvents()
- Automatically do all of the above when needed.
Gamestate Callbacks^ top
A gamestate can define (nearly) all callbacks that LÖVE defines. In addition, there are callbacks for entering and leaving a state.:
init()
- Called once before entering the state. See
switch()
. enter(previous, ...)
- Called when entering the state. See
switch()
. leave()
- Called when leaving a state. See
switch()
. update()
- Update the game state. Called every frame.
draw()
- Draw on the screen. Called every frame.
focus()
- Called if the window gets or looses focus.
keypressed()
- Triggered when a key is pressed.
keyreleased()
- Triggered when a key is released.
mousepressed()
- Triggered when a mouse button is pressed.
mousereleased()
- Triggered when a mouse button is released.
joystickpressed()
- Triggered when a joystick button is pressed.
joystickreleased()
- Triggered when a joystick button is released.
quit()
- Called on quitting the game. Only called on the active gamestate.
When using registerEvents()
, all these callbacks will receive the same arguments as the LÖVE callbacks do.
Example:menu = Gamestate.new()
function menu:init() -- run only once
- self.background = love.graphics.newImage('bg.jpg')
+ self.background = love.graphics.newImage('bg.jpg')
Buttons.initialize()
end
@@ -106,9 +18,9 @@ function menu:draw()
end
function menu:keyreleased(key)
- if key == 'up' then
+ if key == 'up' then
Buttons.selectPrevious()
- elseif key == 'down' then
+ elseif key == 'down' then
Buttons.selectNext()
elseif
Buttons.active:onClick()
@@ -119,13 +31,11 @@ function menu:mousereleased(x,y, mouse_btn)
local button = Buttons.hovered(x,y)
if button then
Button.select(button)
- if mouse_btn == 'l' then
+ if mouse_btn == 'l' then
button:onClick()
end
end
-end
function new()^ top
Declare a new gamestate. A gamestate can define several callbacks
Parameters:- None.
Returns:- Gamestate
- The new gamestate.
Example:menu = Gamestate.new()
function switch(to, ...)^ top
Switch to a gamestate, with any additional arguments passed to the new state.
Switching a gamestate will call the leave() callback on the current gamestate,
- replace the current gamestate with to, call the init() function if the state
- was not yet inialized and finally call enter(old_state, ...) on the new gamestate.
Parameters:- Gamestate
to
- Target gamestate.
- mixed
...
- Additional arguments to pass to to:enter().
Returns:- mixed
- The results of to:enter()
Example:Gamestate.switch(game, level_two)
function update(...)^ top
function draw(...)^ top
function focus(...)^ top
function keypressed(...)^ top
function keyreleased(...)^ top
function mousepressed(...)^ top
function mousereleased(...)^ top
function joystickpressed(...)^ top
function joystickreleased(...)^ top
function quit(...)^ top
Calls the corresponding function on the current gamestate (see callbacks).
Only needed when not using registerEvents().
Parameters:- mixed
...
- Arguments to pass to the corresponding callback.
Returns:- mixed
- The results of the callback function.
Example:function love.update(dt)
+end
function new()^ top
Declare a new gamestate. A gamestate can define several callbacks.
Parameters:- None
Returns:- Gamestate
The new gamestate.
Example:menu = Gamestate.new()
function switch(to, ...)^ top
Switch to a gamestate, with any additional arguments passed to the new state.
Switching a gamestate will call the leave()
callback on the current gamestate, replace the current gamestate with to, call the init()
function if the state was not yet inialized and finally call enter(old_state, ...)
on the new gamestate.
Parameters:- Gamestate
to
Target gamestate.
- mixed
...
Additional arguments to pass to to:enter().
Returns:- mixed
The results of to:enter()
Example:Gamestate.switch(game, level_two)
function update(...)^ top
function draw(...)^ top
function focus(...)^ top
function keypressed(...)^ top
function keyreleased(...)^ top
function mousepressed(...)^ top
function mousereleased(...)^ top
function joystickpressed(...)^ top
function joystickreleased(...)^ top
function quit(...)^ top
Calls the corresponding function on the current gamestate (see callbacks).
Only needed when not using registerEvents().
Parameters:- mixed
...
Arguments to pass to the corresponding callback.
Returns:- mixed
The results of the callback function.
Example:function love.update(dt)
Gamestate.update(dt)
end
@@ -136,63 +46,31 @@ end
function love.keypressed(key, code)
Gamestate.keypressed(key, code)
-end
function registerEvents()^ top
Register all love callbacks to call Gamestate.update(), Gamestate.draw(), etc. automatically.
This is by done by overwriting the love callbacks, e.g.:
-
local old_update = love.update
-function love.update(dt)
- old_update(dt)
- Gamestate.current:update(dt)
-end
Note: Only works when called in love.load()
or any other function that is executed
-after the whole file is loaded.
Parameters:- None.
Returns:- Nothing.
Example:function love.load()
+end
function registerEvents()^ top
Register all love callbacks to call Gamestate.update(), Gamestate.draw(), etc. automatically.
This is by done by overwriting the love callbacks, e.g.:
local old_update = love.updatefunction love.update(dt) old_update(dt) Gamestate.current:update(dt)end
Note: Only works when called in love.load()
or any other function that is executedafter the whole file is loaded.
Parameters:- None
Returns:- Nothing
Example:function love.load()
Gamestate.registerEvents()
Gamestate.switch(menu)
-end
-hump.timer^ top
hump.timer = require "Timer"
hump.timer provides a simple interface to use delayed functions, i.e. functions
- that will be executed after some amount time has passed. For example, you can use
- a timer to set the player invincible for a short amount of time. In addition, the module offers facilities to create functions that interpolate
- or oscillate over time. An interpolator could fade the color or a text message,
- whereas an oscillator could be used for the movement of foes in a shmup.
Module overview
- add()
- Add a timed function.
- addPeriodic()
- Add a periodic function.
- cancel()
- Cancel a timed function.
- clear()
- Remove all timed and periodic functions.
- update()
- Update timed functions.
- Interpolator()
- Create a new interpolating function.
- Oscillator()
- Create a new oscillating function.
function add(delay, func)^ top
Add a timed function. The function will be executed after delay
seconds
- have elapsed, given that update() is called every frame.
Note that there is no guarantee that the delay will not be exceeded, it is
- only guaranteed that the function will not be executed before the delay
- has passed.
It is an error to schedule a timer again if it is not yet finished or canced.
func
will receive itself as only parameter. This is useful to implement
- periodic behavior (see the example).
Parameters:- number
delay
- Number of seconds the function will be delayed.
- function
func
- The function to be delayed.
Returns:- function
- The timer handle.
Examples:-- grant the player 5 seconds of immortality
+end
hump.timer^ top
Timer = require "hump.timer"
hump.timer provides a simple interface to use delayed functions, i.e. functionsthat will be executed after some amount time has passed. For example, you can usea timer to set the player invincible for a short amount of time.
In addition, the module offers facilities to create functions that interpolateor oscillate over time. An interpolator could fade the color or a text message,whereas an oscillator could be used for the movement of foes in a shmup.
Module overview
- add()
- Add a timed function.
- addPeriodic()
- Add a periodic function.
- cancel()
- Cancel a scheduled function.
- clear()
- Remove all timed and periodic functions.
- update()
- Update timed functions.
- Interpolator()
- Create a new interpolating function.
- Oscillator()
- Create a new oscillating function.
function add(delay, func)^ top
Add a timed function. The function will be executed after delay
seconds have elapsed, given that update() is called every frame.
Note that there is no guarantee that the delay will not be exceeded, it is only guaranteed that the function will not be executed before the delay has passed.
It is an error to schedule a function again if it is not yet finished or canceled.
func
will receive itself as only parameter. This is useful to implement periodic behavior (see the example).
Parameters:- number
delay
Number of seconds the function will be delayed.
- function
func
The function to be delayed.
Returns:- function
The timer handle.
Example:-- grant the player 5 seconds of immortality
player.isInvincible = true
-Timer.add(5, function() player.isInvincible = false end)
-- print "foo" every second. See addPeriodic.
-Timer.add(1, function(func) print("foo") Timer.add(1, func) end)
function addPeriodic(delay, func, count)^ top
Add a function that will be called count
times every delay
seconds.
If count
is omitted, the function will be called until it returns false
- or clear() is called.
Parameters:- number
delay
- Number of seconds between two consecutive function calls.
- function
func
- The function to be called periodically.
- number
count
(optional) - Number of times the function is to be called.
Returns:- function
- The timer handle.
Examples:Timer.addPeriodic(1, function() lamp:toggleLight() end)
Timer.addPeriodic(0.3, function() mothership:spawnFighter() end, 5)
-- flicker player's image as long as he is invincible
+Timer.add(5, function() player.isInvincible = false end)
-- print "foo" every second. See addPeriodic.
+Timer.add(1, function(func) print("foo") Timer.add(1, func) end)
function addPeriodic(delay, func, count)^ top
Add a function that will be called count
times every delay
seconds.
If count
is omitted, the function will be called until it returns false
or clear() is called.
Parameters:- number
delay
Number of seconds between two consecutive function calls.
- function
func
The function to be called periodically.
- number
count
Number of times the function is to be called.
Returns:- function
The timer handle.
Example:Timer.addPeriodic(1, function() lamp:toggleLight() end)
Timer.addPeriodic(0.3, function() mothership:spawnFighter() end, 5)
-- flicker player's image as long as he is invincible
Timer.addPeriodic(0.1, function()
player:flipImage()
return player.isInvincible
-end)
function cancel(func)^ top
Prevent a timer from being executed in the future.
Alway use the function handle returned by add()
/addPeriodic()
to cancel a timer.
Never use this in another timer.
Parameters:- function
func
- The function to be canceled.
Returns:- Nothing.
Example:function tick()
- print('tock')
+end)
function cancel(func)^ top
Prevent a timer from being executed in the future.
Always use the function handle returned by add()/addPeriodic() to cancel a timer.
Never use this in another timer.
Parameters:- function
func
The function to be canceled.
Returns:- Nothing
Example:function tick()
+ print('tick... tock...')
end
handle = Timer.addPeriodic(1, tick)
-
-- later
-Timer.cancel(handle) -- NOT: Timer.cancel(tick)
function update(dt)^ top
Update timers and execute functions if the deadline is reached. Use this in love.update(dt).
Parameters:- number
dt
- Time that has passed since the last update().
Returns:- Nothing.
Example:function love.update(dt)
+Timer.cancel(handle) -- NOT: Timer.cancel(tick)
function clear()^ top
Remove all timed and periodic functions. Functions that have not yet been executed will discarded.
Parameters:- None
Returns:- Nothing
Example:Timer.clear()
function update(dt)^ top
Update timers and execute functions if the deadline is reached. Use this in love.update(dt).
Parameters:- number
dt
Time that has passed since the last update().
Returns:- Nothing
Example:function love.update(dt)
do_stuff()
Timer.update(dt)
-end
function clear()^ top
Remove all timed and periodic functions. Functions that have not yet been executed will discarded.
Parameters:- None.
Returns:- Nothing.
Example:Timer.clear()
function update(dt)^ top
Update timers and execute functions if the deadline is reached. Use this in love.update(dt).
Parameters:- number
dt
- Time that has passed since the last update().
Returns:- Nothing.
Example:function love.update(dt)
- do_stuff()
- Timer.update(dt)
-end
function Interpolator(length, func)^ top
Create a wrapper for an interpolating function, i.e. a function that acts
- depending on how much time has passed.
The wrapper will have the prototype:
-
function wrapper(dt, ...)
- where dt
is the time that has passed since the last call of the wrapper
- and ...
are arguments passed to the interpolating function. It will return
- whatever the interpolating functions returns if the interpolation is not yet
- finished or nil if the interpolation is done. The prototype of the interpolating function is:
-
function interpolator(fraction, ...)
- where fraction
is a number between 0 and 1 depending on how much time has
- passed and ...
are additional arguments supplied to the wrapper.Parameters:- number
length
- Interpolation length in seconds.
- function
func
- Interpolating function.
Returns:- function
- The wrapper function.
Example:fader = Timer.Interpolator(5, function(frac, r,g,b)
+end
function Interpolator(length, func)^ top
Create a wrapper for an interpolating function, i.e. a function that acts depending on how much time has passed.
The wrapper will have the prototype:
function wrapper(dt, ...)
where dt
is the time that has passed since the last call of the wrapper and ...
are arguments passed to the interpolating function. It will return whatever the interpolating functions returns if the interpolation is not yet finished or nil if the interpolation is done.The prototype of the interpolating function is:
function interpolator(fraction, ...)
where fraction
is a number between 0 and 1 depending on how much time has passed and ...
are additional arguments supplied to the wrapper.Parameters:- number
length
Interpolation length in seconds.
- function
func
Interpolating function.
Returns:- function
The wrapper function.
Example:fader = Timer.Interpolator(5, function(frac, r,g,b)
love.graphics.setBackgroundColor(frac*r,frac*g,frac*b)
end)
function love.update(dt)
fader(dt, 255,255,255)
-end
function Oscillator(length, func)^ top
Create a wrapper for an oscillating function, which is basically a looping
- interpolating function.
The function prototypes are the same as with Interpolator():
-
function wrapper(dt, ...)
- function oscillator(fraction, ...)
As with Interpolator, the wrapper will return whatever oscillator()
returns.
Parameters:- number
length
- Length of one interpolation period.
- function
func
- Oscillating function.
Returns:- function
- The wrapper function.
Example:mover = Timer.Oscillator(10, function(frac)
+end
function Oscillator(length, func)^ top
Create a wrapper for an oscillating function, which is basically a looping interpolating function.
The function prototypes are the same as with Interpolator():
function wrapper(dt, ...)
function oscillator(fraction, ...)
As with Interpolator, the wrapper will return whatever oscillator()
returns.
Parameters:- number
length
Length of one interpolation period.
- function
func
Oscillating function.
Returns:- function
The wrapper function.
Example:mover = Timer.Oscillator(10, function(frac)
return 400 + 300 * math.sin(2*math.pi*frac)
end)
@@ -202,116 +80,112 @@ function love.update(dt)
end
function love.draw()
- love.graphics.circle('fill', xpos, 300, 80, 36)
-end
-hump.vector^ top
hump.vector = require "vector"
A handy 2D vector class providing most of the things you do with vectors. You can access the individual coordinates by using vec.x
and vec.y
.
Module overview
- new()
- Create a new vector.
- isvector()
- Test if value is a vector.
- vector:clone()
- Copy a vector.
- vector:unpack()
- Extract coordinates.
- vector:permul()
- Per element multiplication.
- vector:len()
- Get length.
- vector:len2()
- Get squared length.
- vector:dist()
- Distance to other vector.
- vector:normalized()
- Get normalized vector.
- vector:normalize_inplace()
- Normalize vector in-place.
- vector:rotated()
- Get rotated vector.
- vector:rotate_inplace()
- Rotate vector in-place.
- vector:perpendicular()
- Get perpendicular vector.
- vector:projectOn()
- Get projection onto another vector.
- vector:mirrorOn()
- Mirrors vector on other vector
- vector:cross()
- Cross product of two vectors.
Arithmetics and relations
Vector arithmetic is implemented by using __add
, __mul
and other metamethods:
vector + vector = vector
- Component wise sum.
-
vector - vector = vector
- Component wise difference.
-
vector * vector = number
- Dot product.
-
number * vector = vector
- Vector scaling (scalar multiplication).
-
vector * number = vector
- Vector scaling.
-
vector / number = vector
- Vector scaling.
-
Relational operators are defined, too:
- a == b
true
, if a.x == b.x
and a.y == b.y
.
-- a <= b
true
, if a.x <= b.x
and a.y <= b.y
.
-- a < b
- Lexical sort:
true
, if a.x < b.x
or a.x == b.x
and a.y < b.y
.
-
Example:-- acceleration, player.velocity and player.position are vectors
+ love.graphics.circle('fill', xpos, 300, 80, 36)
+end
hump.vector^ top
vector = require "hump.vector"
A handy 2D vector class providing most of the things you do with vectors.
You can access the individual coordinates by using vec.x
and vec.y
.
Module overview
- operators
- Arithmetics and relations
- new()
- Create a new vector.
- isvector()
- Test if value is a vector.
- vector:clone()
- Copy a vector.
- vector:unpack()
- Extract coordinates.
- vector:permul()
- Per element multiplication.
- vector:len()
- Get length.
- vector:len2()
- Get squared length.
- vector:dist()
- Distance to other vector.
- vector:normalized()
- Get normalized vector.
- vector:normalize_inplace()
- Normalize vector in-place.
- vector:rotated()
- Get rotated vector.
- vector:rotate_inplace()
- Rotate vector in-place.
- vector:perpendicular()
- Get perpendicular vector.
- vector:projectOn()
- Get projection onto another vector.
- vector:mirrorOn()
- Mirrors vector on other vector
- vector:cross()
- Cross product of two vectors.
Arithmetics and relations^ top
Vector arithmetic is implemented by using __add
, __mul
and other metamethods:
vector + vector = vector
- Component wise sum.
vector - vector = vector
- Component wise difference.
vector * vector = number
- [^http://en.wikipedia.org/wiki/Dot_product Dot product].
number * vector = vector
- Vector scaling ([^http://en.wikipedia.org/wiki/Scalar_multiplication scalar multiplication]).
vector * number = vector
- Vector scaling.
vector / number = vector
- Vector scaling.
Relational operators are defined, too:
- a == b
true
, if a.x == b.x
and a.y == b.y
.- a <= b
true
, if a.x <= b.x
and a.y <= b.y
.- a < b
- Lexical sort:
true
, if a.x < b.x
or a.x == b.x
and a.y < b.y
.
Example:-- acceleration, player.velocity and player.position are vectors
acceleration = vector(0,-9)
player.velocity = player.velocity + acceleration * dt
-player.position = player.position + player.velocity * dt
function new(x,y)^ top
Create a new vector.
Parameters:- numbers
x,y
- Coordinates.
Returns:- vector
- The vector.
Examples:a = vector.new(10,10)
-- as a shortcut, you can call the module like a function:
-vector = require "hump.vector"
-a = vector(10,10)
function isvector(v)^ top
Test whether a variable is a vector.
Parameters:- mixed
v
- The variable to test.
Returns:- boolean
true
if v
is a vector, false
otherwise
Example:if not vector.isvector(v) then
+player.position = player.position + player.velocity * dt
function new(x,y)^ top
Create a new vector.
Parameters:- numbers
x,y
Coordinates.
Returns:- vector
The vector.
Example:a = vector.new(10,10)
-- as a shortcut, you can call the module like a function:
+vector = require "hump.vector"
+a = vector(10,10)
function isvector(v)^ top
Test whether a variable is a vector.
Parameters:- mixed
v
The variable to test.
Returns:- boolean
true
if v
is a vector, false
otherwise
Example:if not vector.isvector(v) then
v = vector(v,0)
-end
function vector:clone()^ top
Copy a vector. Simply assigning a vector a vector to a variable will create
- a reference, so when modifying the vector referenced by the new variable
- would also change the old one:
-
a = vector(1,1) -- create vector
-b = a -- b references a
-c = a:clone() -- c is a copy of a
-b.x = 0 -- changes a,b and c
-print(a,b,c) -- prints '(1,0), (1,0), (1,1)'
Parameters:- None.
Returns:- vector
- Copy of the vector
Example:copy = original:clone
function vector:unpack()^ top
Extract coordinates.
Parameters:- None.
Returns:- numbers
- The coordinates
Examples:x,y = pos:unpack()
love.graphics.draw(self.image, self.pos:unpack())
function vector:permul(other)^ top
Multiplies vectors coordinate wise, i.e. result = vector(a.x * b.x, a.y * b.y)
.
This does not change either argument vectors, but creates a new one.
Parameters:- vector
other
- The other vector
Returns:- vector
- The new vector as described above
Example:scaled = original:permul(vector(1,1.5))
function vector:len()^ top
Get length of a vector, i.e. math.sqrt(vec.x * vec.x + vec.y * vec.y)
.
Parameters:- None.
Returns:- number
- Length of the vector.
Example:distance = (a - b):len()
function vector:len2()^ top
Get squared length of a vector, i.e. vec.x * vec.x + vec.y * vec.y
.
Parameters:- None.
Returns:- number
- Squared length of the vector.
Example:-- get closest vertex to a given vector
+end
function vector:clone()^ top
Copy a vector. Simply assigning a vector a vector to a variable will create a reference, so when modifying the vector referenced by the new variable would also change the old one:
a = vector(1,1) -- create vectorb = a -- b references ac = a:clone() -- c is a copy of ab.x = 0 -- changes a,b and cprint(a,b,c) -- prints '(1,0), (1,0), (1,1)'
Parameters:- None
Returns:- vector
Copy of the vector
Example:copy = original:clone
function vector:unpack()^ top
Extract coordinates.
Parameters:- None
Returns:- numbers
The coordinates
Example:x,y = pos:unpack()
love.graphics.draw(self.image, self.pos:unpack())
function vector:permul(other)^ top
Multiplies vectors coordinate wise, i.e. result = vector(a.x * b.x, a.y * b.y)
.
This does not change either argument vectors, but creates a new one.
Parameters:- vector
other
The other vector
Returns:- vector
The new vector as described above
Example:scaled = original:permul(vector(1,1.5))
function vector:len()^ top
Get length of a vector, i.e. math.sqrt(vec.x * vec.x + vec.y * vec.y)
.
Parameters:- None
Returns:- number
Length of the vector.
Example:distance = (a - b):len()
function vector:len2()^ top
Get squared length of a vector, i.e. vec.x * vec.x + vec.y * vec.y
.
Parameters:- None
Returns:- number
Squared length of the vector.
Example:-- get closest vertex to a given vector
closest, dsq = vertices[1], (pos - vertices[1]):len2()
for i = 2,#vertices do
local temp = (pos - vertices[i]):len2()
- if temp < dsq then
+ if temp < dsq then
closest, dsq = vertices[i], temp
end
-end
function vector:dist(other)^ top
Get distance of two vectors. The same as (a - b):len()
.
Parameters:- vector
other
- Other vector to measure the distance to.
Returns:- number
- The distance of the vectors.
Example:-- get closest vertex to a given vector
+end
function vector:dist(other)^ top
Get distance of two vectors. The same as (a - b):len()
.
Parameters:- vector
other
Other vector to measure the distance to.
Returns:- number
The distance of the vectors.
Example:-- get closest vertex to a given vector
-- slightly slower than the example using len2()
closest, dist = vertices[1], pos:dist(vertices[1])
for i = 2,#vertices do
local temp = pos:dist(vertices[i])
- if temp < dist then
+ if temp < dist then
closest, dist = vertices[i], temp
end
-end
function vector:normalized()^ top
Get normalized vector, i.e. a vector with the same direction as the input
- vector, but with length 1.
This does not change the input vector, but creates a new vector.
Parameters:- None.
Returns:- vector
- Vector with same direction as the input vector, but length 1.
Example:direction = velocity:normalized()
function vector:normalize_inplace()^ top
Normalize a vector, i.e. make the vector unit length. Great to use on
- intermediate results.
This modifies the vector. If in doubt, use vector:normalized()
.
Parameters:- None.
Returns:- vector
- Itself - the normalized vector
Example:normal = (b - a):perpendicular():normalize_inplace()
function vector:rotated(phi)^ top
Get a rotated vector.
This does not change the input vector, but creates a new vector.
Parameters:- number
phi
- Rotation angle in radians.
Returns:- vector
- The rotated vector
Example:-- approximate a circle
+end
function vector:normalized()^ top
Get normalized vector, i.e. a vector with the same direction as the input vector, but with length 1.
This does not change the input vector, but creates a new vector.
Parameters:- None
Returns:- vector
Vector with same direction as the input vector, but length 1.
Example:direction = velocity:normalized()
function vector:normalize_inplace()^ top
Normalize a vector, i.e. make the vector unit length. Great to use on intermediate results.
This modifies the vector. If in doubt, use {#vector:normalized()}.
Parameters:- None
Returns:- vector
Itself - the normalized vector
Example:normal = (b - a):perpendicular():normalize_inplace()
function vector:rotated(phi)^ top
Get a rotated vector.
This does not change the input vector, but creates a new vector.
Parameters:- number
phi
Rotation angle in radians.
Returns:- vector
The rotated vector
Example:-- approximate a circle
circle = {}
for i = 1,30 do
local phi = 2 * math.pi * i / 30
circle[#circle+1] = vector(0,1):rotated(phi)
-end
Sketch:function vector:rotate_inplace(phi)^ top
Rotate a vector in-place. Great to use on intermediate results.
This modifies the vector. If in doubt, use vector:rotate()
Parameters:- number
phi
- Rotation angle in radians.
Returns:- vector
- Itself - the rotated vector
Example:-- ongoing rotation
-spawner.direction:rotate_inplace(dt)
function vector:perpendicular()^ top
Quick rotation by 90°. Creates a new vector. The same as (but faster):
-
vec:rotate(math.pi/2)
Parameters:- None.
Returns:- vector
- A vector perpendicular to the input vector
Example:normal = (b - a):perpendicular():normalize_inplace()
Sketch:function vector:projectOn(v)^ top
Project vector onto another vector (see sketch).
Parameters:- vector
v
- The vector to project on.
Returns:- vector
- The projected vector.
Example:velocity_component = velocity:projectOn(axis)
Sketch:function vector:mirrorOn(v)^ top
Mirrors vector on the axis defined by the other vector.
Parameters:- vector
v
- The vector to mirror on.
Returns:- vector
- The mirrored vector.
Example:deflected_velocity = ball.velocity:mirrorOn(surface_normal)
Sketch:function vector:cross(other)^ top
Get cross product of both vectors. Equals the area of the parallelogram
- spanned by both vectors.
Parameters:- vector
other
- Vector to compute the cross product with.
Returns:- number
- Cross product of both vectors.
Example:parallelogram_area = a:cross(b)
Sketch:
-hump.class^ top
hump.class = require "Class"
A small, fast class implementation with multiple inheritance supportModule overview
- new()
- Declare a new class.
- class.construct()
- Call class constructor.
- class:inherit()
- Explicit class inheritance/mixin support.
- object:is_a()
- Test object's type.
function new{constructor, name = the_name, inherits = super}^ top
Declare a new class.
The constructor will receive the newly create object as first argument.
You can check if an object is an instance of a class using object:is_a()
.
The name of the variable that holds the module can be used as a shortcut to
- new()
(see example).
Parameters:- function
constructor
(optional) - Class constructor. Can be accessed with
theclass.construct(object, ...)
- string
the_name
(optional) - Class name (used only to make the class compliant to
tostring()
. - class or table of classes
super
(optional) - Classes to inherit from. Can either be a single class or a table of classes
Returns:- class
- The class
Examples:Class = require 'hump.class' -- `Class' is now a shortcut to new()
+end
Sketch:function vector:rotate_inplace(phi)^ top
Rotate a vector in-place. Great to use on intermediate results.
This modifies the vector. If in doubt, use {#vector:rotate()}
Parameters:- number
phi
Rotation angle in radians.
Returns:- vector
Itself - the rotated vector
Example:-- ongoing rotation
+spawner.direction:rotate_inplace(dt)
function vector:perpendicular()^ top
Quick rotation by 90°. Creates a new vector. The same as (but faster):
vec:rotate(math.pi/2)
Parameters:- None
Returns:- vector
A vector perpendicular to the input vector
Example:normal = (b - a):perpendicular():normalize_inplace()
Sketch:function vector:projectOn(v)^ top
Project vector onto another vector (see sketch).
Parameters:- vector
v
The vector to project on.
Returns:- vector
The projected vector.
Example:velocity_component = velocity:projectOn(axis)
Sketch:function vector:mirrorOn(v)^ top
Mirrors vector on the axis defined by the other vector.
Parameters:- vector
v
The vector to mirror on.
Returns:- vector
The mirrored vector.
Example:deflected_velocity = ball.velocity:mirrorOn(surface_normal)
Sketch:function vector:cross(other)^ top
Get cross product of both vectors. Equals the area of the parallelogram spanned by both vectors.
Parameters:- vector
other
Vector to compute the cross product with.
Returns:- number
Cross product of both vectors.
Example:parallelogram_area = a:cross(b)
Sketch:hump.vector-light^ top
vector = require "hump.vector-light"
An table-free version of hump.vector
. Instead of a vector class, hump.vector-light
provides functions that operate on numbers.
Using this module instead of vector
might result in faster code, but does so at the expense of readability. Unless you are sure that it causes a significant performance penalty, I recommend to use hump.vector
.
Module overview
- str()
- String representation.
- mul()
- Product of a vector and a scalar.
- div()
- Product of a vector and the inverse of a scalar.
- add()
- Sum of two vectors.
- sub()
- Difference of two vectors.
- permul()
- Per element multiplication.
- dot()
- [^http://en.wikipedia.org/wiki/Dot_product Dot product]
- det()
- Cross product
- cross()
- Cross product
- eq()
- Equality.
- le()
- Partial lexical order.
- lt()
- Strict lexical order.
- len()
- Get length.
- len2()
- Get squared length.
- dist()
- Distance of two points.
- normalize()
- Normalize vector.
- rotate()
- Rotate vector.
- perpendicular()
- Get perpendicular vector.
- project()
- Project projection onto another vector.
- mirror()
- Mirrors vector on other vector.
function str(x,y)^ top
Transforms a vector to a string of the form (x,y)
.
Parameters:- numbers
x,y
The vector
Returns:- string
The string representation
Example:print(vector.str(love.mouse.getPosition()))
function mul(s, x,y)^ top
function div(s, x,y)^ top
Computes x*s, y*s
and x/s, y/s
. The order of arguments is chosen so that you can chain multiple operations (see example).
Parameters:- number
s
The scalar.
- numbers
x,y
The vector.
Returns:- numbers
The result of the operation.
Example:velx,vely = vec.mul(dt, vec.add(velx,vely, accx,accy))
x,y = vec.div(self.zoom, x-w/2, y-h/2)
function add(x1,y1, x2,y2)^ top
function sub(x1,y1, x2,y2)^ top
Computes the sum/difference of vectors. Same as x1+x2, y1+y2
or x1-x2, y1-y2
respectively. Meant to be used in conjunction with other functions.
Parameters:- numbers
x1,y1
First vector.
- numbers
x2,y2
Second vector.
Returns:- numbers
The result of the operation.
Example:player.x,player.y = vector.add(player.x,player.y, vector.mul(dt, dx,dy))
dx,dy = vector.sub(400,300, love.mouse.getPosition())
function permul(x1,y1, x2,y2)^ top
Multiplies vectors coordinate wise, i.e. x1*x2, y1*y2)
.
Parameters:- numbers
x1,y1
First vector.
- numbers
x2,y2
Second vector.
Returns:- numbers
The result of the operation.
Example:x,y = vector.permul(x,y, 1,1.5)
function dot(x1,y1, x2,y2)^ top
Computes the dot product of two vectors, x1*x2 + y1*y2
.
Parameters:- numbers
x1,y1
First vector.
- numbers
x2,y2
Second vector.
Returns:- number
The dot product.
Example:cosphi = vector.dot(rx,ry, vx,vy)
function det(x1,y1, x2,y2)^ top
function cross(x1,y1, x2,y2)^ top
Computes the cross product/determinant of two vectors, x1*y2 - y1*x2
.
Parameters:- numbers
x1,y1
First vector.
- numbers
x2,y2
Second vector.
Returns:- number
The cross product.
Example:parallelogram_area = vector.det(ax,ay, bx,by)
function eq(x1,y1, x2,y2)^ top
function le(x1,y1, x2,y2)^ top
function lt(x1,y1, x2,y2)^ top
Compares two vectors according to
vector.eq(x1,y1, x2,y2)
x1 == x2 and y1 == y2
vector.le(x1,y1, x2,y2)
x1 <= x2 and y1 <= y2
vector.lt(x1,y1, x2,y2)
x1 < x2 or (x1 == x2) and y1 <= y2
Parameters:- numbers
x1,y1
First vector.
- numbers
x2,y2
Second vector.
Returns:- boolean
The result of the operation.
Example:...
function len(x,y)^ top
Get length of a vector, i.e. math.sqrt(x*x + y*y)
.
Parameters:- numbers
x,y
The vector.
Returns:- number
Length of the vector.
Example:distance = vector.len(love.mouse.getPosition())
function len2(x,y)^ top
Get squared length of a vector, i.e. x*x + y*y
.
Parameters:- numbers
x,y
The vector.
Returns:- number
Squared length of the vector.
Example:-- get closest vertex to a given vector
+closest, dsq = vertices[1], vector.len2(px-vertices[1].x, py-vertices[1].y)
+for i = 2,#vertices do
+ local temp = vector.len2(px-vertices[i].x, py-vertices[i].y)
+ if temp < dsq then
+ closest, dsq = vertices[i], temp
+ end
+end
function dist(x1,y1, x2,y2)^ top
Get distance of two points. The same as vector.len(x1-x2, y1-y2)
.
Parameters:- numbers
x1,y1
First vector.
- numbers
x2,y2
Second vector.
Returns:- number
The distance of the points.
Example:-- get closest vertex to a given vector
+-- slightly slower than the example using len2()
+closest, dist = vertices[1], vector.dist(px,py, vertices[1].x,vertices[1].y)
+for i = 2,#vertices do
+ local temp = vector.dist(px,py, vertices[i].x,vertices[i].y)
+ if temp < dist then
+ closest, dist = vertices[i], temp
+ end
+end
function normalize(x,y)^ top
Get normalized vector, i.e. a vector with the same direction as the input vector, but with length 1.
Parameters:- numbers
x,y
The vector.
Returns:- numbers
Vector with same direction as the input vector, but length 1.
Example:dx,dy = vector.normalize(vx,vy)
function rotate(phi, x,y)^ top
Get a rotated vector.
Parameters:- number
phi
Rotation angle in radians.
- numbers
x,y
The vector.
Returns:- numbers
The rotated vector
Example:-- approximate a circle
+circle = {}
+for i = 1,30 do
+ local phi = 2 * math.pi * i / 30
+ circle[i*2-1], circle[i*2] = vector.rotate(phi, 0,1)
+end
function perpendicular(x,y)^ top
Quick rotation by 90°. The same as (but faster)
vector.rotate(math.pi/2, x,y)
Parameters:- numbers
x,y
The vector.
Returns:- numbers
A vector perpendicular to the input vector
Example:nx,ny = vector.normalize(vector.perpendicular(bx-ax, by-ay))
function project(x,y, u,v)^ top
Project vector onto another vector.
Parameters:- numbers
x,y
The vector to project.
- numbers
u,v
The vector to project onto.
Returns:- numbers
The projected vector.
Example:vx_p,vy_p = vector.project(vx,vy, ax,ay)
function mirror(x,y, u,v)^ top
Mirrors vector on the axis defined by the other vector.
Parameters:- numbers
x,y
The vector to mirror.
- numbers
u,v
The vector defining the axis.
Returns:- numbers
The mirrored vector.
Example:vx,vy = vector.mirror(vx,vy, surface.x,surface.y)
hump.class^ top
Class = require "hump.class"
A small, fast class implementation with multiple inheritance support
Module overview
- new()
- Declare a new class.
- class.construct()
- Call class constructor.
- class:inherit()
- Explicit class inheritance/mixin support.
- object:is_a()
- Test object's type.
- caveats
- Caveats
function new(constructor, the_name, super)^ top
Declare a new class.
The constructor will receive the newly create object as first argument.
You can check if an object is an instance of a class using object:is_a()
.
The name of the variable that holds the module can be used as a shortcut to new()
(see example).
Parameters:- function
constructor
Class constructor. Can be accessed with theclass.construct(object, ...)
- string
the_name
Class name (used only to make the class compliant to tostring()
.
- class or table of classes
super
Classes to inherit from. Can either be a single class or a table of classes
Returns:- class
The class
Example:Class = require 'hump.class' -- `Class' is now a shortcut to new()
--- define class without a name
+-- define class with implicit name 'Feline'
Feline = Class{function(self, size, weight)
self.size = size
self.weight = weight
end}
-print(Feline) -- prints '<unnamed class>'
+print(Feline) -- prints 'Feline'
-- define class method
function Feline:stats()
- return string.format("size: %.02f, weight %.02f", self.size, self.weight)
+ return string.format("size: %.02f, weight %.02f", self.size, self.weight)
end
-- create two objects
garfield = Feline(.7, 45)
felix = Feline(.8, 12)
-print("Garfield: " .. garfield:stats(), "Felix: " .. felix:stats())
-
Class = require 'hump.class'
+print("Garfield: " .. garfield:stats(), "Felix: " .. felix:stats())
+
Class = require 'hump.class'
--- define class with explicit name 'Feline'
-Feline = Class{name = "Feline", function(self, size, weight)
+-- define class with explicit name 'Feline'
+Feline = Class{name = "Feline", function(self, size, weight)
self.size = size
self.weight = weight
end}
garfield = Feline(.7, 45)
-print(Feline, garfield) -- prints 'Feline <instance of Feline>'
-
Class = require 'hump.class'
+print(Feline, garfield) -- prints 'Feline '
+
Class = require 'hump.class'
A = Class{}
function A:foo()
- print('foo')
+ print('foo')
end
B = Class{}
function B:bar()
- print('bar')
+ print('bar')
end
-- single inheritance
C = Class{inherits = A}
instance = C()
-instance:foo() -- prints 'foo'
+instance:foo() -- prints 'foo'
-- multiple inheritance
D = Class{inherits = {A,B}}
instance = D()
-instance:foo() -- prints 'foo'
-instance:bar() -- prints 'bar'
-
function class.construct(object, ...)^ top
Calls class constructor of a class on an object
Derived classes use this function their constructors to initialize the
- parent class(es) portions of the object.
Parameters:- Object
object
- The object. Usually
self
. - mixed
...
- Arguments to pass to the constructor
Returns:- mixed
- Whatever the parent class constructor returns
Examples:Class = require 'hump.class'
+instance:foo() -- prints 'foo'
+instance:bar() -- prints 'bar'
+
function class.construct(object, ...)^ top
Calls class constructor of a class on an object
Derived classes use this function their constructors to initialize the parent class(es) portions of the object.
Parameters:- Object
object
The object. Usually self
.
- mixed
...
Arguments to pass to the constructor
Returns:- mixed
Whatever the parent class constructor returns
Example:Class = require 'hump.class'
Shape = Class{function(self, area)
self.area = area
end}
function Shape:__tostring()
- return "area = " .. self.area
+ return "area = " .. self.area
end
Rectangle = Class{inherits = Shape, function(self, width, height)
@@ -321,14 +195,14 @@ Rectangle = Class{inherits = Shape, function(self, width, height)
end}
function Rectangle:__tostring()
local strs = {
- "width = " .. self.width,
- "height = " .. self.height,
+ "width = " .. self.width,
+ "height = " .. self.height,
Shape.__tostring(self)
},
- return table.concat(strs, ", ")
+ return table.concat(strs, ", ")
end
-print( Rectangle(2,4) ) -- prints 'width = 2, height = 4, area = 8'
+print( Rectangle(2,4) ) -- prints 'width = 2, height = 4, area = 8'
Menu = Class{function(self)
self.entries = {}
end}
@@ -352,14 +226,7 @@ Submenu = Class{inherits = {Menu, Entry}, function(self, title)
-- redirect self:execute() to self:display()
Entry.construct(self, title, Menu.display)
end}
-
function class:inherit(...)^ top
Inherit functions and variables of another class, if they are not already
- defined for the class. This is done by simply copying the functions and
- variables over to the subclass. The Lua rules for copying apply
- (i.e. tables are referenced, functions and primitive types are copied by value).
Be careful with changing table values in a subclass: This will change the
- value in the parent class too.
If more than one parent class is specified, inherit from all of these, in
- order of occurrence. That means that when two parent classes define the same
- method, the one from the first class will be inherited.
Note: class:inherit()
doesn't actually care if the arguments supplied are
- hump classes. Just any table will work.
Parameters:- tables
...
- Parent classes to inherit from
Returns:- Nothing.
Example:Class = require 'hump.class'
+
function class:inherit(...)^ top
Inherit functions and variables of another class, if they are not already defined for the class. This is done by simply copying the functions and variables over to the subclass. The Lua rules for copying apply (i.e. tables are referenced, functions and primitive types are copied by value).
Be careful with changing table values in a subclass: This will change the value in the parent class too.
If more than one parent class is specified, inherit from all of these, in order of occurrence. That means that when two parent classes define the same method, the one from the first class will be inherited.
Note: class:inherit()
doesn't actually care if the arguments supplied are hump classes. Just any table will work.
Parameters:- tables
...
Parent classes to inherit from
Returns:- Nothing
Example:Class = require 'hump.class'
Entity = Class{function(self)
GameObjects.register(self)
@@ -370,194 +237,95 @@ Collidable = {
if self.collision_handler[other.type])
return collision_handler[other.type](self, other, dx, dy)
end
- return collision_handler["*"](self, other, dx, dy)
+ return collision_handler["*"](self, other, dx, dy)
end,
- collision_handler = {["*"] = function() end},
+ collision_handler = {["*"] = function() end},
}
Spaceship = Class{function(self)
- self.type = "Spaceship"
+ self.type = "Spaceship"
-- ...
end}
-- make Spaceship collidable
Spaceship:inherit(Collidable)
-function Spaceship:collision_handler["Spaceship"](other, dx, dy)
+function Spaceship:collision_handler["Spaceship"](other, dx, dy)
-- ...
end
-
function object:is_a(cls)^ top
Tests whether an object is an instance of a class.
Parameters:- class
cls
- Class to test. Note: this is the class itself, not the name of the class.
Returns:- Boolean
true
if the object is an instance of the class, false
otherwise
Example:Class = require 'hump.class'
+
function object:is_a(cls)^ top
Tests whether an object is an instance of a class.
Parameters:- class
cls
Class to test. Note: this is the class itself, not the name of the class.
Returns:- Boolean
true
if the object is an instance of the class, false
otherwise
Example:Class = require 'hump.class'
A = Class{}
B = Class{inherits=A}
C = Class{inherits=B}
a, b, c = A(), B(), C()
-print(a:is_a(A), a:is_a(B), a:is_a(C)) --> true false false
-print(b:is_a(A), b:is_a(B), b:is_a(C)) --> true true false
-print(c:is_a(A), c:is_a(B), c:is_a(C)) --> true true true
+print(a:is_a(A), a:is_a(B), a:is_a(C)) --> true false false
+print(b:is_a(A), b:is_a(B), b:is_a(C)) --> true true false
+print(c:is_a(A), c:is_a(B), c:is_a(C)) --> true true true
D = Class{}
E = Class{inherits={B,D}}
d, e = D(), E()
-print(d:is_a(A), d:is_a(B), d:is_a(D)) --> false false true
-print(e:is_a(A), e:is_a(B), e:is_a(D)) --> true true true
-
Caveats
Be careful when using metamethods like __add
or __mul
: If subclass
- inherits those methods from a superclass, but does not overwrite them, the
- result of the operation may be of the type superclass. Consider the following:
-
Class = require 'hump.class'A = Class{function(self, x) self.x = x end}
-function A:__add(other) return A(self.x + other.x) end
-function A:show() print("A:", self.x) end
B = Class{inherits = A, function(self, x, y) A.construct(self, x) self.y = y end}
-function B:show() print("B:", self.x, self.y) end
-function B:foo() print("foo") end
one, two = B(1,2), B(3,4)
-result = one + two
-result:show() -- prints "A: 4"
-result:foo() -- error: method does not exist
Note that while you can define the __index
metamethod of the class, this
- is not a good idea: It will break the class. To add a custom __index
- metamethod without breaking the class system, you have to use rawget().
- But beware that this won't affect subclasses:
-
Class = require 'hump.class'A = Class{}
-function A:foo() print('bar') end
function A:__index(key)
- print(key)
- return rawget(A, key)
-end
instance = A()
-instance:foo() -- prints foo <newline> bar
B = Class{inherits = A}
-instance = B()
-instance:foo() -- prints only foo
-hump.camera^ top
hump.camera = require "Camera"
Depends on hump.vector A camera utility for LÖVE. A camera can "look" at a position. It can zoom in and
- out and it can rotate it's view. In the background, this is done by actually
- moving, scaling and rotating everything in the game world. But don't worry about
- that.
Module overview
- new()
- Create a new camera object.
- camera:rotate()
- Rotate camera object.
- camera:move()
- Move camera object.
- camera:attach()
- Attach camera object.
- camera:detach()
- Detach camera object.
- camera:draw()
- Attach, draw and detach.
- camera:worldCoords()
- Convert point to world coordinates.
- camera:cameraCoords()
- Convert point to camera coordinates.
- camera:mousepos()
- Get mouse position in world coordinates.
function new(pos, zoom, rot)^ top
Creates a new camera object. You can access the camera position using
- camera.pos
, the zoom using camera.zoom
and the rotation using
- camera.rot
.
The module variable name can be used at a shortcut to new()
.
Parameters:- vector
pos
(screen center) - Point for the camera to look at.
- number
zoom
(1) - Camera zoom.
- number
rot
(0) - Camera rotation in radians.
Returns:- camera
- A new camera object.
Example:camera = require 'hump.camera'
-vector = require 'hump.vector'
+print(d:is_a(A), d:is_a(B), d:is_a(D)) --> false false true
+print(e:is_a(A), e:is_a(B), e:is_a(D)) --> true true true
+
Caveats^ top
Be careful when using metamethods like __add
or __mul
: If subclass inherits those methods from a superclass, but does not overwrite them, the result of the operation may be of the type superclass. Consider the following:
Class = require 'hump.class'A = Class{function(self, x) self.x = x end}function A:__add(other) return A(self.x + other.x) endfunction A:show() print("A:", self.x) end
B = Class{inherits = A, function(self, x, y) A.construct(self, x) self.y = y end}function B:show() print("B:", self.x, self.y) endfunction B:foo() print("foo") end
one, two = B(1,2), B(3,4)result = one + tworesult:show() -- prints "A: 4"result:foo() -- error: method does not exist
Note that while you can define the __index
metamethod of the class, this is not a good idea: It will break the class. To add a custom __index metamethod without breaking the class system, you have to use rawget(). But beware that this won't affect subclasses:
Class = require 'hump.class'A = Class{}function A:foo() print('bar') end
function A:__index(key) print(key) return rawget(A, key)end
instance = A()instance:foo() -- prints foo bar
B = Class{inherits = A}instance = B()instance:foo() -- prints only foo
hump.camera^ top
Camera = require "hump.camera"
Depends on hump.vector-light
A camera utility for LÖVE. A camera can "look" at a position. It can zoom in andout and it can rotate it's view. In the background, this is done by actuallymoving, scaling and rotating everything in the game world. But don't worry aboutthat.
Module overview
- new()
- Create a new camera object.
- camera:rotate()
- Rotate camera object.
- camera:move()
- Move camera object.
- camera:attach()
- Attach camera object.
- camera:detach()
- Detach camera object.
- camera:draw()
- Attach, draw and detach.
- camera:worldCoords()
- Convert point to world coordinates.
- camera:cameraCoords()
- Convert point to camera coordinates.
- camera:mousepos()
- Get mouse position in world coordinates.
function new(x,y, zoom, rot)^ top
Creates a new camera object. You can access the camera position using camera.x, camera.y
, the zoom using camera.zoom
and the rotation using camera.rot
.
The module variable name can be used at a shortcut to new()
.
Parameters:- numbers
x,y
Point for the camera to look at.
- number
zoom
Camera zoom.
- number
rot
Camera rotation in radians.
Returns:- camera
A new camera object.
Example:camera = require 'hump.camera'
-- camera looking at (100,100) with zoom 2 and rotated by 45 degrees
-cam = camera(vector(100,100), 2, math.pi/2)
-
function camera:rotate(angle)^ top
Rotate the camera by some angle. To set the angle use
- camera.rot = new_angle
.
This function is shortcut to camera.rot = camera.rot + angle
.
Parameters:- number
angle
- Rotation angle in radians
Returns:- camera
- The camera object.
Examples:function love.update(dt)
+cam = camera(100,100, 2, math.pi/2)
+
function camera:rotate(angle)^ top
Rotate the camera by some angle. To set the angle use camera.rot = new_angle
.
This function is shortcut to camera.rot = camera.rot + angle
.
Parameters:- number
angle
Rotation angle in radians
Returns:- camera
The camera object.
Example:function love.update(dt)
camera:rotate(dt)
end
function love.update(dt)
- camera:rotate(dt):move(dt)
-end
function camera:move(v)^ top
function camera:move(x, y)^ top
Move the camera by some vector. To set the position, use
- camera.pos = some_vector
or camera.pos.x, camera.pos.y = new_x, new_y
.
This function is shortcut to camera.pos = camera.pos + v
.
Parameters:- vector
v
- Direction to move the camera.
- numbers
x, y
- Direction to move the camera.
Returns:- camera
- The camera object.
Examples:function love.update(dt)
- camera:move(dt * velocity)
-end
function love.update(dt)
+ camera:rotate(dt):move(dt,dt)
+end
function camera:move(dx,dy)^ top
Move the camera by some vector. To set the position, use camera.x,camera.y = new_x,new_y
.
This function is shortcut to camera.x,camera.y = camera.x+dx, camera.y+dy
.
Parameters:- numbers
dx,dy
Direction to move the camera.
Returns:- camera
The camera object.
Example:function love.update(dt)
camera:move(dt * 5, dt * 6):rotate(dt)
-end
function camera:attach()^ top
Start looking through the camera.
Apply camera transformations, i.e. move, scale and rotate everything until
- camera:detach()
as if looking through the camera.
Parameters:- None.
Returns:- Nothing.
Example:function love.draw()
+end
function camera:attach()^ top
Start looking through the camera.
Apply camera transformations, i.e. move, scale and rotate everything until camera:detach()
as if looking through the camera.
Parameters:- None
Returns:- Nothing
Example:function love.draw()
camera:attach()
draw_world()
cam:detach()
draw_hud()
-end
function camera:detach()^ top
Stop looking through the camera.
Parameters:- None.
Returns:- Nothing.
Example:function love.draw()
+end
function camera:detach()^ top
Stop looking through the camera.
Parameters:- None
Returns:- Nothing
Example:function love.draw()
camera:attach()
draw_world()
cam:detach()
draw_hud()
-end
function camera:draw(func)^ top
Wrap a function between a camera:attach()
/camera:detach()
pair:
-
cam:attach()
-func()
-cam:detach()
Parameters:- function
func
- Drawing function to be wrapped.
Returns:- Nothing.
Example:function love.draw()
+end
function camera:draw(func)^ top
Wrap a function between a camera:attach()
/camera:detach()
pair:
cam:attach()func()cam:detach()
Parameters:- function
func
Drawing function to be wrapped.
Returns:- Nothing
Example:function love.draw()
camera:draw(draw_world)
draw_hud()
-end
function camera:worldCoords(v)^ top
function camera:worldCoords(x, y)^ top
function camera:cameraCoords(v)^ top
function camera:cameraCoords(x, y)^ top
Because a camera has a point it looks at, a rotation and a zoom factor, it
- defines a coordinate system. A point now has two sets of coordinates: One
- defines where the point is to be found in the game world, and the other
- describes the position on the computer screen. The first set of coordinates
- is called world coordinates, the second one camera coordinates.
-
- Sometimes it is needed to convert between the two coordinate systems, for
- example to get the position of a mouse click in the game world in a strategy
- game, or to see if an object is visible on the screen.
These two functions convert a point between these two coordinate systems.
Parameters:- vector
v
- Point to transform.
- numbers
x, y
- Point to transform.
Returns:- vector
- Transformed point.
Examples:target = camera:worldCoords( vector(love.mouse.getPosition()) )
-selectedUnit:plotPath(target)
-
pos = cam:toCameraCoords(player.pos)
-love.graphics.line(pos.x, pos.y, love.mouse.getPosition())
-
function camera:mousepos()^ top
Shortcut to camera:worldCoords(vector(love.mouse.getPosition()))
.
Parameters:- None.
Returns:- vector
- Mouse position in world coordinates.
Example:target = camera:mousepos()
-selectedUnit:plotPath(target)
-
-hump.ringbuffer^ top
hump.ringbuffer = require "Ringbuffer"
A ring-buffer is a circular array: It does not have a first nor a last item,
- but it has a selected or current element. A ring-buffer can be used to implement Tomb Raider style inventories, looping
- play-lists, recurring dialogs (like a unit's answers when selecting it multiple
- times in Warcraft) and generally everything that has a circular or looping
- structure.
Module overview
- new()
- Create new ring-buffer.
- ringbuffer:insert()
- Insert element.
- ringbuffer:remove()
- Remove currently selected item.
- ringbuffer:removeAt()
- Remove an item.
- ringbuffer:next()
- Select next item.
- ringbuffer:prev()
- Select previous item.
- ringbuffer:get()
- Get currently selected item.
- ringbuffer:size()
- Get ringbuffer size.
function new(...)^ top
Create new ring-buffer.
The module name is a shortcut to this function.
Parameters:- mixed
...
- Initial elements.
Returns:- Ringbuffer
- The ring-buffer object.
Example:Ringbuffer = require 'hump.ringbuffer'
+end
function camera:worldCoords(x, y)^ top
function camera:cameraCoords(x, y)^ top
Because a camera has a point it looks at, a rotation and a zoom factor, it defines a coordinate system. A point now has two sets of coordinates: One defines where the point is to be found in the game world, and the other describes the position on the computer screen. The first set of coordinates is called world coordinates, the second one camera coordinates. Sometimes it is needed to convert between the two coordinate systems, for example to get the position of a mouse click in the game world in a strategy game, or to see if an object is visible on the screen.
These two functions convert a point between these two coordinate systems.
Parameters:- numbers
x, y
Point to transform.
Returns:- numbers
Transformed point.
Example:x,y = camera:worldCoords(love.mouse.getPosition())
+selectedUnit:plotPath(x,y)
+
x,y = cam:toCameraCoords(player.pos)
+love.graphics.line(x, y, love.mouse.getPosition())
+
function camera:mousepos()^ top
Shortcut to camera:worldCoords(vector(love.mouse.getPosition()))
.
Parameters:- None
Returns:- numbers
Mouse position in world coordinates.
Example:x,y = camera:mousepos()
+selectedUnit:plotPath(x,y)
+
hump.ringbuffer^ top
Ringbuffer = require "hump.ringbuffer"
A ring-buffer is a circular array: It does not have a first nor a last item,but it has a selected or current element.
A ring-buffer can be used to implement Tomb Raider style inventories, loopingplay-lists, recurring dialogs (like a unit's answers when selecting it multipletimes in Warcraft) and generally everything that has a circular or loopingstructure.
Module overview
- new()
- Create new ring-buffer.
- ringbuffer:insert()
- Insert element.
- ringbuffer:remove()
- Remove currently selected item.
- ringbuffer:removeAt()
- Remove an item.
- ringbuffer:next()
- Select next item.
- ringbuffer:prev()
- Select previous item.
- ringbuffer:get()
- Get currently selected item.
- ringbuffer:size()
- Get ringbuffer size.
function new(...)^ top
Create new ring-buffer.
The module name is a shortcut to this function.
Parameters:- mixed
...
Initial elements.
Returns:- Ringbuffer
The ring-buffer object.
Example:Ringbuffer = require 'hump.ringbuffer'
rb = ringbuffer(1,2,3)
-
function ringbuffer:insert(...)^ top
Insert items behind current element.
Parameters:- mixed
...
- Items to insert.
Returns:- Nothing.
Example:rb = RingbuffeR(1,5,6) -- content: 1,5,6
+
function ringbuffer:insert(...)^ top
Insert items behind current element.
Parameters:- mixed
...
Items to insert.
Returns:- Nothing
Example:rb = RingbuffeR(1,5,6) -- content: 1,5,6
rb:insert(2,3,4) -- content: 1,2,3,4,5,6
-
function ringbuffer:remove()^ top
Remove current item, return it and select next element.
Parameters:- None.
Returns:- mixed
- The removed item.
Example:rb = Ringbuffer(1,2,3,4) -- content: 1,2,3,4
+
function ringbuffer:remove()^ top
Remove current item, return it and select next element.
Parameters:- None
Returns:- mixed
The removed item.
Example:rb = Ringbuffer(1,2,3,4) -- content: 1,2,3,4
val = rb:remove() -- content: 2,3,4
-print(val) -- prints `1'
-
function ringbuffer:removeAt(pos)^ top
Remove the item at a position relative to the current element.
Parameters:- number
pos
- Position of the item to remove.
Returns:- mixed
- The removed item.
Example:rb = Ringbuffer(1,2,3,4,5) -- content: 1,2,3,4,5
+print(val) -- prints `1'
+
function ringbuffer:removeAt(pos)^ top
Remove the item at a position relative to the current element.
Parameters:- number
pos
Position of the item to remove.
Returns:- mixed
The removed item.
Example:rb = Ringbuffer(1,2,3,4,5) -- content: 1,2,3,4,5
rb:removeAt(2) -- content: 1,2,4,5
rb:removeAt(-1) -- content: 1,2,4
-
function ringbuffer:next()^ top
Select and return the next element.
Parameters:- None.
Returns:- mixed
- The next item.
Example:rb = Ringbuffer(1,2,3)
+
function ringbuffer:next()^ top
Select and return the next element.
Parameters:- None
Returns:- mixed
The next item.
Example:rb = Ringbuffer(1,2,3)
rb:next() -- content: 2,3,1
rb:next() -- content: 3,1,2
x = rb:next() -- content: 1,2,3
-print(x) -- prints `1'
-
function ringbuffer:prev()^ top
Select and return the previous item.
Parameters:- None.
Returns:- mixed
- The previous item.
Example:rb = Ringbuffer(1,2,3)
+print(x) -- prints `1'
+
function ringbuffer:prev()^ top
Select and return the previous item.
Parameters:- None
Returns:- mixed
The previous item.
Example:rb = Ringbuffer(1,2,3)
rb:prev()) -- content: 3,1,2
rb:prev()) -- content: 2,3,1
x = rb:prev() -- content: 1,2,3
-print(x) -- prints `1'
-
function ringbuffer:get()^ top
Return the current element.
Parameters:- None.
Returns:- mixed
- The currently selected element.
Example:rb = Ringbuffer(1,2,3)
+print(x) -- prints `1'
+
function ringbuffer:get()^ top
Return the current element.
Parameters:- None
Returns:- mixed
The currently selected element.
Example:rb = Ringbuffer(1,2,3)
rb:next() -- content: 2,3,1
-print(rb:get()) -- prints '2'
-
function ringbuffer:size()^ top
Get number of items in the buffer
Parameters:- None.
Returns:- number
- Number of items in the buffer.
Example:rb = Ringbuffer(1,2,3)
-print(rb:size()) -- prints '3'
+print(rb:get()) -- prints '2'
+
function ringbuffer:size()^ top
Get number of items in the buffer
Parameters:- None
Returns:- number
Number of items in the buffer.
Example:rb = Ringbuffer(1,2,3)
+print(rb:size()) -- prints '3'
rb:remove()
-print(rb:size()) -- prints '2'
-
-
Yay, free software:
- --Copyright (c) 2010 Matthias Richter
-Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions:
- -The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software.
- -Except as contained in this notice, the name(s) of the above copyright holders - shall not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization.
- -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE.
You can view and download the individual modules on github: vrld/hump. - You may also download the whole packed sourcecode either in - zip or - tar formats.
-You can clone the project with Git by running: -
git clone git://github.com/vrld/hump- Once done, tou can check for updates by running -
git pull-
Yay, free software:
Copyright (c) 2010 Matthias Richter
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
Except as contained in this notice, the name(s) of the above copyright holders shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
' + if c == '[' then return element(out, next) end + out[#out+1] = c + return block(out, next) + end + + function block(out, next) + local c = next() + if not c then out[#out+1] = '
' return out end + if c == '[' then return element(out, next) end + if c == '\n' then return block2(out, next) end + out[#out+1] = c + return block(out, next) + end + + function block2(out, next) + local c = next() + if not c then out[#out+1] = '' return out end + if c == '[' then return element(out, next) end + if c == '\n' then out[#out+1] = '' return parse(out, next) end + + if c ~= ' ' and c ~= '\t' then out[#out+1] = c end + return block(out, next) + end + + function element(out, next) + local c = assert(next(), 'markup error') + if c == '^' then out[#out+1] = '' return title(out, next) end + out[#out+1] = c + return url(out, next) + end + + function title(out, next) + local c = assert(next(), 'markup error') + if c == ']' then out[#out+1] = '' return block(out, next) end + out[#out+1] = c + return title(out, next) + end + + function def(out, next) + local c = assert(next(), 'markup error') + if c == ' ' or c == '\t' or c == '\n' then return def(out, next) end + if c == ']' then out[#out+1] = '' return block(out, next) end + out[#out+1] = ''..rest..'
' end
+ if cmd == '%' then return ''..rest..'
' end
+ if cmd == '*' then return ''..rest..'' end
+ if cmd == '!' then return ''..rest..'' end
+ return m
+ end)
+end
+
+
+-- PREPARE DOCUMENTATION MARKUP
+local DOC = { short = {}, long = {} }
+
+function Module(M)
+ for _,field in ipairs{'name', 'title', 'short', 'long'} do
+ assert(M[field], "Module: Required field `"..field.."' is missing")
+ end
+
+ DOC.short[#DOC.short+1] = ('%s = require "%s"
', M.title:gsub("^(%w+)%W.+", "%1"), M.name)
+ F(markup(M.long))
+ F('')
+ F(M.example[i])
+ F('
')
+ end
+ F('%s
')
+ F(M.example[i])
+ F('
')
+ end
+ F('Helper Utilities for a Multitude of Problems is a set of lightweight helpers for the awesome LÖVE Engine.
It features
hump differs from other libraries in that every component is independent of the remaining ones (apart from camera.lua, which does depends on vector.lua). hump's footprint is very small and thus should fit nicely into your projects.
Yay, free software:
Copyright (c) 2010 Matthias Richter
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
Except as contained in this notice, the name(s) of the above copyright holders shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.