Vendor libs/hump, sfxrlua, json4lua, narrator as real files
These were committed as empty submodule gitlinks with no .gitmodules, so the folders were never populated and the game could not load (require of libs/hump/timer, libs/sfxrlua/sfxr, narrator.narrator). Checked out each at its pinned commit and vendored the files, matching the existing bundled-libs convention. Removed the junk libs/libs/ tree. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
e73f63b5d4
commit
03532d29e4
219 changed files with 20254 additions and 252 deletions
361
libs/hump/docs/gamestate.rst
Normal file
361
libs/hump/docs/gamestate.rst
Normal file
|
|
@ -0,0 +1,361 @@
|
|||
hump.gamestate
|
||||
==============
|
||||
|
||||
::
|
||||
|
||||
Gamestate = require "hump.gamestate"
|
||||
|
||||
A gamestate encapsulates independent data and behaviour in a single table.
|
||||
|
||||
A typical game could consist of a menu-state, a level-state and a game-over-state.
|
||||
|
||||
**Example**::
|
||||
|
||||
local menu = {} -- previously: Gamestate.new()
|
||||
local game = {}
|
||||
|
||||
function menu:draw()
|
||||
love.graphics.print("Press Enter to continue", 10, 10)
|
||||
end
|
||||
|
||||
function menu:keyreleased(key, code)
|
||||
if key == 'return' then
|
||||
Gamestate.switch(game)
|
||||
end
|
||||
end
|
||||
|
||||
function game:enter()
|
||||
Entities.clear()
|
||||
-- setup entities here
|
||||
end
|
||||
|
||||
function game:update(dt)
|
||||
Entities.update(dt)
|
||||
end
|
||||
|
||||
function game:draw()
|
||||
Entities.draw()
|
||||
end
|
||||
|
||||
function love.load()
|
||||
Gamestate.registerEvents()
|
||||
Gamestate.switch(menu)
|
||||
end
|
||||
|
||||
List of Functions
|
||||
-----------------
|
||||
|
||||
* :func:`Gamestate.new() <Gamestate.new>`
|
||||
* :func:`Gamestate.switch(to, ...) <Gamestate.switch>`
|
||||
* :func:`Gamestate.current() <Gamestate.current>`
|
||||
* :func:`Gamestate.push(to, ...) <Gamestate.push>`
|
||||
* :func:`Gamestate.pop(...) <Gamestate.pop>`
|
||||
* :func:`Gamestate.<callback>(...) <Gamestate.<callback>>`
|
||||
* :func:`Gamestate.registerEvents([callbacks]) <Gamestate.registerEvents>`
|
||||
|
||||
|
||||
.. _callbacks:
|
||||
|
||||
Gamestate Callbacks
|
||||
-------------------
|
||||
|
||||
A gamestate can define all callbacks that LÖVE defines. In addition, there are
|
||||
callbacks for initalizing, entering and leaving a state:
|
||||
|
||||
``init()``
|
||||
Called once, and only once, before entering the state the first time. See
|
||||
:func:`Gamestate.switch`.
|
||||
|
||||
``enter(previous, ...)``
|
||||
Called every time when entering the state. See :func:`Gamestate.switch`.
|
||||
|
||||
``leave()``
|
||||
Called when leaving a state. See :func:`Gamestate.switch` and :func:`Gamestate.pop`.
|
||||
|
||||
``resume()``
|
||||
Called when re-entering a state by :func:`Gamestate.pop`-ing another state.
|
||||
|
||||
``update()``
|
||||
Update the game state. Called every frame.
|
||||
|
||||
``draw()``
|
||||
Draw on the screen. Called every frame.
|
||||
|
||||
``focus()``
|
||||
Called if the window gets or loses 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 :func:`Gamestate.registerEvents`, all these callbacks will be called by the
|
||||
corresponding LÖVE callbacks and receive the same arguments (e.g.
|
||||
``state:update(dt)`` will be called by ``love.update(dt)``).
|
||||
|
||||
**Example**::
|
||||
|
||||
menu = {} -- previously: Gamestate.new()
|
||||
|
||||
function menu:init()
|
||||
self.background = love.graphics.newImage('bg.jpg')
|
||||
Buttons.initialize()
|
||||
end
|
||||
|
||||
function menu:enter(previous) -- runs every time the state is entered
|
||||
Buttons.setActive(Buttons.start)
|
||||
end
|
||||
|
||||
function menu:update(dt) -- runs every frame
|
||||
Buttons.update(dt)
|
||||
end
|
||||
|
||||
function menu:draw()
|
||||
love.graphics.draw(self.background, 0, 0)
|
||||
Buttons.draw()
|
||||
end
|
||||
|
||||
function menu:keyreleased(key)
|
||||
if key == 'up' then
|
||||
Buttons.selectPrevious()
|
||||
elseif key == 'down' then
|
||||
Buttons.selectNext()
|
||||
elseif
|
||||
Buttons.active:onClick()
|
||||
end
|
||||
end
|
||||
|
||||
function menu:mousereleased(x,y, mouse_btn)
|
||||
local button = Buttons.hovered(x,y)
|
||||
if button then
|
||||
Button.select(button)
|
||||
if mouse_btn == 'l' then
|
||||
button:onClick()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Function Reference
|
||||
------------------
|
||||
|
||||
.. function:: Gamestate.new()
|
||||
|
||||
:returns: An empty table.
|
||||
|
||||
|
||||
**Deprecated: Use the table constructor instead (see example)**
|
||||
|
||||
Declare a new gamestate (just an empty table). A gamestate can define several
|
||||
callbacks.
|
||||
|
||||
**Example**::
|
||||
|
||||
menu = {}
|
||||
-- deprecated method:
|
||||
menu = Gamestate.new()
|
||||
|
||||
|
||||
.. function:: Gamestate.switch(to, ...)
|
||||
|
||||
:param Gamestate to: Target gamestate.
|
||||
:param mixed ...: Additional arguments to pass to ``to:enter(current, ...)``.
|
||||
:returns: The results of ``to:enter(current, ...)``.
|
||||
|
||||
|
||||
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, and only if, the state was not yet inialized and finally call
|
||||
``enter(old_state, ...)`` on the new gamestate.
|
||||
|
||||
.. note::
|
||||
Processing of callbacks is suspended until ``update()`` is called on the new
|
||||
gamestate, but the function calling :func:`Gamestate.switch` can still continue - it is
|
||||
your job to make sure this is handled correctly. See also the examples below.
|
||||
|
||||
|
||||
**Examples**::
|
||||
|
||||
Gamestate.switch(game, level_two)
|
||||
|
||||
::
|
||||
|
||||
-- stop execution of the current state by using return
|
||||
if player.has_died then
|
||||
return Gamestate.switch(game, level_two)
|
||||
end
|
||||
|
||||
-- this will not be called when the state is switched
|
||||
player:update()
|
||||
|
||||
|
||||
|
||||
.. function:: Gamestate.current()
|
||||
|
||||
:returns: The active gamestate.
|
||||
|
||||
Returns the currently activated gamestate.
|
||||
|
||||
**Example**::
|
||||
|
||||
function love.keypressed(key)
|
||||
if Gamestate.current() ~= menu and key == 'p' then
|
||||
Gamestate.push(pause)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
.. function:: Gamestate.push(to, ...)
|
||||
|
||||
:param Gamestate to: Target gamestate.
|
||||
:param mixed ...: Additional arguments to pass to ``to:enter(current, ...)``.
|
||||
:returns: The results of ``to:enter(current, ...)``.
|
||||
|
||||
Pushes the ``to`` on top of the state stack, i.e. makes it the active state.
|
||||
Semantics are the same as ``switch(to, ...)``, except that ``leave()`` is *not*
|
||||
called on the previously active state.
|
||||
|
||||
Useful for pause screens, menus, etc.
|
||||
|
||||
.. note::
|
||||
Processing of callbacks is suspended until ``update()`` is called on the
|
||||
new gamestate, but the function calling ``GS.push()`` can still continue -
|
||||
it is your job to make sure this is handled correctly. See also the
|
||||
example below.
|
||||
|
||||
|
||||
**Example**::
|
||||
|
||||
-- pause gamestate
|
||||
Pause = Gamestate.new()
|
||||
function Pause:enter(from)
|
||||
self.from = from -- record previous state
|
||||
end
|
||||
|
||||
function Pause:draw()
|
||||
local W, H = love.graphics.getWidth(), love.graphics.getHeight()
|
||||
-- draw previous screen
|
||||
self.from:draw()
|
||||
-- overlay with pause message
|
||||
love.graphics.setColor(0,0,0, 100)
|
||||
love.graphics.rectangle('fill', 0,0, W,H)
|
||||
love.graphics.setColor(255,255,255)
|
||||
love.graphics.printf('PAUSE', 0, H/2, W, 'center')
|
||||
end
|
||||
|
||||
-- [...]
|
||||
function love.keypressed(key)
|
||||
if Gamestate.current() ~= menu and key == 'p' then
|
||||
return Gamestate.push(pause)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
.. function:: Gamestate.pop(...)
|
||||
|
||||
:returns: The results of ``new_state:resume(...)``.
|
||||
|
||||
Calls ``leave()`` on the current state and then removes it from the stack, making
|
||||
the state below the current state and calls ``resume(...)`` on the activated state.
|
||||
Does *not* call ``enter()`` on the activated state.
|
||||
|
||||
.. note::
|
||||
Processing of callbacks is suspended until ``update()`` is called on the
|
||||
new gamestate, but the function calling ``GS.pop()`` can still continue -
|
||||
it is your job to make sure this is handled correctly. See also the
|
||||
example below.
|
||||
|
||||
|
||||
**Example**::
|
||||
|
||||
-- extending the example of Gamestate.push() above
|
||||
function Pause:keypressed(key)
|
||||
if key == 'p' then
|
||||
return Gamestate.pop() -- return to previous state
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
.. function:: Gamestate.<callback>(...)
|
||||
|
||||
:param mixed ...: Arguments to pass to the corresponding function.
|
||||
:returns: The result of the callback function.
|
||||
|
||||
Calls a function on the current gamestate. Can be any function, but is intended
|
||||
to be one of the :ref:`callbacks`. Mostly useful when not using
|
||||
:func:`Gamestate.registerEvents`.
|
||||
|
||||
**Example**::
|
||||
|
||||
function love.draw()
|
||||
Gamestate.draw() -- <callback> is `draw'
|
||||
end
|
||||
|
||||
function love.update(dt)
|
||||
Gamestate.update(dt) -- pass dt to currentState:update(dt)
|
||||
end
|
||||
|
||||
function love.keypressed(key, code)
|
||||
Gamestate.keypressed(key, code) -- pass multiple arguments
|
||||
end
|
||||
|
||||
|
||||
.. function:: Gamestate.registerEvents([callbacks])
|
||||
|
||||
:param table callbacks: Names of the callbacks to register. If omitted,
|
||||
register all love callbacks (optional).
|
||||
|
||||
Overwrite love callbacks to call ``Gamestate.update()``, ``Gamestate.draw()``,
|
||||
etc. automatically. ``love`` callbacks (e.g. ``love.update()``) are still
|
||||
invoked as usual.
|
||||
|
||||
This is by done by overwriting the love callbacks, e.g.::
|
||||
|
||||
local old_update = love.update
|
||||
function love.update(dt)
|
||||
old_update(dt)
|
||||
return 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.
|
||||
|
||||
**Examples**::
|
||||
|
||||
function love.load()
|
||||
Gamestate.registerEvents()
|
||||
Gamestate.switch(menu)
|
||||
end
|
||||
|
||||
-- love callback will still be invoked
|
||||
function love.update(dt)
|
||||
Timer.update(dt)
|
||||
-- no need for Gamestate.update(dt)
|
||||
end
|
||||
|
||||
::
|
||||
|
||||
function love.load()
|
||||
-- only register draw, update and quit
|
||||
Gamestate.registerEvents{'draw', 'update', 'quit'}
|
||||
Gamestate.switch(menu)
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue