diff --git a/doc.lua b/doc.lua index bd2f07e..43a0678 100644 --- a/doc.lua +++ b/doc.lua @@ -233,7 +233,7 @@ Module { name = "hump.timer", {"function", "func", "The function to be delayed."}, }, returns = { - {"function", "The timer handle."} + {"table", "The timer handle."} }, example = { [===[ @@ -261,7 +261,7 @@ Timer.add(1, function(func) print("foo") Timer.add(1, func) end)]===], {"number", "count", "Number of times the function is to be called.", optional = true}, }, returns = { - {"function", "The timer handle."} + {"table", "The timer handle."} }, example = { "Timer.addPeriodic(1, function() lamp:toggleLight() end)", @@ -274,6 +274,39 @@ end)]===], }, }, + Function { name = {"do_for", "instance:do_for"}, + short = "Run a function for the next few seconds.", + long = [===[ + Run a {#func(dt)} for the next {#delta} seconds. The function is called + every time {#update(dt)} is called. Optionally run {#after()} once + {#delta} seconds have passed. + + {#after} will receive itself as only parameter. + + The same constraints as with {#add()} apply.]===], + params = { + {"number", "delta", "Number of seconds the {#func} will be called."}, + {"function", "func", "The function to be called upon {#update(dt)}."}, + {"function", "after", "A function to be called after {#delta} seconds.", optional=true}, + }, + returns = { + {"table", "The timer handle."} + }, + example = { + [===[Timer.do_for(3, function() screen:shake() end)]===], + [===[player.isInvincible = true +-- flash player for 3 seconds +local t = 0 +player.timer:do_for(3, function(dt) + t = t + dt + player.visible = (t % .2) < .1 +end, function() + player.visible = true -- make sure the player is visible after three seconds + player.isInvincible = false +end)]===] + }, + }, + Function { name = {"cancel", "instance:cancel"}, short = "Cancel a scheduled function.", long = [===[ @@ -284,7 +317,7 @@ end)]===], {*Never} use this inside a scheduled function.]===], params = { - {"function", "func", "The function to be canceled."}, + {"table", "handle", "The function to be canceled."}, }, returns = {}, example = { @@ -320,75 +353,6 @@ Timer.cancel(handle) -- NOT: Timer.cancel(tick)]===] function love.update(dt) do_stuff() Timer.update(dt) -end]===], - }, - - Function { name = "Interpolator", - short = "Create a new interpolating function.", - long = [===[ - 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.]===], - params = { - {"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 { name = "Oscillator", - short = "Create a new oscillating function.", - long = [===[ - 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.]===], - params = { - {"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) - -local xpos = 100 -function love.update(dt) - xpos = mover(dt) -end - -function love.draw() - love.graphics.circle('fill', xpos, 300, 80, 36) end]===], }, } diff --git a/index.html b/index.html index 8a1425b..b168a50 100644 --- a/index.html +++ b/index.html @@ -56,14 +56,23 @@ end

Note: Only works when called end

function love.load()
     Gamestate.registerEvents{'draw', 'update', 'quit'}
     Gamestate.switch(menu)
-end

hump.timer^ top

Timer = require "hump.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

new()
Create new timer instance.
add()
Schedule a function.
addPeriodic()
Add a periodic function.
cancel()
Cancel a scheduled function.
clear()
Remove all timed and periodic functions.
update()
Update scheduled functions.
Interpolator()
Create a new interpolating function.
Oscillator()
Create a new oscillating function.

function new()^ top

If you don't need multiple independent schedulers, you can use the global/default timer (see examples).

Creates a new timer instance that is independent of the global timer: It will manage it's own list of scheduled functions and does not in any way affect the the global timer. Likewise, the global timer does not affect the timer instance.

Note: Timer instances use the colon-notation (e.g. instance:update(dt)), while the global timer uses the dot-notation (e.g. Timer.update(dt)).

Parameters:
None
Returns:
Timer
A timer instance
Example:
menuTimer = Timer.new()

function add(delay, func)^ top

function instance:add(delay, func)^ top

Schedule a function. The function will be executed after delay seconds have elapsed, given that update(dt) 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
+end

hump.timer^ top

Timer = require "hump.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

new()
Create new timer instance.
add()
Schedule a function.
addPeriodic()
Add a periodic function.
do_for()
Run a function for the next few seconds.
cancel()
Cancel a scheduled function.
clear()
Remove all timed and periodic functions.
update()
Update scheduled functions.

function new()^ top

If you don't need multiple independent schedulers, you can use the global/default timer (see examples).

Creates a new timer instance that is independent of the global timer: It will manage it's own list of scheduled functions and does not in any way affect the the global timer. Likewise, the global timer does not affect the timer instance.

Note: Timer instances use the colon-notation (e.g. instance:update(dt)), while the global timer uses the dot-notation (e.g. Timer.update(dt)).

Parameters:
None
Returns:
Timer
A timer instance
Example:
menuTimer = Timer.new()

function add(delay, func)^ top

function instance:add(delay, func)^ top

Schedule a function. The function will be executed after delay seconds have elapsed, given that update(dt) 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:
table
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)
menuTimer:add(1, finishAnimation)

function addPeriodic(delay, func, count)^ top

function instance: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.
Example:
Timer.addPeriodic(1, function() lamp:toggleLight() end)
mothership_timer:addPeriodic(0.3, function() self: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)
menuTimer:add(1, finishAnimation)

function addPeriodic(delay, func, count)^ top

function instance: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:
table
The timer handle.
Example:
Timer.addPeriodic(1, function() lamp:toggleLight() end)
mothership_timer:addPeriodic(0.3, function() self: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

function instance: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 inside a scheduled function.

Parameters:
function func
The function to be canceled.
Returns:
Nothing
Example:
function tick()
+end)

function do_for(delta, func, after)^ top

function instance:do_for(delta, func, after)^ top

Run a func(dt) for the next delta seconds. The function is called every time update(dt) is called. Optionally run after() once delta seconds have passed.

after will receive itself as only parameter.

The same constraints as with add() apply.

Parameters:
number delta
Number of seconds the func will be called.
function func
The function to be called upon update(dt).
function after (optional)
A function to be called after delta seconds.
Returns:
table
The timer handle.
Example:
Timer.do_for(3, function() screen:shake() end)
player.isInvincible = true
+-- flash player for 3 seconds
+local t = 0
+player.timer:do_for(3, function(dt)
+	t = t + dt
+	player.visible = (t % .2) < .1
+end, function()
+	player.visible = true -- make sure the player is visible after three seconds
+	player.isInvincible = false
+end)

function cancel(handle)^ top

function instance:cancel(handle)^ 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 inside a scheduled function.

Parameters:
table handle
The function to be canceled.
Returns:
Nothing
Example:
function tick()
     print('tick... tock...')
 end
 handle = Timer.addPeriodic(1, tick)
@@ -71,23 +80,6 @@ handle = Timer.addPeriodic(1, tick)
 Timer.cancel(handle) -- NOT: Timer.cancel(tick)

function clear()^ top

function instance:clear()^ top

Remove all timed and periodic functions. Functions that have not yet been executed will discarded. Never use this inside a scheduled function.

Parameters:
None
Returns:
Nothing
Example:
Timer.clear()

function update(dt)^ top

function instance: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)
-    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)
-   return 400 + 300 * math.sin(2*math.pi*frac)
-end)
-
-local xpos = 100
-function love.update(dt)
-    xpos = mover(dt)
-end
-
-function love.draw()
-    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
Dot product.
number * vector = vector
Scalar multiplication (scaling).
vector * number = vector
Scalar multiplication.
vector / number = vector
Scalar multiplication.

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