diff --git a/index.html b/index.html index 6e18a19..bf4c956 100644 --- a/index.html +++ b/index.html @@ -35,7 +35,7 @@ function menu:mousereleased(x,y, mouse_btn) button:onClick() end end -end
Declare a new gamestate. A gamestate can define several callbacks.
The new gamestate.
menu = Gamestate.new()
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.
to
Target gamestate.
...
Additional arguments to pass to to:enter().
The results of to:enter()
Gamestate.switch(game, level_two)
Calls the corresponding function on the current gamestate (see callbacks).
Only needed when not using registerEvents().
...
Arguments to pass to the corresponding callback.
The results of the callback function.
function love.update(dt)
+end
Declare a new gamestate. A gamestate can define several callbacks.
menu = Gamestate.new()
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.
to
...
Gamestate.switch(game, level_two)
Calls the corresponding function on the current gamestate (see callbacks).
Only needed when not using registerEvents().
...
function love.update(dt)
Gamestate.update(dt)
end
@@ -49,28 +49,28 @@ function love.keypressed(key, code)
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.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.
function love.load()
Gamestate.registerEvents()
Gamestate.switch(menu)
-end
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.
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).
delay
Number of seconds the function will be delayed.
func
The function to be delayed.
The timer handle.
-- grant the player 5 seconds of immortality
+end
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.
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).
delay
func
-- 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)
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.
delay
Number of seconds between two consecutive function calls.
func
The function to be called periodically.
count
Number of times the function is to be called.
The timer handle.
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(1, function(func) print("foo") Timer.add(1, func) end)
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.
delay
func
count
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)
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.
func
The function to be canceled.
function tick()
+end)
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.
func
function tick()
print('tick... tock...')
end
handle = Timer.addPeriodic(1, tick)
-- later
-Timer.cancel(handle) -- NOT: Timer.cancel(tick)
Remove all timed and periodic functions. Functions that have not yet been executed will discarded.
Timer.clear()
Update timers and execute functions if the deadline is reached. Use this in love.update(dt).
dt
Time that has passed since the last update().
function love.update(dt)
+Timer.cancel(handle) -- NOT: Timer.cancel(tick)
Remove all timed and periodic functions. Functions that have not yet been executed will discarded.
Timer.clear()
Update timers and execute functions if the deadline is reached. Use this in love.update(dt).
dt
function love.update(dt)
do_stuff()
Timer.update(dt)
-end
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.length
Interpolation length in seconds.
func
Interpolating function.
The wrapper function.
fader = Timer.Interpolator(5, function(frac, r,g,b)
+end
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.length
func
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
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.
length
Length of one interpolation period.
func
Oscillating function.
The wrapper function.
mover = Timer.Oscillator(10, function(frac)
+end
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.
length
func
mover = Timer.Oscillator(10, function(frac)
return 400 + 300 * math.sin(2*math.pi*frac)
end)
@@ -84,18 +84,18 @@ function love.draw()
end
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
.
Vector arithmetic is implemented by using __add
, __mul
and other metamethods:
vector + vector = vector
vector - vector = vector
vector * vector = number
number * vector = vector
vector * number = vector
vector / number = vector
Relational operators are defined, too:
true
, if a.x == b.x
and a.y == b.y
.true
, if a.x <= b.x
and a.y <= b.y
.true
, if a.x < b.x
or a.x == b.x
and a.y < b.y
.-- 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
Create a new vector.
x,y
Coordinates.
The vector.
a = vector.new(10,10)
-- as a shortcut, you can call the module like a function:
+player.position = player.position + player.velocity * dt
Create a new vector.
x,y
a = vector.new(10,10)
-- as a shortcut, you can call the module like a function:
vector = require "hump.vector"
-a = vector(10,10)
Test whether a variable is a vector.
v
The variable to test.
true
if v
is a vector, false
otherwise
if not vector.isvector(v) then
+a = vector(10,10)
Test whether a variable is a vector.
v
true
if v
is a vector, false
otherwiseif not vector.isvector(v) then
v = vector(v,0)
-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 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)'
Copy of the vector
copy = original:clone
Extract coordinates.
The coordinates
x,y = pos:unpack()
love.graphics.draw(self.image, self.pos:unpack())
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.
other
The other vector
The new vector as described above
scaled = original:permul(vector(1,1.5))
Get length of a vector, i.e. math.sqrt(vec.x * vec.x + vec.y * vec.y)
.
Length of the vector.
distance = (a - b):len()
Get squared length of a vector, i.e. vec.x * vec.x + vec.y * vec.y
.
Squared length of the vector.
-- get closest vertex to a given vector
+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 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)'
copy = original:clone
Extract coordinates.
x,y = pos:unpack()
love.graphics.draw(self.image, self.pos:unpack())
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.
other
scaled = original:permul(vector(1,1.5))
Get length of a vector, i.e. math.sqrt(vec.x * vec.x + vec.y * vec.y)
.
distance = (a - b):len()
Get squared length of a vector, i.e. vec.x * vec.x + vec.y * vec.y
.
-- 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
closest, dsq = vertices[i], temp
end
-end
Get distance of two vectors. The same as (a - b):len()
.
other
Other vector to measure the distance to.
The distance of the vectors.
-- get closest vertex to a given vector
+end
Get distance of two vectors. The same as (a - b):len()
.
other
-- 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
@@ -103,20 +103,20 @@ for i = 2,#vertices do
if temp < dist then
closest, dist = vertices[i], temp
end
-end
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.
Vector with same direction as the input vector, but length 1.
direction = velocity:normalized()
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()}.
Itself - the normalized vector
normal = (b - a):perpendicular():normalize_inplace()
Get a rotated vector.
This does not change the input vector, but creates a new vector.
phi
Rotation angle in radians.
The rotated vector
-- approximate a circle
+end
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.
direction = velocity:normalized()
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()}.
normal = (b - a):perpendicular():normalize_inplace()
Get a rotated vector.
This does not change the input vector, but creates a new vector.
phi
-- 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
Rotate a vector in-place. Great to use on intermediate results.
This modifies the vector. If in doubt, use {#vector:rotate()}
phi
Rotation angle in radians.
Itself - the rotated vector
-- ongoing rotation
-spawner.direction:rotate_inplace(dt)
Quick rotation by 90°. Creates a new vector. The same as (but faster):
vec:rotate(math.pi/2)
A vector perpendicular to the input vector
normal = (b - a):perpendicular():normalize_inplace()
Project vector onto another vector (see sketch).
v
The vector to project on.
The projected vector.
velocity_component = velocity:projectOn(axis)
Mirrors vector on the axis defined by the other vector.
v
The vector to mirror on.
The mirrored vector.
deflected_velocity = ball.velocity:mirrorOn(surface_normal)
Get cross product of both vectors. Equals the area of the parallelogram spanned by both vectors.
other
Vector to compute the cross product with.
Cross product of both vectors.
parallelogram_area = a:cross(b)
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
.
Transforms a vector to a string of the form (x,y)
.
x,y
The vector
The string representation
print(vector.str(love.mouse.getPosition()))
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).
s
The scalar.
x,y
The vector.
The result of the operation.
velx,vely = vec.mul(dt, vec.add(velx,vely, accx,accy))
x,y = vec.div(self.zoom, x-w/2, y-h/2)
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.
x1,y1
First vector.
x2,y2
Second vector.
The result of the operation.
player.x,player.y = vector.add(player.x,player.y, vector.mul(dt, dx,dy))
dx,dy = vector.sub(400,300, love.mouse.getPosition())
Multiplies vectors coordinate wise, i.e. x1*x2, y1*y2)
.
x1,y1
First vector.
x2,y2
Second vector.
The result of the operation.
x,y = vector.permul(x,y, 1,1.5)
Computes the dot product of two vectors, x1*x2 + y1*y2
.
x1,y1
First vector.
x2,y2
Second vector.
The dot product.
cosphi = vector.dot(rx,ry, vx,vy)
Computes the cross product/determinant of two vectors, x1*y2 - y1*x2
.
x1,y1
First vector.
x2,y2
Second vector.
The cross product.
parallelogram_area = vector.det(ax,ay, bx,by)
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
x1,y1
First vector.
x2,y2
Second vector.
The result of the operation.
...
Get length of a vector, i.e. math.sqrt(x*x + y*y)
.
x,y
The vector.
Length of the vector.
distance = vector.len(love.mouse.getPosition())
Get squared length of a vector, i.e. x*x + y*y
.
x,y
The vector.
Squared length of the vector.
-- get closest vertex to a given vector
+end
Rotate a vector in-place. Great to use on intermediate results.
This modifies the vector. If in doubt, use {#vector:rotate()}
phi
-- ongoing rotation
+spawner.direction:rotate_inplace(dt)
Quick rotation by 90°. Creates a new vector. The same as (but faster):
vec:rotate(math.pi/2)
normal = (b - a):perpendicular():normalize_inplace()
Project vector onto another vector (see sketch).
v
velocity_component = velocity:projectOn(axis)
Mirrors vector on the axis defined by the other vector.
v
deflected_velocity = ball.velocity:mirrorOn(surface_normal)
Get cross product of both vectors. Equals the area of the parallelogram spanned by both vectors.
other
parallelogram_area = a:cross(b)
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
.
Transforms a vector to a string of the form (x,y)
.
x,y
print(vector.str(love.mouse.getPosition()))
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).
s
x,y
velx,vely = vec.mul(dt, vec.add(velx,vely, accx,accy))
x,y = vec.div(self.zoom, x-w/2, y-h/2)
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.
x1,y1
x2,y2
player.x,player.y = vector.add(player.x,player.y, vector.mul(dt, dx,dy))
dx,dy = vector.sub(400,300, love.mouse.getPosition())
Multiplies vectors coordinate wise, i.e. x1*x2, y1*y2)
.
x1,y1
x2,y2
x,y = vector.permul(x,y, 1,1.5)
Computes the dot product of two vectors, x1*x2 + y1*y2
.
x1,y1
x2,y2
cosphi = vector.dot(rx,ry, vx,vy)
Computes the cross product/determinant of two vectors, x1*y2 - y1*x2
.
x1,y1
x2,y2
parallelogram_area = vector.det(ax,ay, bx,by)
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
x1,y1
x2,y2
...
Get length of a vector, i.e. math.sqrt(x*x + y*y)
.
x,y
distance = vector.len(love.mouse.getPosition())
Get squared length of a vector, i.e. x*x + y*y
.
x,y
-- 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
Get distance of two points. The same as vector.len(x1-x2, y1-y2)
.
x1,y1
First vector.
x2,y2
Second vector.
The distance of the points.
-- get closest vertex to a given vector
+end
Get distance of two points. The same as vector.len(x1-x2, y1-y2)
.
x1,y1
x2,y2
-- 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
@@ -124,12 +124,12 @@ for i = 2,#vertices do
if temp < dist then
closest, dist = vertices[i], temp
end
-end
Get normalized vector, i.e. a vector with the same direction as the input vector, but with length 1.
x,y
The vector.
Vector with same direction as the input vector, but length 1.
dx,dy = vector.normalize(vx,vy)
Get a rotated vector.
phi
Rotation angle in radians.
x,y
The vector.
The rotated vector
-- approximate a circle
+end
Get normalized vector, i.e. a vector with the same direction as the input vector, but with length 1.
x,y
dx,dy = vector.normalize(vx,vy)
Get a rotated vector.
phi
x,y
-- 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
Quick rotation by 90°. The same as (but faster)
vector.rotate(math.pi/2, x,y)
x,y
The vector.
A vector perpendicular to the input vector
nx,ny = vector.normalize(vector.perpendicular(bx-ax, by-ay))
Project vector onto another vector.
x,y
The vector to project.
u,v
The vector to project onto.
The projected vector.
vx_p,vy_p = vector.project(vx,vy, ax,ay)
Mirrors vector on the axis defined by the other vector.
x,y
The vector to mirror.
u,v
The vector defining the axis.
The mirrored vector.
vx,vy = vector.mirror(vx,vy, surface.x,surface.y)
Class = require "hump.class"
A small, fast class implementation with multiple inheritance support
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).
constructor
Class constructor. Can be accessed with theclass.construct(object, ...)
the_name
Class name (used only to make the class compliant to tostring()
.
super
Classes to inherit from. Can either be a single class or a table of classes
The class
Class = require 'hump.class' -- `Class' is now a shortcut to new()
+end
Quick rotation by 90°. The same as (but faster)
vector.rotate(math.pi/2, x,y)
x,y
nx,ny = vector.normalize(vector.perpendicular(bx-ax, by-ay))
Project vector onto another vector.
x,y
u,v
vx_p,vy_p = vector.project(vx,vy, ax,ay)
Mirrors vector on the axis defined by the other vector.
x,y
u,v
vx,vy = vector.mirror(vx,vy, surface.x,surface.y)
Class = require "hump.class"
A small, fast class implementation with multiple inheritance support
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).
constructor
theclass.construct(object, ...)
the_name
tostring()
.super
Class = require 'hump.class' -- `Class' is now a shortcut to new()
-- define class with implicit name 'Feline'
Feline = Class{function(self, size, weight)
@@ -179,7 +179,7 @@ D = Class{inherits = {A,B}}
instance = D()
instance:foo() -- prints 'foo'
instance:bar() -- prints 'bar'
-
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.
object
The object. Usually self
.
...
Arguments to pass to the constructor
Whatever the parent class constructor returns
Class = require 'hump.class'
+
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.
object
self
....
Class = require 'hump.class'
Shape = Class{function(self, area)
self.area = area
@@ -226,7 +226,7 @@ Submenu = Class{inherits = {Menu, Entry}, function(self, title)
-- redirect self:execute() to self:display()
Entry.construct(self, title, Menu.display)
end}
-
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.
...
Parent classes to inherit from
Class = require 'hump.class'
+
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.
...
Class = require 'hump.class'
Entity = Class{function(self)
GameObjects.register(self)
@@ -254,7 +254,7 @@ Spaceship:inherit(Collidable)
function Spaceship:collision_handler["Spaceship"](other, dx, dy)
-- ...
end
-
Tests whether an object is an instance of a class.
cls
Class to test. Note: this is the class itself, not the name of the class.
true
if the object is an instance of the class, false
otherwise
Class = require 'hump.class'
+
Tests whether an object is an instance of a class.
cls
true
if the object is an instance of the class, false
otherwiseClass = require 'hump.class'
A = Class{}
B = Class{inherits=A}
@@ -269,15 +269,15 @@ 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
-
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
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.
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()
.
x,y
Point for the camera to look at.
zoom
Camera zoom.
rot
Camera rotation in radians.
A new camera object.
camera = require 'hump.camera'
+
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
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.
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()
.
x,y
zoom
rot
camera = require 'hump.camera'
-- camera looking at (100,100) with zoom 2 and rotated by 45 degrees
cam = camera(100,100, 2, math.pi/2)
-
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
.
angle
Rotation angle in radians
The camera object.
function love.update(dt)
+
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
.
angle
function love.update(dt)
camera:rotate(dt)
end
function love.update(dt)
camera:rotate(dt):move(dt,dt)
-end
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
.
dx,dy
Direction to move the camera.
The camera object.
function love.update(dt)
+end
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
.
dx,dy
function love.update(dt)
camera:move(dt * 5, dt * 6):rotate(dt)
end
Start looking through the camera.
Apply camera transformations, i.e. move, scale and rotate everything until camera:detach()
as if looking through the camera.
function love.draw()
camera:attach()
@@ -291,40 +291,40 @@ end
Wrap a function between a camera:attach()
/camera:detach()
pair:
cam:attach()func()cam:detach()
func
Drawing function to be wrapped.
function love.draw()
+end
Wrap a function between a camera:attach()
/camera:detach()
pair:
cam:attach()func()cam:detach()
func
function love.draw()
camera:draw(draw_world)
draw_hud()
-end
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.
x, y
Point to transform.
Transformed point.
x,y = camera:worldCoords(love.mouse.getPosition())
+end
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.
x, y
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())
-
Shortcut to camera:worldCoords(vector(love.mouse.getPosition()))
.
Mouse position in world coordinates.
x,y = camera:mousepos()
+
Shortcut to camera:worldCoords(vector(love.mouse.getPosition()))
.
x,y = camera:mousepos()
selectedUnit:plotPath(x,y)
-
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.
Create new ring-buffer.
The module name is a shortcut to this function.
...
Initial elements.
The ring-buffer object.
Ringbuffer = require 'hump.ringbuffer'
+
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.
Create new ring-buffer.
The module name is a shortcut to this function.
...
Ringbuffer = require 'hump.ringbuffer'
rb = ringbuffer(1,2,3)
-
Insert items behind current element.
...
Items to insert.
rb = RingbuffeR(1,5,6) -- content: 1,5,6
+
Insert items behind current element.
...
rb = RingbuffeR(1,5,6) -- content: 1,5,6
rb:insert(2,3,4) -- content: 1,2,3,4,5,6
-
Remove current item, return it and select next element.
The removed item.
rb = Ringbuffer(1,2,3,4) -- content: 1,2,3,4
+
Remove current item, return it and select next element.
rb = Ringbuffer(1,2,3,4) -- content: 1,2,3,4
val = rb:remove() -- content: 2,3,4
print(val) -- prints `1'
-
Remove the item at a position relative to the current element.
pos
Position of the item to remove.
The removed item.
rb = Ringbuffer(1,2,3,4,5) -- content: 1,2,3,4,5
+
Remove the item at a position relative to the current element.
pos
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
-
Select and return the next element.
The next item.
rb = Ringbuffer(1,2,3)
+
Select and return the next element.
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'
-
Select and return the previous item.
The previous item.
rb = Ringbuffer(1,2,3)
+
Select and return the previous item.
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'
-
Return the current element.
The currently selected element.
rb = Ringbuffer(1,2,3)
+
Return the current element.
rb = Ringbuffer(1,2,3)
rb:next() -- content: 2,3,1
print(rb:get()) -- prints '2'
-
Get number of items in the buffer
Number of items in the buffer.
rb = Ringbuffer(1,2,3)
+
Get number of items in the buffer
rb = Ringbuffer(1,2,3)
print(rb:size()) -- prints '3'
rb:remove()
print(rb:size()) -- prints '2'
diff --git a/makedoc.lua b/makedoc.lua
index dfcdb61..1e7d7f2 100644
--- a/makedoc.lua
+++ b/makedoc.lua
@@ -189,7 +189,7 @@ function Function(M)
F('Parameters:')
if #M.params == 0 then F('- None
') end
for _,p in ipairs(M.params) do
- F('- %s
%s
- %s
', p[1], p[2], markup(p[3]))
+ F('- %s
%s
- %s
', p[1], p[2], markup(p[3]):sub(4,-5))
end
F('
')
@@ -197,7 +197,7 @@ function Function(M)
F('Returns:')
if #M.returns == 0 then F('- Nothing
') end
for _,r in ipairs(M.returns) do
- F('- %s
- %s
', r[1], markup(r[2]))
+ F('- %s
- %s
', r[1], markup(r[2]):sub(4,-5))
end
F('
')