Project Name | Stars | Downloads | Repos Using This | Packages Using This | Most Recent Commit | Total Releases | Latest Release | Open Issues | License | Language |
---|---|---|---|---|---|---|---|---|---|---|
Picolove | 621 | 4 months ago | 17 | zlib | Lua | |||||
PICO-8 Reimplementation in Love2D. Chat: https://discord.gg/jGEMUse6RM | ||||||||||
Picolove | 84 | 5 years ago | n,ull | zlib | Lua | |||||
Pico-8 Reimplementation in Love2D | ||||||||||
Neko8 | 69 | 5 years ago | 3 | C++ | ||||||
Fantasy console inspired by pico8, tic80 and liko12, written in c++ | ||||||||||
Vector Paint | 5 | 3 years ago | mit | Lua | ||||||
A vector drawing program in LÖVE to produce art for PICO-8 carts | ||||||||||
Leaf | 4 | a year ago | n,ull | mit | Lua | |||||
leaf (Love's Extensions And Facilities) is collection of libraries and classes for LÖVE. | ||||||||||
Selection Sort Visualization | 2 | 5 years ago | Lua | |||||||
A visualization of the selection sort algorithm using love2d and the pico-8 color palette. |
leaf (Love's Extensions And Facilities) is collection of libraries and classes for LVE. The structure of code and functions' names are entirely based on Pyxel.
leaf is open source and free to use.
Shorter functions' names
On Key Pressed Once function
Screen configurator
Object Platform and Multiple-State Machine Enemy classes
Physical and graphical tilemap composer
2D colision system
Sprite Animator class
Save-Load build-in system
NES-Like resources system
Simple debug function
New Table and strings functions
leaf is a lua module that can be loaded using require
.
require 'leaf'
leaf.skip('resources')
leaf.init({w = 480, h = 480, s = 3})
local x, y = 0, 0
function leaf.step(dt)
if leaf.btn('a') then x = x - 1
elseif leaf.btn('d') then x = x + 1 end
if leaf.btn('w') then y = y - 1
elseif leaf.btn('s') then y = y + 1 end
end
function leaf.draw()
leaf.rectb(x, y, 4)
end
Do not use love.load | update | draw, it would override the Leaf's functions. Instead, use leaf.load | step | draw.
-leaf.init(conf)
Sets the screen size (conf.w
x conf.h
), the drawing scale (conf.s
), if the screen is resizeable (conf.rz
), the min screen size (conf.mw
x conf.mh
) and if vsync is enabled (conf.vs
). Also the drawmode (conf.dm
) See Graphics for better understanding. Default values:
conf = {
w = 512, h = 512, s = 4,
mv = true, rz = true,
vs = true,
dm = "default"
}
leaf.load
Works like love.load
.
leaf.step
Works like love.update
.
leaf.late
Called after leaf.step
.
leaf.draw
Works like love.draw
.
leaf.fps
The current fps.
leaf.s_wdth
The current game screen width (real size / scale).
leaf.s_hght
The current game screen Height (real size / scale).
leaf.table_first(lst)
Returns idx, itm
of the first item in lst
.
leaf.table_last(lst)
Returns idx, itm
of the last item in lst
.
leaf.table_find(lst, itm)
Returns the index of the itm
if it is in lst
, otherwise returns nil
.
leaf.table_eq(lst, otr)
Returns true
if lst
has the same items in the same indexes of otr
, otherwise returns false
.
leaf.table_copy(lst)
Returns an copy of lst
.
All these functions works with string objects
string.split(str, pat)
Returns a table of substrings splited by pat
from str
, returns str
if doesn't find pat
.
string.startswith(str, sub)
Returns true
if str
starts with sub
, otherwise returns false
.
string.endswith(str, sub)
Returns true
if str
ends with sub
, otherwise returns false
.
leaf.tobool(val)
true
if is "true"
, not 0
or not nil
.Simple print all function.
leaf.log(tag, [...])
tag
followed by all subsequent values (...
). e.g.leaf.log('debug', true, 4, 6 - 9)
>>> [debug][true, 4, -3]
leaf.drawmode = "default"
: draws game sprites and shapes normally.leaf.drawmode = "pixper"
: rounds the values before drawing, keeping all shapes on-grid.leaf.popup(usr, msg)
Creates a pop-up window to usr
with msg
as content. (Avaliable only on Windows and Linux).
leaf.color([r, g, b, [a]])
Same of love.graphics.setColor()
, but it uses 0 to 255 scale, and a
is optional. If empty, resset the color to default.
leaf.rect(x, y, [w], [h])
Draws an w
x h
rectangle (line draw method) at {x
, y
}. If w
is nil
, w
and h
will be 1
, if only h
is nil
, h
will be w
.
leaf.rectb(x, y, [w], [h])
Draws an w
x h
rectangle (fill draw method) at {x
, y
}. If w
is nil
, w
and h
will be 1
, if only h
is nil
, h
will be w
.
ESC key
Quits the application.
leaf.btn(key)
Returns true
if key
is pressed, otherwise returns false
.
leaf.btnp(key)
Returns true
if key
was pressed at that frame, otherwise returns false
.
leaf.btnr(key)
Returns true
if key
was released at that frame, otherwise returns false
.
leaf.txt_conf(font, size, speed)
Sets the default font as font
, with size size
and the class will type 1 letter per speed
(seconds).
leaf.new_txt(tmsg, ypos, [effect], [trigger, tgrTime])
Adds a new text object, that will be drawed at height ypos
and alligned at center acording to the size (better with monospaced fonts). If trigger
is definided (a table
with the letter positions) the text will wait 1/tgrTime
seconds before continue. If this text object already exists, nothing happens.
effect = 'noises'
: will draw some red and blue shadows behind the text.effect = 'glitch'
: will render random red and blue glitches and change the showing text once in a whileeffect = 'wobbly'
: will draw the letters in a waveform, wobbling over the timeeffect = 'shaking'
: will shake the letters separately and randomlyleaf.type_txt(dt, [sound])
Updates all text objects, playing the tape sound
if given (See Gramophone).
leaf.txt_exist(idxr)
Returns true
if an text object has idxr
as content.
leaf.txt_end(idxr)
Returns true
if the text object that has idxr
as content has ended.
leaf.del_txt(idxr)
Removes the text object that has idxr
as content.
leaf.pop_text()
Removes all text objects that has ended.
leaf.vector([x[, y[, s]]])
Returns a new 2D vector at {x
, y
} with optional scale (s
). If empty, returns a {0
, 0
} vector.
vector:sum([x[, y]])
Sums x
(or 0
) and y
(or 0
) to the vector. Returns itself.
vector:sub([x[, y]])
Subtracts x
(or 0
) and y
(or 0
) from the vector. Returns itself.
vector:mul([x[, y]])
Multiplies vector.x
by x
(or 1
) and vector.y
by y
(or 1
). Returns itself.
vector:mul([x[, y]])
Divides vector.x
by x
(or 1
) and vector.y
by y
(or 1
). Returns itself.
leaf.vect4D([lt[, rt[, up[, dn]]]])
Returns a 4dir vector with values left (lt
), right (rt
), up (up
) and down (dn
). If empty, returns all values as 0
.
leaf.add_plat(type, pos, wdt, hgt, name)
Adds a new platform of the type type
('solid'
or 'jthru'
) of size wdt
x hgt
at pos
(vector
), identified by name
.
leaf.coll(pos, coll, [down])
Updates coll
(vect4D
) with all solid walls near pos
. Ignore the floor (coll.dn
) if the platform is jthru
and down
is true
.
leaf.del_plat(name)
deletes the name
platform.
leaf.draw_plat()
Draws all platforms.
leaf.add_itm(name, ipos, sprt, [wall])
Adds a collectable item at ipos
, rendered with sprt
(vector
). Will be a solid tile if wall
is true
.
leaf.catch(coll)
Destroys overlapped items by call
(vector
) and returns item name if was caught.
leaf.tilemap(back, main, info, [obj])
Sets the tile map of the game.
back
metatable with the layers at the background (not solid).
main
table with the tiles of the main layer (solid).
info
table with the definition of the tiles.
obj
optional arg. table with the definitions of enemies that will be spawned at every correponding tile.
leaf.add_tile(name, spos, sprt, wall)
Adds an tile with the indexer name
at spos
(vector
) rendered with sprt
(vector
). If wall
is true, the tile will be solid.
leaf.del_tile(name)
Deletes the name
tile.
First you have to create a classtype for the tiles.
function char_to_tile(char, _x, _y)
local sx = char % 16
local sy = (char - sx) / 16
return {
p = leaf.vector(_y, _x, 8), -- the tile itself position
s = leaf.vector(sx, sy, 8), -- the sprite position at tilemap.png
c = char -- the byte that represents its sprite
}
end
The byte value is the sprite position converted into a single numeric value (0-255). You can do it using this formula: byte = y * 16 + x
.
Then you'll need to specify what each tile is:
local info = {
skipt = {[255] = true}, jthru = {[34] = true}, -- 255 is skiped because it's the empty tile | 34 is the platform tile (jump thru)
index = {spawn = 254} -- this value tells to the tilemapper to return the position of the last occurrence of 254
}
After this you can create a table containing all your tiles in your tilemap.
local map = {
char_to_tile(255, 0, 0), char_to_tile(055, 1, 0), char_to_tile(255, 2, 0),
char_to_tile(255, 0, 1), char_to_tile(034, 1, 1), char_to_tile(255, 2, 1),
char_to_tile(233, 0, 2), char_to_tile(013, 1, 2), char_to_tile(112, 2, 2),
}
Also, you can specify an item that can be caught.
local item = {
wall = false, -- the item isn't solid
tile = {45, 61}, -- both 45 and 61 are items
name = {[45] = 'star_', [61] = 'coin_'}, -- to you be able of accessing it later, name the items with a prefix
}
Finally, if you want, you can instantiate enemies to prow in a certain area (between every two chars).
local enemy = { -- the arg must be a table of every enemy, in this case just one
[66] = { -- the char that represents the bounds of the enemy habbitation
name = 'pm-ghost', -- name given to leaf.create()
clip = {
-- same source name to --
-- change only sprites --
-- and not the current --
-- frame --
idle = leaf.asrc('idle', 2, 0, 04),
angry = leaf.asrc('idle', 2, 5, 10),
}
}
}
```
Then just give everything to the tilemapper:
leaf.tilemap(map, _, info, item, enemy)
It's highly recomended that you use the Ethereal tilemap editor instead of tiling by hand. In this case, do something like this:
local main, back = leaf.decoder('map.txt')
leaf.tilemap(main, back, info, item, enemy)
leaf.create(otype, ...)
Returns a platform object of the otype
.
platform:step(dt, [cpos])
Updates platform
object (moviment, collision, animaiton). If platform
is an pm-ghost
, the object will haunt the cpos
position (vector
).
platform:draw()
Draws platform
object. If object has no animator, a rectangle will be drawn instead.
platform:get_pos([scale])
Returns a vector
with the current position of platform
. The s
parameter will be used as scale, if given.
platform:set_pos(npos)
Sets the platform
position to npos
(vector
).
platform:get_stt()
Returns the current animation state of platform
(idle
or moving
).
platform:get_yac()
Returns current Y
axis acceleration.
platform:can_jmp()
Returns count of remained jumps of object or if it can jump (boolean).
platform:jumped()
Returns true
if platform
has jumped at that frame.
platform:on_wall()
Returns true
if the platform
is leaning against a horizontal wall.
platform:landed()
Returns true
if the platform
is landed.
platform:onland()
Returns true
when platform
lands.
platform:get_mrr()
Returns the mirror state of platform
. -1
if sprite is flipped, 1
if it's not.
(ipos, ctrl, [def])
Returns a playable object, instantiated at ipos
, using ctrl
as key definition. def
is used do give an animator object and physics parameters. e.g.
local ctrl = {
lft = 'left' , -- move to left
rgt = 'right', -- move to right
dwn = 'down' , -- climb down
int = 'up', -- interact
ups = 'x' , -- jump
atk = 'c' , -- atack
}
local def = {
speed = 1.5, -- moviment speed
anim = leaf.anim(), -- animator object
clip = {
jump = leaf.asrc('def-jump', 0, 6), -- jumping animation clip
fall = leaf.asrc('def-fall', 0, 7), -- falling animation clip
idle = leaf.asrc('def-idle', 0, 0, 4), -- idle animation clip
walk = leaf.asrc('stp-walk', 0, 4, 0, 5), -- walking animation clip
size = 8, -- object size (value x value)
mass = 8, -- the object weight
jump_count = 2, -- Count of jumps
jump_strength = -200, -- Jump strength
coytote_time = 4, -- how may frames after falling off from a platform are still able to jump
}
}
local char = leaf.create('platform', leaf.vector(0, 0), ctrl, def)
If ctrl
be a table of booleans, you can control indirectly the object, e.g.
local ctrl = {
lft = false,
rgt = false,
ups = false,
dwn = false,
}
local char = leaf.create('platform', leaf.vector(0, 0), ctrl, def)
function leaf.step(dt)
-- updating this table updates the character's one --
-- when true, char moves, when false, char stops --
ctrl.lft = leaf.btn('left')
ctrl.rgt = leaf.btn('right')
ctrl.ups = leaf.btn('up')
char:step(dt)
end
(min, max, pos, [clip])
Platform Packman-like enemy. Runs the area from min
to max
, but is instantiated at pos
. If defined, the clip
will be used as an animator object, containing the idle and angry animation clips. e.g.
clip = {
-- Same name to change only sprites --
idle = leaf.asrc('idle', 2, 0, 4),
angry = leaf.asrc('idle', 2, 5, 9),
}
ghost = leaf.create('pm-ghost', 0, 32, leaf.vector(0, 0), clip)
Leaf uses two png files ("tilemap.png" to the tilemap class and "sprites.png" to animator objects) in resources/
as graphic sources and all files in tracks/
as audio souces. The graphic files will be automaticly loaded, except if you use leaf.skip('resources')
.
Animation class, responsible for controlling and animating sprites.
leaf.anim([frame])
Returns an animator object. If frame
(vector
) is specified, the animator will be initialized in this frame.
leaf.asrc(name, ...)
Returns an animation source, taged with name
, that can hold a prefix that specify the animation type.
('def-name', rw, fx, lx, [opt])
Default type, the same without a prefix. Returns a sprite sheet animation source, in the rw
row, from thefx
to lx
columns. If opt
({spr, cnt}
) is specified, optional frames (spr
) will be appended at the end of the animation cnt
times.
('stp-name', rw, fx, mx, lx)
Stepped type. Returns a sprite sheet animation source, interleaved animation of fx and lx separated by mx ({fx, mx, lx, mx}
).
anim:play(dt, anim, speed, loop)
Causes object anim
to play animationanim
at speed speed
(frames per second). If loop
is specified, the animation will be looping.
anim:loop()
Causes object anim
to loop the current animation.
anim:draw(pos, side)
Draws the current animation of anim
at pos
(vector
). If side
is smaller than 0, the sprite will be flipped, if it's greater, will not.
leaf.playlist(main, back, ...)
Sets the playlist of audio souce. main
(tracks/<main>
) is the main music layer, back
is the background environment. ...
is all other play-once sounds of the game (sfx), like soundsteps, hits, etc. * Max 8 tracks (0 to 7).
leaf.gramo.theme()
Starts playing the main and background musics.
leaf.gramo.set(thm, stt)
Sets playing status of thm
('main'
or 'back'
) to stt
(boolean).
leaf.gramo.play(tape, track, loop)
Plays tape
(indexed in leaf.playlist
) at sound layer track
. If loop
is true, tape
will play in looping. The volume will be set to track / 7
.
leaf.gramo.pause(track)
Pauses track
if it exists.
leaf.gramo.resume(track)
Resumes track
if it exists.
leaf.gramo.fade_in(track, speed)
Increases the volume of track
from 0 to 1 in speed
(percent per second).
leaf.gramo.fadeout(track, speed)
Decreases the volume of track
from 1 to 0 in speed
(percent per second).
leaf.save_data(file, data, [method, msg])
Saves a file named file
containing the data of data
(string, number or table) in the standard LVE directory, using an optional method.
method = nil
Standart method. Save all data inside a .lua file.
method = 'safe'
Magic method. Saves the file as file
and store the data in a slightly difficult way to change it. It usually causes errors of nullity if done (not sure why). It also adds msg
as a message at the top of the file.
leaf.load_data(file, method)
Returns the content of file
. If an method was used to save the file, it must be specified with method
.