mirror of
https://github.com/Reuh/ubiquitousse.git
synced 2025-10-27 09:09:30 +00:00
Add LDtk, update docs
This commit is contained in:
parent
c793617ded
commit
582f592a79
13 changed files with 2733 additions and 39 deletions
|
|
@ -1,8 +1,8 @@
|
|||
# ubiquitousse
|
||||
|
||||
Set of various libraries I use for game development, mainly with LÖVE. Nothing that hasn't been done before, but these are tailored to what I need.
|
||||
Set of various libraries I use for game development, mainly with LÖVE. Nothing that hasn't been done before, but these are tailored to what I need. They can be used independently too.
|
||||
|
||||
Documentation is done in LDoc-like comments in source files, but LDoc doesn't really like how I structure my libraries so you can't really generate documentation with it.
|
||||
Documentation is done in LDoc-like comments in source files, but LDoc doesn't really like how I structure my libraries so you can't really generate documentation with it. I'm currently trying to fix this; some modules already have a working LDoc documentation in `doc/`.
|
||||
|
||||
Whatever is currently on the master branch should be working and usable. Changelog, including breaking changes, are documented in commit messages.
|
||||
|
||||
|
|
|
|||
20
config.ld
20
config.ld
|
|
@ -1,12 +1,18 @@
|
|||
project = "Ubiquitousse"
|
||||
description = "Ubiquitousse Game Engine"
|
||||
full_description = "A simple Lua game framework, made to run everywhere. See the Ubiquitousse module for more information."
|
||||
title = "Ubiquitousse reference"
|
||||
description = "Ubiquitousse game development tools"
|
||||
full_description = [[Set of Lua libraries to make game development easier using the [LÖVE](https://love2d.org/) game framework.
|
||||
|
||||
title = "Ubiquitousse Reference"
|
||||
package = "ubiquitousse"
|
||||
See [main module](modules/init.html) for more information, or the [GitHub page](https://github.com/Reuh/ubiquitousse) for the source.
|
||||
]]
|
||||
--package = "ubiquitousse"
|
||||
|
||||
file = "./"
|
||||
format = "markdown"
|
||||
format = "discount"
|
||||
style = "!fixed"
|
||||
|
||||
no_summary = true
|
||||
not_luadoc = true
|
||||
|
||||
custom_tags = { { "require", title="Requires" } }
|
||||
|
||||
topics = { "README.md", "LICENSE" }
|
||||
file = { "init.lua", "ldtk/ldtk.can" }
|
||||
|
|
|
|||
85
doc/index.html
Normal file
85
doc/index.html
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<head>
|
||||
<title>Ubiquitousse reference</title>
|
||||
<link rel="stylesheet" href="ldoc_fixed.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="container">
|
||||
|
||||
<div id="product">
|
||||
<div id="product_logo"></div>
|
||||
<div id="product_name"><big><b></b></big></div>
|
||||
<div id="product_description"></div>
|
||||
</div> <!-- id="product" -->
|
||||
|
||||
|
||||
<div id="main">
|
||||
|
||||
|
||||
<!-- Menu -->
|
||||
|
||||
<div id="navigation">
|
||||
<br/>
|
||||
<h1>Ubiquitousse</h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h2>Modules</h2>
|
||||
<ul class="nowrap">
|
||||
<li><a href="modules/init.html">init</a></li>
|
||||
<li><a href="modules/ldtk.html">ldtk</a></li>
|
||||
</ul>
|
||||
<h2>Topics</h2>
|
||||
<ul class="">
|
||||
<li><a href="topics/README.md.html">README</a></li>
|
||||
<li><a href="topics/LICENSE.html">LICENSE</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
|
||||
|
||||
<h2>Ubiquitousse game development tools</h2>
|
||||
<p>Set of Lua libraries to make game development easier using the <a href="https://love2d.org/">LÖVE</a> game framework.</p>
|
||||
|
||||
<p>See <a href="modules/init.html">main module</a> for more information, or the <a href="https://github.com/Reuh/ubiquitousse">GitHub page</a> for the source.</p>
|
||||
|
||||
<h2>Modules</h2>
|
||||
<table class="module_list">
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="modules/init.html">init</a></td>
|
||||
<td class="summary">Ubiquitousse main module.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="modules/ldtk.html">ldtk</a></td>
|
||||
<td class="summary"><a href="https://ldtk.io/">LDtk</a> level importer for LÖVE.</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2>Topics</h2>
|
||||
<table class="module_list">
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="topics/README.md.html">README.md</a></td>
|
||||
<td class="summary"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="topics/LICENSE.html">LICENSE</a></td>
|
||||
<td class="summary"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div> <!-- id="content" -->
|
||||
</div> <!-- id="main" -->
|
||||
<div id="about">
|
||||
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
|
||||
<i style="float:right;">Last updated 2021-12-24 23:49:41 </i>
|
||||
</div> <!-- id="about" -->
|
||||
</div> <!-- id="container" -->
|
||||
</body>
|
||||
</html>
|
||||
311
doc/ldoc_fixed.css
Normal file
311
doc/ldoc_fixed.css
Normal file
|
|
@ -0,0 +1,311 @@
|
|||
/* BEGIN RESET
|
||||
|
||||
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.com/yui/license.html
|
||||
version: 2.8.2r1
|
||||
*/
|
||||
html {
|
||||
color: #000;
|
||||
background: #FFF;
|
||||
}
|
||||
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
fieldset,img {
|
||||
border: 0;
|
||||
}
|
||||
address,caption,cite,code,dfn,em,strong,th,var,optgroup {
|
||||
font-style: inherit;
|
||||
font-weight: inherit;
|
||||
}
|
||||
del,ins {
|
||||
text-decoration: none;
|
||||
}
|
||||
li {
|
||||
margin-left: 20px;
|
||||
}
|
||||
caption,th {
|
||||
text-align: left;
|
||||
}
|
||||
h1,h2,h3,h4,h5,h6 {
|
||||
font-size: 100%;
|
||||
font-weight: bold;
|
||||
}
|
||||
q:before,q:after {
|
||||
content: '';
|
||||
}
|
||||
abbr,acronym {
|
||||
border: 0;
|
||||
font-variant: normal;
|
||||
}
|
||||
sup {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
sub {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
legend {
|
||||
color: #000;
|
||||
}
|
||||
input,button,textarea,select,optgroup,option {
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
font-style: inherit;
|
||||
font-weight: inherit;
|
||||
}
|
||||
input,button,textarea,select {*font-size:100%;
|
||||
}
|
||||
/* END RESET */
|
||||
|
||||
body {
|
||||
margin-left: 1em;
|
||||
margin-right: 1em;
|
||||
font-family: arial, helvetica, geneva, sans-serif;
|
||||
background-color: #ffffff; margin: 0px;
|
||||
}
|
||||
|
||||
code, tt { font-family: monospace; font-size: 1.1em; }
|
||||
span.parameter { font-family:monospace; }
|
||||
span.parameter:after { content:":"; }
|
||||
span.types:before { content:"("; }
|
||||
span.types:after { content:")"; }
|
||||
.type { font-weight: bold; font-style:italic }
|
||||
|
||||
body, p, td, th { font-size: .95em; line-height: 1.2em;}
|
||||
|
||||
p, ul { margin: 10px 0 0 0px;}
|
||||
|
||||
strong { font-weight: bold;}
|
||||
|
||||
em { font-style: italic;}
|
||||
|
||||
h1 {
|
||||
font-size: 1.5em;
|
||||
margin: 0 0 20px 0;
|
||||
}
|
||||
h2, h3, h4 { margin: 15px 0 10px 0; }
|
||||
h2 { font-size: 1.25em; }
|
||||
h3 { font-size: 1.15em; }
|
||||
h4 { font-size: 1.06em; }
|
||||
|
||||
a:link { font-weight: bold; color: #004080; text-decoration: none; }
|
||||
a:visited { font-weight: bold; color: #006699; text-decoration: none; }
|
||||
a:link:hover { text-decoration: underline; }
|
||||
|
||||
hr {
|
||||
color:#cccccc;
|
||||
background: #00007f;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
blockquote { margin-left: 3em; }
|
||||
|
||||
ul { list-style-type: disc; }
|
||||
|
||||
p.name {
|
||||
font-family: "Andale Mono", monospace;
|
||||
padding-top: 1em;
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: rgb(245, 245, 245);
|
||||
border: 1px solid #C0C0C0; /* silver */
|
||||
padding: 10px;
|
||||
margin: 10px 0 10px 0;
|
||||
overflow: auto;
|
||||
font-family: "Andale Mono", monospace;
|
||||
}
|
||||
|
||||
pre.example {
|
||||
font-size: .85em;
|
||||
}
|
||||
|
||||
table.index { border: 1px #00007f; }
|
||||
table.index td { text-align: left; vertical-align: top; }
|
||||
|
||||
#container {
|
||||
margin-left: 1em;
|
||||
margin-right: 1em;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
#product {
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #cccccc;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
#product big {
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
#main {
|
||||
background-color:#FFFFFF; // #f0f0f0;
|
||||
border-left: 1px solid #cccccc;
|
||||
}
|
||||
|
||||
#navigation {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
float: left;
|
||||
width: 14em;
|
||||
vertical-align: top;
|
||||
background-color:#FFFFFF; // #f0f0f0;
|
||||
border-right: 2px solid #cccccc;
|
||||
overflow: visible;
|
||||
overflow-y: scroll;
|
||||
height: 100%;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
#navigation h2 {
|
||||
background-color:#FFFFFF;//:#e7e7e7;
|
||||
font-size:1.1em;
|
||||
color:#000000;
|
||||
text-align: left;
|
||||
padding:0.2em;
|
||||
border-bottom:1px solid #dddddd;
|
||||
}
|
||||
|
||||
#navigation ul
|
||||
{
|
||||
font-size:1em;
|
||||
list-style-type: none;
|
||||
margin: 1px 1px 10px 1px;
|
||||
}
|
||||
|
||||
#navigation li {
|
||||
text-indent: -1em;
|
||||
display: block;
|
||||
margin: 3px 0px 0px 22px;
|
||||
}
|
||||
|
||||
#navigation li li a {
|
||||
margin: 0px 3px 0px -1em;
|
||||
}
|
||||
|
||||
#content {
|
||||
margin-left: 14em;
|
||||
padding: 1em;
|
||||
padding-left: 2em;
|
||||
width: 700px;
|
||||
border-left: 2px solid #cccccc;
|
||||
// border-right: 2px solid #cccccc;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
#about {
|
||||
clear: both;
|
||||
padding-left: 1em;
|
||||
margin-left: 14em; // avoid the damn sidebar!
|
||||
border-top: 2px solid #cccccc;
|
||||
border-left: 2px solid #cccccc;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
@media print {
|
||||
body {
|
||||
font: 12pt "Times New Roman", "TimeNR", Times, serif;
|
||||
}
|
||||
a { font-weight: bold; color: #004080; text-decoration: underline; }
|
||||
|
||||
#main {
|
||||
background-color: #ffffff;
|
||||
border-left: 0px;
|
||||
}
|
||||
|
||||
#container {
|
||||
margin-left: 2%;
|
||||
margin-right: 2%;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
#content {
|
||||
padding: 1em;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
#navigation {
|
||||
display: none;
|
||||
}
|
||||
pre.example {
|
||||
font-family: "Andale Mono", monospace;
|
||||
font-size: 10pt;
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
}
|
||||
|
||||
table.module_list {
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: #cccccc;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
table.module_list td {
|
||||
border-width: 1px;
|
||||
padding: 3px;
|
||||
border-style: solid;
|
||||
border-color: #cccccc;
|
||||
}
|
||||
table.module_list td.name { background-color: #f0f0f0; ; min-width: 200px; }
|
||||
table.module_list td.summary { width: 100%; }
|
||||
|
||||
table.function_list {
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: #cccccc;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
table.function_list td {
|
||||
border-width: 1px;
|
||||
padding: 3px;
|
||||
border-style: solid;
|
||||
border-color: #cccccc;
|
||||
}
|
||||
table.function_list td.name { background-color: #f6f6ff; ; min-width: 200px; }
|
||||
table.function_list td.summary { width: 100%; }
|
||||
|
||||
dl.table dt, dl.function dt {border-top: 1px solid #ccc; padding-top: 1em;}
|
||||
dl.table dd, dl.function dd {padding-bottom: 1em; margin: 10px 0 0 20px;}
|
||||
dl.table h3, dl.function h3 {font-size: .95em;}
|
||||
|
||||
ul.nowrap {
|
||||
overflow:auto;
|
||||
whitespace:nowrap;
|
||||
}
|
||||
|
||||
/* stop sublists from having initial vertical space */
|
||||
ul ul { margin-top: 0px; }
|
||||
ol ul { margin-top: 0px; }
|
||||
ol ol { margin-top: 0px; }
|
||||
ul ol { margin-top: 0px; }
|
||||
|
||||
/* make the target distinct; helps when we're navigating to a function */
|
||||
a:target + * {
|
||||
background-color: #FF9;
|
||||
}
|
||||
|
||||
|
||||
/* styles for prettification of source */
|
||||
pre .comment { color: #558817; }
|
||||
pre .constant { color: #a8660d; }
|
||||
pre .escape { color: #844631; }
|
||||
pre .keyword { color: #aa5050; font-weight: bold; }
|
||||
pre .library { color: #0e7c6b; }
|
||||
pre .marker { color: #512b1e; background: #fedc56; font-weight: bold; }
|
||||
pre .string { color: #8080ff; }
|
||||
pre .number { color: #f8660d; }
|
||||
pre .operator { color: #2239a8; font-weight: bold; }
|
||||
pre .preprocessor, pre .prepro { color: #a33243; }
|
||||
pre .global { color: #800080; }
|
||||
pre .user-keyword { color: #800080; }
|
||||
pre .prompt { color: #558817; }
|
||||
pre .url { color: #272fc2; text-decoration: underline; }
|
||||
|
||||
303
doc/modules/init.html
Normal file
303
doc/modules/init.html
Normal file
|
|
@ -0,0 +1,303 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<head>
|
||||
<title>Ubiquitousse reference</title>
|
||||
<link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="container">
|
||||
|
||||
<div id="product">
|
||||
<div id="product_logo"></div>
|
||||
<div id="product_name"><big><b></b></big></div>
|
||||
<div id="product_description"></div>
|
||||
</div> <!-- id="product" -->
|
||||
|
||||
|
||||
<div id="main">
|
||||
|
||||
|
||||
<!-- Menu -->
|
||||
|
||||
<div id="navigation">
|
||||
<br/>
|
||||
<h1>Ubiquitousse</h1>
|
||||
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Index</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<h2>Fields</h2>
|
||||
<ul class="nowrap">
|
||||
<li><a href="#version">version</a></li>
|
||||
<li><a href="#asset">asset</a></li>
|
||||
<li><a href="#ecs">ecs</a></li>
|
||||
<li><a href="#input">input</a></li>
|
||||
<li><a href="#ldtk">ldtk</a></li>
|
||||
<li><a href="#scene">scene</a></li>
|
||||
<li><a href="#signal">signal</a></li>
|
||||
<li><a href="#timer">timer</a></li>
|
||||
<li><a href="#util">util</a></li>
|
||||
</ul>
|
||||
<h2>Modules</h2>
|
||||
<ul class="nowrap">
|
||||
<li><strong>init</strong></li>
|
||||
<li><a href="../modules/ldtk.html">ldtk</a></li>
|
||||
</ul>
|
||||
<h2>Topics</h2>
|
||||
<ul class="">
|
||||
<li><a href="../topics/README.md.html">README</a></li>
|
||||
<li><a href="../topics/LICENSE.html">LICENSE</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
|
||||
<h1>Module <code>init</code></h1>
|
||||
<p>Ubiquitousse main module.</p>
|
||||
<p> Set of various Lua libraries to make game development easier, mainly made to be used alongside the <a href="https://love2d.org/">LÖVE</a> game framework.
|
||||
Nothing that hasn’t been done before, but these are tailored to what I need. They can be used independently too, and are relatively portable, even without LÖVE.</p>
|
||||
|
||||
<p> This is the main module, which will try to load every other Ubiquitousse module when required and may even provide a few convenience functions.</p>
|
||||
|
||||
<p> This also perform a quick LÖVE version check and show a warning in case of potential incompatibility.</p>
|
||||
|
||||
<p> <strong>Regarding Ubiquitousse’s organization</strong></p>
|
||||
|
||||
<p> Ubiquitousse may or may not be used in its totality. You can delete the modules directories you don’t need and Ubiquitousse
|
||||
should adapt accordingly. You can also simply copy the modules directories you need and use them directly, without using this
|
||||
file at all.
|
||||
However, some modules may provide more feature when other modules are available.
|
||||
These dependencies are written at the top of every main module file.</p>
|
||||
|
||||
<p> Ubiquitousse’s original goal was to run everywhere with the least porting effort possible, so while the current version now mainly focus LÖVE, it
|
||||
should still be easily modifiable to work with something else. Ubiquitousse is mainly tested on LuaJIT and Lua 5.3 but should also support Lua 5.1 and 5.2.
|
||||
In order to keep a good idea of how portable this all is, other dependencies, including LÖVE, are explicited at the top of every module file and in specific
|
||||
functions definition using the <code>@require</code> tag (e.g., <code>— @require love</code> for LÖVE).</p>
|
||||
|
||||
<p> Some modules are developped in <a href="https://github.com/Reuh/candran">Candran</a> (.can files), but can easily be compiled into regular Lua code.</p>
|
||||
|
||||
<p> Units used in the API documentation, unless written otherwise:</p>
|
||||
|
||||
<ul>
|
||||
<li>All distances are expressed in pixels (px)</li>
|
||||
<li>All durations are expressed in seconds (ms)</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<p> These units are only used to make writing documentation easier; you can use other units if you want, as long as you're consistent.</p>
|
||||
|
||||
<p> Style:</p>
|
||||
|
||||
<ul>
|
||||
<li>tabs for indentation, spaces for esthetic whitespace (notably in comments)</li>
|
||||
<li>no globals</li>
|
||||
<li>UPPERCASE for constants (or maybe not).</li>
|
||||
<li>CamelCase for class names.</li>
|
||||
<li>lowerCamelCase is expected for everything else.</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<p> Regarding the documentation: Ubiquitousse used LDoc/LuaDoc styled-comments, but since LDoc hates me and my code, the
|
||||
generated result is complete garbage, so please read the documentation directly in the comments here until fix this.
|
||||
Stuff you're interested in starts with triple – (e.g., “—– This functions saves the world”).</p>
|
||||
|
||||
<p> <em>UPDATE</em>: I give up, currently in the process of admitting defat to LDoc and progressively porting all my documentation to it.
|
||||
Though I had to modify a few things to get LDoc to like me, so the documentation is generated using <a href="https://github.com/Reuh/LDoc">my LDoc fork</a>.</p>
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">local ubiquitousse = require("ubiquitousse")
|
||||
</pre>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<h2 class="section-header "><a name="Fields"></a>Fields</h2>
|
||||
|
||||
<dl class="function">
|
||||
<dt>
|
||||
<a name = "version"></a>
|
||||
<strong>version</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Ubiquitousse version string (currently <code>"0.1.0"</code>).
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "asset"></a>
|
||||
<strong>asset</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Asset manager module, if available.
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>See also:</h3>
|
||||
<ul>
|
||||
<a href="../modules/init.html#asset">asset</a>
|
||||
</ul>
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "ecs"></a>
|
||||
<strong>ecs</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Entity Component System, if available.
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>See also:</h3>
|
||||
<ul>
|
||||
<a href="../modules/init.html#ecs">ecs</a>
|
||||
</ul>
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "input"></a>
|
||||
<strong>input</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Input management, if available.
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>See also:</h3>
|
||||
<ul>
|
||||
<a href="../modules/init.html#input">input</a>
|
||||
</ul>
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "ldtk"></a>
|
||||
<strong>ldtk</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
LDtk level import, if available.
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>See also:</h3>
|
||||
<ul>
|
||||
<a href="../modules/ldtk.html#">ldtk</a>
|
||||
</ul>
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "scene"></a>
|
||||
<strong>scene</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Scene management, if available.
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>See also:</h3>
|
||||
<ul>
|
||||
<a href="../modules/init.html#scene">scene</a>
|
||||
</ul>
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "signal"></a>
|
||||
<strong>signal</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Signal management, if available.
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>See also:</h3>
|
||||
<ul>
|
||||
<a href="../modules/init.html#signal">signal</a>
|
||||
</ul>
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "timer"></a>
|
||||
<strong>timer</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Timer utilities, if available.
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>See also:</h3>
|
||||
<ul>
|
||||
<a href="../modules/init.html#timer">timer</a>
|
||||
</ul>
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "util"></a>
|
||||
<strong>util</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Various useful functions, if available.
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>See also:</h3>
|
||||
<ul>
|
||||
<a href="../modules/init.html#util">util</a>
|
||||
</ul>
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
</div> <!-- id="content" -->
|
||||
</div> <!-- id="main" -->
|
||||
<div id="about">
|
||||
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
|
||||
<i style="float:right;">Last updated 2021-12-24 23:49:41 </i>
|
||||
</div> <!-- id="about" -->
|
||||
</div> <!-- id="container" -->
|
||||
</body>
|
||||
</html>
|
||||
1230
doc/modules/ldtk.html
Normal file
1230
doc/modules/ldtk.html
Normal file
File diff suppressed because it is too large
Load diff
65
doc/topics/LICENSE.html
Normal file
65
doc/topics/LICENSE.html
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<head>
|
||||
<title>Ubiquitousse reference</title>
|
||||
<link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="container">
|
||||
|
||||
<div id="product">
|
||||
<div id="product_logo"></div>
|
||||
<div id="product_name"><big><b></b></big></div>
|
||||
<div id="product_description"></div>
|
||||
</div> <!-- id="product" -->
|
||||
|
||||
|
||||
<div id="main">
|
||||
|
||||
|
||||
<!-- Menu -->
|
||||
|
||||
<div id="navigation">
|
||||
<br/>
|
||||
<h1>Ubiquitousse</h1>
|
||||
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Index</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<h2>Topics</h2>
|
||||
<ul class="">
|
||||
<li><a href="../topics/README.md.html">README</a></li>
|
||||
<li><strong>LICENSE</strong></li>
|
||||
</ul>
|
||||
<h2>Modules</h2>
|
||||
<ul class="nowrap">
|
||||
<li><a href="../modules/init.html">init</a></li>
|
||||
<li><a href="../modules/ldtk.html">ldtk</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
|
||||
Copyright 2021 Étienne “Reuh” Fildadut</p>
|
||||
|
||||
<p>Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.</p>
|
||||
|
||||
<p>THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
</div> <!-- id="content" -->
|
||||
</div> <!-- id="main" -->
|
||||
<div id="about">
|
||||
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
|
||||
<i style="float:right;">Last updated 2021-12-24 23:49:41 </i>
|
||||
</div> <!-- id="about" -->
|
||||
</div> <!-- id="container" -->
|
||||
</body>
|
||||
</html>
|
||||
70
doc/topics/README.md.html
Normal file
70
doc/topics/README.md.html
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<head>
|
||||
<title>Ubiquitousse reference</title>
|
||||
<link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="container">
|
||||
|
||||
<div id="product">
|
||||
<div id="product_logo"></div>
|
||||
<div id="product_name"><big><b></b></big></div>
|
||||
<div id="product_description"></div>
|
||||
</div> <!-- id="product" -->
|
||||
|
||||
|
||||
<div id="main">
|
||||
|
||||
|
||||
<!-- Menu -->
|
||||
|
||||
<div id="navigation">
|
||||
<br/>
|
||||
<h1>Ubiquitousse</h1>
|
||||
|
||||
|
||||
<ul>
|
||||
<li><a href="../index.html">Index</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<h2>Topics</h2>
|
||||
<ul class="">
|
||||
<li><strong>README</strong></li>
|
||||
<li><a href="../topics/LICENSE.html">LICENSE</a></li>
|
||||
</ul>
|
||||
<h2>Modules</h2>
|
||||
<ul class="nowrap">
|
||||
<li><a href="../modules/init.html">init</a></li>
|
||||
<li><a href="../modules/ldtk.html">ldtk</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
|
||||
<h1>ubiquitousse</h1>
|
||||
|
||||
<p>Set of various libraries I use for game development, mainly with LÖVE. Nothing that hasn’t been done before, but these are tailored to what I need. They can be used independently too.</p>
|
||||
|
||||
<p>Documentation is done in LDoc-like comments in source files, but LDoc doesn’t really like how I structure my libraries so you can’t really generate documentation with it. I'm currently trying to fix this; some modules already have a working LDoc documentation in <code>doc/</code>.</p>
|
||||
|
||||
<p>Whatever is currently on the master branch should be working and usable. Changelog, including breaking changes, are documented in commit messages.</p>
|
||||
|
||||
<p>Licensed under ISC (equivalent to MIT/Expat/Simplified BSD).</p>
|
||||
|
||||
|
||||
</div> <!-- id="content" -->
|
||||
</div> <!-- id="main" -->
|
||||
<div id="about">
|
||||
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
|
||||
<i style="float:right;">Last updated 2021-12-24 23:49:41 </i>
|
||||
</div> <!-- id="about" -->
|
||||
</div> <!-- id="container" -->
|
||||
</body>
|
||||
</html>
|
||||
69
init.lua
69
init.lua
|
|
@ -1,7 +1,14 @@
|
|||
-- ubiquitousse
|
||||
|
||||
--- Ubiquitousse Game Framework.
|
||||
-- Main module, which will try to load every other Ubiquitousse module when required and provide a few convenience functions.
|
||||
--- Ubiquitousse main module.
|
||||
-- Set of various Lua libraries to make game development easier, mainly made to be used alongside the [LÖVE](https://love2d.org/) game framework.
|
||||
-- Nothing that hasn't been done before, but these are tailored to what I need. They can be used independently too, and are relatively portable, even without LÖVE.
|
||||
--
|
||||
-- This is the main module, which will try to load every other Ubiquitousse module when required and may even provide a few convenience functions.
|
||||
--
|
||||
-- This also perform a quick LÖVE version check and show a warning in case of potential incompatibility.
|
||||
--
|
||||
-- **Regarding Ubiquitousse's organization**
|
||||
--
|
||||
-- Ubiquitousse may or may not be used in its totality. You can delete the modules directories you don't need and Ubiquitousse
|
||||
-- should adapt accordingly. You can also simply copy the modules directories you need and use them directly, without using this
|
||||
|
|
@ -9,47 +16,67 @@
|
|||
-- However, some modules may provide more feature when other modules are available.
|
||||
-- These dependencies are written at the top of every main module file.
|
||||
--
|
||||
-- Ubiquitousse's goal is to run everywhere with the least porting effort possible, so while the current version mainly focus LÖVE, it
|
||||
-- should be easily modifiable to work with something else. Ubiquitousse should only require:
|
||||
-- * The backend needs to have access to some kind of main loop, or at least a function called very often (may or may not be the
|
||||
-- same as the redraw screen callback).
|
||||
-- * Some way of measuring time (preferably with millisecond-precision).
|
||||
-- * Some kind of filesystem.
|
||||
-- * Lua 5.1, 5.2, 5.3 or LuaJit.
|
||||
-- * Other requirement for specific modules should be described in the module's documentation.
|
||||
-- Ubiquitousse's original goal was to run everywhere with the least porting effort possible, so while the current version now mainly focus LÖVE, it
|
||||
-- should still be easily modifiable to work with something else. Ubiquitousse is mainly tested on LuaJIT and Lua 5.3 but should also support Lua 5.1 and 5.2.
|
||||
-- In order to keep a good idea of how portable this all is, other dependencies, including LÖVE, are explicited at the top of every module file and in specific
|
||||
-- functions definition using the `@require` tag (e.g., `-- @require love` for LÖVE).
|
||||
--
|
||||
-- Functions that depends on LÖVE or anything that's not in the Lua standard libraries (and therefore the one you may want to port to
|
||||
-- another framework) are indicated by a "-- @impl love" annotation.
|
||||
-- Some modules are developped in [Candran](https://github.com/Reuh/candran) (.can files), but can easily be compiled into regular Lua code.
|
||||
--
|
||||
-- Units used in the API documentation, unless written otherwise:
|
||||
--
|
||||
-- Units used in the API documentation:
|
||||
-- * All distances are expressed in pixels (px)
|
||||
-- * All durations are expressed in seconds (ms)
|
||||
--
|
||||
-- These units are only used to make writing documentation easier; you can use other units if you want, as long as you're consistent.
|
||||
--
|
||||
-- Style:
|
||||
--
|
||||
-- * tabs for indentation, spaces for esthetic whitespace (notably in comments)
|
||||
-- * no globals
|
||||
-- * UPPERCASE for constants (or maybe not).
|
||||
-- * CamelCase for class names.
|
||||
-- * lowerCamelCase is expected for everything else.
|
||||
--
|
||||
-- For game writer:
|
||||
-- Ubiquitousse works with Lua 5.1 to 5.3, including LuaJit, but doesn't provide any version checking or compatibility layer
|
||||
-- between the different versions, so it's up to you to handle that in your game (or ignore the problem and sticks to your
|
||||
-- main's backend Lua version).
|
||||
--
|
||||
-- Regarding the documentation: Ubiquitousse used LDoc/LuaDoc styled-comments, but since LDoc hates me and my code, the
|
||||
-- generated result is complete garbage, so please read the documentation directly in the comments here until fix this.
|
||||
-- Stuff you're interested in starts with triple - (e.g., "--- This functions saves the world").
|
||||
--
|
||||
-- *UPDATE*: I give up, currently in the process of admitting defat to LDoc and progressively porting all my documentation to it.
|
||||
-- Though I had to modify a few things to get LDoc to like me, so the documentation is generated using [my LDoc fork](https://github.com/Reuh/LDoc).
|
||||
--
|
||||
-- @usage local ubiquitousse = require("ubiquitousse")
|
||||
|
||||
local p = ... -- require path
|
||||
local ubiquitousse
|
||||
|
||||
ubiquitousse = {
|
||||
--- Ubiquitousse version.
|
||||
version = "0.1.0"
|
||||
--- Ubiquitousse version string (currently `"0.1.0"`).
|
||||
version = "0.1.0",
|
||||
--- Asset manager module, if available.
|
||||
-- @see asset
|
||||
asset = nil,
|
||||
--- Entity Component System, if available.
|
||||
-- @see ecs
|
||||
ecs = nil,
|
||||
--- Input management, if available.
|
||||
-- @see input
|
||||
input = nil,
|
||||
--- LDtk level import, if available.
|
||||
-- @see ldtk
|
||||
ldtk = nil,
|
||||
--- Scene management, if available.
|
||||
-- @see scene
|
||||
scene = nil,
|
||||
--- Signal management, if available.
|
||||
-- @see signal
|
||||
signal = nil,
|
||||
--- Timer utilities, if available.
|
||||
-- @see timer
|
||||
timer = nil,
|
||||
--- Various useful functions, if available.
|
||||
-- @see util
|
||||
util = nil
|
||||
}
|
||||
|
||||
-- Check LÖVE version
|
||||
|
|
@ -70,7 +97,7 @@ end
|
|||
package.loaded[p] = ubiquitousse
|
||||
|
||||
-- Require external submodules
|
||||
for _, m in ipairs{"signal", "asset", "ecs", "input", "scene", "timer", "util"} do
|
||||
for _, m in ipairs{"signal", "asset", "ecs", "input", "scene", "timer", "util", "ldtk"} do
|
||||
local s, t = pcall(require, p.."."..m)
|
||||
if s then
|
||||
ubiquitousse[m] = t
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ input = {
|
|||
-- The function may error if the identifier is incorrect.
|
||||
-- @tparam string button identifier, depends on the platform Ubiquitousse is running on
|
||||
-- @treturn the new button detector
|
||||
-- @impl love
|
||||
-- @require love
|
||||
basicButtonDetector = function(str) end,
|
||||
|
||||
--- Make a new button detector from a detector function, string, or list of buttons.
|
||||
|
|
@ -85,7 +85,7 @@ input = {
|
|||
-- The function may error if the identifier is incorrect.
|
||||
-- @tparam string axis identifier, depends on the platform Ubiquitousse is running on
|
||||
-- @treturn the new axis detector
|
||||
-- @impl love
|
||||
-- @require love
|
||||
basicAxisDetector = function(str) end,
|
||||
|
||||
--- Make a new axis detector from a detector function, string, or a couple of buttons.
|
||||
|
|
@ -117,13 +117,13 @@ input = {
|
|||
-- This may also returns "axis threshold" buttons if an axis passes the threshold.
|
||||
-- @tparam[opt=0.5] number threshold the threshold to detect axes as button
|
||||
-- @treturn string,... buttons identifiers list
|
||||
-- @impl love
|
||||
-- @require love
|
||||
buttonUsed = function(threshold) end,
|
||||
|
||||
--- Returns a list of the axes currently in use, identified by their string axis identifier
|
||||
-- @tparam[opt=0.5] number threshold the threshold to detect axes
|
||||
-- @treturn string,... axes identifiers list
|
||||
-- @impl love
|
||||
-- @require love
|
||||
axisUsed = function(threshold) end,
|
||||
|
||||
--- Returns a nice name for the button identifier.
|
||||
|
|
@ -131,7 +131,7 @@ input = {
|
|||
-- May returns the raw identifier if you're lazy.
|
||||
-- @tparam string... button identifier string(s)
|
||||
-- @treturn string... the displayable names
|
||||
-- @impl love
|
||||
-- @require love
|
||||
buttonName = function(...) end,
|
||||
|
||||
--- Returns a nice name for the axis identifier.
|
||||
|
|
@ -139,7 +139,7 @@ input = {
|
|||
-- May returns the raw identifier if you're lazy.
|
||||
-- @tparam string... axis identifier string(s)
|
||||
-- @treturn string... the displayable names
|
||||
-- @impl love
|
||||
-- @require love
|
||||
axisName = function(...) end,
|
||||
|
||||
-------------------
|
||||
|
|
@ -152,7 +152,7 @@ input = {
|
|||
-- any platform without having to configure the keys.
|
||||
-- If some key function in your game match one of theses defaults, using it instead of creating a new
|
||||
-- input would be a good idea.
|
||||
-- @impl love
|
||||
-- @require love
|
||||
default = {
|
||||
pointer = nil, -- Pointer: used to move and select. Example binds: arrow keys, WASD, stick.
|
||||
confirm = nil, -- Button: used to confirm something. Example binds: Enter, A button.
|
||||
|
|
@ -161,7 +161,7 @@ input = {
|
|||
|
||||
--- Get draw area dimensions.
|
||||
-- Used for pointers.
|
||||
-- @impl love
|
||||
-- @require love
|
||||
getDrawWidth = function() return 1 end,
|
||||
getDrawHeight = function() return 1 end,
|
||||
|
||||
|
|
|
|||
1
ldtk/init.lua
Normal file
1
ldtk/init.lua
Normal file
|
|
@ -0,0 +1 @@
|
|||
return require((...)..".ldtk")
|
||||
596
ldtk/ldtk.can
Normal file
596
ldtk/ldtk.can
Normal file
|
|
@ -0,0 +1,596 @@
|
|||
--- [LDtk](https://ldtk.io/) level importer for LÖVE.
|
||||
-- Support most LDtk features, and allow easy usage in LÖVE projects.
|
||||
--
|
||||
-- Every unit is in pixel in the API unless written otherwise.
|
||||
--
|
||||
-- This modules returns a single function @{LDtk}(path).
|
||||
--
|
||||
-- Requires LÖVE `love.graphics` (drawing Image, SpriteBatch, Quad).
|
||||
--
|
||||
-- @module ldtk
|
||||
-- @require love
|
||||
-- @usage
|
||||
-- local ldtk = require("ubiquitousse.ldtk")
|
||||
--
|
||||
-- local project = ltdk("example.ldtk")
|
||||
--
|
||||
-- local callbacks = {
|
||||
-- onAddEntity = function(entity)
|
||||
-- -- handle entity...
|
||||
-- end
|
||||
-- }
|
||||
--
|
||||
-- -- load every level
|
||||
-- for _, lvl in ipairs(project.levels) do lvl:load() end
|
||||
--
|
||||
-- function love.draw()
|
||||
-- -- draw every level
|
||||
-- for _, lvl in ipairs(project.levels) do lvl:draw() end
|
||||
-- end
|
||||
|
||||
-- TODO: give associated tile & color with enum values, also give enum info
|
||||
|
||||
let lg = love.graphics
|
||||
|
||||
--- json helpers
|
||||
let json_decode = require("json").decode
|
||||
let readJson = (file)
|
||||
let f = assert(io.open(file, "r"))
|
||||
local t = json_decode(f:read("*a"))
|
||||
f:close()
|
||||
return t
|
||||
end
|
||||
|
||||
--- color helpers
|
||||
let parseColor = (str)
|
||||
local r, g, b = str:match("^#(..)(..)(..)")
|
||||
r, g, b = tonumber(r, 16), tonumber(g, 16), tonumber(b, 16)
|
||||
return { r/255, g/255, b/255 }
|
||||
end
|
||||
let white = {1,1,1}
|
||||
|
||||
--- returns a lua table from some fieldInstances
|
||||
let toLua = (type, val)
|
||||
if val == nil then return val end
|
||||
if type:match("^Array%<") then
|
||||
local itype = type:match("^Array%<(.*)%>$")
|
||||
for i, v in ipairs(val) do
|
||||
val[i] = toLua(itype, v)
|
||||
end
|
||||
elseif type == "Color" then
|
||||
return parseColor(val)
|
||||
elseif type == "Point" then
|
||||
return { x = val.cx, y = val.cy }
|
||||
end
|
||||
return val
|
||||
end
|
||||
let getFields = (f)
|
||||
local t = {}
|
||||
for _, v in ipairs(f) do
|
||||
t[v.__identifier] = toLua(v.__type, v.__value)
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
let tileset_mt
|
||||
|
||||
let make_cache = (new_fn)
|
||||
return setmetatable({}, {
|
||||
__mode = "v",
|
||||
__call = (cache, id)
|
||||
if not cache[id] then
|
||||
cache[id] = new_fn(id)
|
||||
end
|
||||
return cache[id]
|
||||
end
|
||||
})
|
||||
end
|
||||
let cache = {
|
||||
tileset = make_cache((tilesetDef)
|
||||
return tileset_mt._init(tilesetDef)
|
||||
end),
|
||||
image = make_cache((path)
|
||||
return lg.newImage(path)
|
||||
end),
|
||||
}
|
||||
|
||||
--- Tileset object.
|
||||
-- Stores the image associated with the tileset; can be shared among several layers and levels.
|
||||
-- @type Tileset
|
||||
-- @require love
|
||||
tileset_mt = {
|
||||
_newQuad = :(x, y, width, height)
|
||||
return lg.newQuad(x, y, width, height, @image)
|
||||
end,
|
||||
_getTileQuad = :(tileid, x, y, size)
|
||||
if not @_tileQuads[tileid] then
|
||||
@_tileQuads[tileid] = @_newQuad(x, y, size, size)
|
||||
end
|
||||
return @_tileQuads[tileid]
|
||||
end,
|
||||
_init = (tilesetDef)
|
||||
local t = {
|
||||
--- The tileset LÖVE image object.
|
||||
image = cache.image(tilesetDef.path),
|
||||
|
||||
_tileQuads = {}
|
||||
}
|
||||
return setmetatable(t, tileset_mt)
|
||||
end
|
||||
}
|
||||
tileset_mt.__index = tileset_mt
|
||||
|
||||
--- Layer object.
|
||||
--
|
||||
-- Part of a @{Level}.
|
||||
--
|
||||
-- @type Layer
|
||||
-- @require love
|
||||
let layer_mt = {
|
||||
--- Draw the current layer.
|
||||
-- Assumes we are currently in level coordinates (i.e. level top-left is at 0,0).
|
||||
-- @require love
|
||||
draw = :()
|
||||
if @visible then
|
||||
lg.push()
|
||||
lg.translate(@offsetX, @offsetY)
|
||||
if @spritebatch then
|
||||
lg.setColor(1, 1, 1, @opacity)
|
||||
lg.draw(@spritebatch)
|
||||
elseif @intTiles then
|
||||
for _, t in ipairs(@intTiles) do
|
||||
lg.setColor(t.color)
|
||||
lg.rectangle("fill", t.x, t.y, t.layer.gridSize, t.layer.gridSize)
|
||||
end
|
||||
elseif @entities then
|
||||
for _, e in ipairs(@entities) do
|
||||
if e.draw then e:draw() end
|
||||
end
|
||||
end
|
||||
lg.pop()
|
||||
end
|
||||
end,
|
||||
|
||||
_unloadCallbacks = :(callbacks)
|
||||
local onRemoveTile = callbacks.onRemoveTile
|
||||
if @tiles and onRemoveTile then
|
||||
for _, t in ipairs(@tiles) do
|
||||
onRemoveTile(t)
|
||||
end
|
||||
end
|
||||
local onRemoveIntTile = callbacks.onRemoveIntTile
|
||||
if @intTiles and onRemoveIntTile then
|
||||
for _, t in ipairs(@intTiles) do
|
||||
onRemoveIntTile(t)
|
||||
end
|
||||
end
|
||||
local onRemoveEntity = callbacks.onRemoveEntity
|
||||
if @entities and onRemoveEntity then
|
||||
for _, e in ipairs(@entities) do
|
||||
onRemoveEntity(e)
|
||||
end
|
||||
end
|
||||
end,
|
||||
_init = (layer, level, order, callbacks)
|
||||
let gridSize = layer.__gridSize
|
||||
let t = {
|
||||
--- @{Level} this layer belongs to.
|
||||
level = level,
|
||||
--- The layer name.
|
||||
identifier = layer.__identifier,
|
||||
--- Type of layer: IntGrid, Entities, Tiles or AutoLayer (string).
|
||||
type = layer.__type,
|
||||
--- Whether the layer is visible or not.
|
||||
visible = layer.visible,
|
||||
--- The layer opacity (0-1).
|
||||
opacity = layer.opacity,
|
||||
--- The layer order: smaller order means it is on top.
|
||||
order = order,
|
||||
--- X position of the layer relative to the level.
|
||||
offsetX = layer.__pxTotalOffsetX,
|
||||
--- Y position of the layer relative to the level.
|
||||
offsetY = layer.__pxTotalOffsetY,
|
||||
--- Size of the grid on this layer.
|
||||
gridSize = gridSize,
|
||||
--- Width of the layer, in grid units.
|
||||
gridWidth = layer.__cWid,
|
||||
--- Height of the layer, in grid units.
|
||||
gridHeight = layer.__cHei,
|
||||
--- _(Entities layer only)_ List of @{Entity} in the layer.
|
||||
entities = nil,
|
||||
--- _(Tiles, AutoLayer, or IntGrid with AutoLayer rules layers only)_ List of @{Tile}s in the layer.
|
||||
tiles = nil,
|
||||
--- _(Tiles, AutoLayer, or IntGrid with AutoLayer rules layers only)_ @{Tileset} object associated with the layer.
|
||||
tileset = nil,
|
||||
--- _(Tiles, AutoLayer, or IntGrid with AutoLayer rules layers only)_ [LÖVE SpriteBatch](https://love2d.org/wiki/SpriteBatch) containing the layer.
|
||||
spritebatch = nil,
|
||||
--- _(IntGrid without AutoLayer rules layer only)_ list of @{IntTile}s in the layer.
|
||||
intTiles = nil,
|
||||
}
|
||||
-- Layers with an associated tileset (otherwise ignore as there is nothing to draw) (Tiles, AutoLayer & IntGrid with AutoLayer rules)
|
||||
if layer.__tilesetDefUid then
|
||||
t.tiles = {}
|
||||
local tilesetData = level.project._tilesetData[layer.__tilesetDefUid]
|
||||
t.tileset = cache.tileset(tilesetData)
|
||||
local tiles = layer.__type == "Tiles" and layer.gridTiles or layer.autoLayerTiles
|
||||
local onAddTile = callbacks.onAddTile
|
||||
t.spritebatch = lg.newSpriteBatch(t.tileset.image)
|
||||
for _, tl in ipairs(tiles) do
|
||||
let quad = t.tileset:_getTileQuad(tl.t, tl.src[1], tl.src[2], gridSize)
|
||||
let sx, sy = 1, 1
|
||||
let x, y = tl.px[1], tl.px[2]
|
||||
--- Tile object.
|
||||
--
|
||||
-- This represent the tiles from a Tiles, AutoLayer or IntGrid with AutoLayer rules layer.
|
||||
--
|
||||
-- Can be retrived from the @{tiles} list or `onAddTile` level load callback.
|
||||
--
|
||||
-- @type Tile
|
||||
let tile = {
|
||||
--- Layer the tile belongs to.
|
||||
layer = t,
|
||||
--- X position of the tile relative to the layer.
|
||||
x = x,
|
||||
--- Y position of the tile relative to the layer.
|
||||
y = y,
|
||||
--- Whether the tile is flipped horizontally.
|
||||
flipX = false,
|
||||
--- Whether the tile is flipped vertically.
|
||||
flipY = false,
|
||||
--- Tags associated with the tile: can be used either as a list of tags or a map of activated tags tags[name] == true.
|
||||
tags = tilesetData[tl.t].tags,
|
||||
--- Custom data associated with the tile, if any.
|
||||
data = tilesetData[tl.t].data,
|
||||
--- Quad associated with the tile (relative to the layer's tileset).
|
||||
quad = quad
|
||||
}
|
||||
if tl.f == 1 or tl.f == 3 then
|
||||
sx = -1
|
||||
x += gridSize
|
||||
tile.flipX = true
|
||||
end
|
||||
if tl.f == 2 or tl.f == 3 then
|
||||
sy = -1
|
||||
y += gridSize
|
||||
tile.flipY = true
|
||||
end
|
||||
t.spritebatch:add(quad, x, y, 0, sx, sy)
|
||||
table.insert(t.tiles, tile)
|
||||
if onAddTile then onAddTile(tile) end
|
||||
end
|
||||
-- IntGrid
|
||||
elseif layer.__type == "IntGrid" then
|
||||
t.intTiles = {}
|
||||
local onAddIntTile = callbacks.onAddIntTile
|
||||
local values = level.project._layerDef[layer.layerDefUid].intGridValues
|
||||
for i, tl in ipairs(layer.intGridCsv) do
|
||||
if tl > 0 then
|
||||
let y = math.floor((i-1) / t.gridWidth) * gridSize
|
||||
let x = ((i-1) % t.gridWidth) * gridSize
|
||||
--- IntTile object.
|
||||
--
|
||||
-- This represent the tiles from a IntGrid without AutoLayer rules layer.
|
||||
--
|
||||
-- Can be retrived from the @{intTiles} list or `onAddIntTile` level load callback.
|
||||
--
|
||||
-- @type IntTile
|
||||
let tile = {
|
||||
--- Layer the IntTile belongs to.
|
||||
layer = t,
|
||||
--- X position of the IntTile relative to the layer.
|
||||
x = x,
|
||||
--- Y position of the IntTile relative to the layer.
|
||||
y = y,
|
||||
--- Name of the IntTile.
|
||||
identifier = values[tl].identifier,
|
||||
--- Integer value of the IntTile.
|
||||
value = tl,
|
||||
--- Color of the IntTile.
|
||||
color = values[tl].color
|
||||
}
|
||||
table.insert(t.intTiles, tile)
|
||||
if onAddIntTile then onAddIntTile(tile) end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Entities layers
|
||||
if layer.__type == "Entities" then
|
||||
t.entities = {}
|
||||
local onAddEntity = callbacks.onAddEntity
|
||||
for _, e in ipairs(layer.entityInstances) do
|
||||
let entityDef = level.project._entityData[e.defUid]
|
||||
--- Entity object.
|
||||
--
|
||||
-- This represent an entity from an Entities layer.
|
||||
--
|
||||
-- Can be retrived from the @{entities} list or `onAddEntity` level load callback.
|
||||
--
|
||||
-- @type Entity
|
||||
let entity = {
|
||||
--- @{Layer} this entity belongs to.
|
||||
layer = t,
|
||||
--- The entity name.
|
||||
identifier = e.__identifier,
|
||||
--- X position of the entity relative to the layer.
|
||||
x = e.px[1],
|
||||
--- Y position of the entity relative to the layer.
|
||||
y = e.px[2],
|
||||
--- The entity width.
|
||||
width = e.width,
|
||||
--- The entity height.
|
||||
height = e.height,
|
||||
--- Scale factor on x axis relative to original entity size.
|
||||
sx = e.width / entityDef.width,
|
||||
--- Scale factor on y axis relative to original entity size.
|
||||
sy = e.height / entityDef.height,
|
||||
--- The entity pivot point x position relative to the entity.
|
||||
pivotX = e.__pivot[1] * e.width,
|
||||
--- The entity pivot point x position relative to the entity.
|
||||
pivotY = e.__pivot[2] * e.height,
|
||||
--- Entity color.
|
||||
color = entityDef.color,
|
||||
--- Entity tile, if any. Is a table { tileset = associated tileset object, quad = associated quad }.
|
||||
tile = nil,
|
||||
--- Map of custom fields of the entity.
|
||||
fields = getFields(e.fieldInstances),
|
||||
--- Called for the entity when drawing the associated entity layer (you will likely want to redefine it).
|
||||
--
|
||||
-- By default, this draws the tile associated with the entity if there is one, or a rectangle around the entity position otherwise.
|
||||
-- @require love
|
||||
draw = :()
|
||||
if @tile then
|
||||
let _, _, w, h = @tile.quad:getViewport()
|
||||
lg.setColor(white)
|
||||
lg.draw(@tile.tileset.image, @tile.quad, @x-@pivotX, @y-@pivotY, 0, @width / w, @height / h)
|
||||
else
|
||||
lg.setColor(@color)
|
||||
lg.rectangle("line", @x-@pivotX, @y-@pivotY, @width, @height)
|
||||
end
|
||||
end
|
||||
}
|
||||
if e.__tile then
|
||||
local tileset = cache.tileset(level.project._tilesetData[e.__tile.tilesetUid])
|
||||
local srcRect = e.__tile.srcRect
|
||||
local quad = tileset:_newQuad(srcRect[1], srcRect[2], srcRect[3], srcRect[4])
|
||||
entity.tile = {
|
||||
tileset = tileset,
|
||||
quad = quad
|
||||
}
|
||||
end
|
||||
table.insert(t.entities, entity)
|
||||
if onAddEntity then onAddEntity(entity) end
|
||||
end
|
||||
end
|
||||
return setmetatable(t, layer_mt)
|
||||
end
|
||||
}
|
||||
layer_mt.__index = layer_mt
|
||||
|
||||
--- Level object.
|
||||
--
|
||||
-- Levels are not automatically loaded in order to not waste ressources if your project is large; so before drawing or operating on a level, you will need to call its @{Level:load} method.
|
||||
--
|
||||
-- Part of a @{Project}.
|
||||
--
|
||||
-- @type Level
|
||||
-- @require love
|
||||
let level_mt = {
|
||||
--- Draw this level.
|
||||
-- Assumes we are currently in world coordinates (i.e. world top-left is at 0,0).
|
||||
-- The level must be loaded.
|
||||
-- Will draw the eventual backgrounds and all the layers in the level.
|
||||
-- @require love
|
||||
draw = :()
|
||||
assert(@loaded == true, "level not loaded")
|
||||
lg.push()
|
||||
lg.translate(@x, @y)
|
||||
-- background color
|
||||
lg.setColor(@_bgColor)
|
||||
lg.rectangle("fill", 0, 0, @width, @height)
|
||||
-- background image
|
||||
lg.setColor(white)
|
||||
if @_bgImage then
|
||||
lg.draw(@_bgImage.image, @_bgImage.quad, @_bgImage.x, @_bgImage.y, 0, @_bgImage.sx, @_bgImage.sy)
|
||||
end
|
||||
-- layers
|
||||
for _, l in ipairs(@layers) do
|
||||
l:draw()
|
||||
end
|
||||
lg.pop()
|
||||
end,
|
||||
|
||||
--- Load the level.
|
||||
-- Will load every layer in the level and the associated images.
|
||||
--
|
||||
-- You can optionally specify some callbacks for the loading process:
|
||||
--
|
||||
-- * `onAddLayer(layer)` will be called for every new layer loaded, with the @{Layer} as sole argument
|
||||
-- * `onAddTile(tile)` will be called for every new tile loaded, with the @{Tile} as sole argument
|
||||
-- * `onAddIntTile(tile)` will be called for every new IntGrid tile loaded, with the @{IntTile} as sole argument
|
||||
-- * `onAddEntity(entity)` will be called for every new entity loaded, with the @{Entity} as sole argument
|
||||
--
|
||||
-- These callbacks should allow you to capture all the important elements needed to use the level, so you can hopefully
|
||||
-- integrate it into your current game engine easily.
|
||||
--
|
||||
-- @tab[opt] callbacks
|
||||
-- @require love
|
||||
load = :(callbacks={})
|
||||
assert(@loaded == false, "level already loaded")
|
||||
if @_json.bgRelPath then
|
||||
let pos = @_json.__bgPos
|
||||
let cropRect = pos.cropRect
|
||||
let image = cache.image(@project._directory..@_json.bgRelPath)
|
||||
@_bgImage = {
|
||||
image = image,
|
||||
quad = lg.newQuad(cropRect[1], cropRect[2], cropRect[3], cropRect[4], image),
|
||||
x = pos.topLeftPx[1],
|
||||
y = pos.topLeftPx[2],
|
||||
sx = pos.scale[1],
|
||||
sy = pos.scale[1]
|
||||
}
|
||||
end
|
||||
let layerInstances
|
||||
if @_json.externalRelPath then
|
||||
layerInstances = readJson(@project._directory..@_json.externalRelPath).layerInstances
|
||||
else
|
||||
layerInstances = @_json.layerInstances
|
||||
end
|
||||
@layers = {}
|
||||
let onAddLayer = callbacks.onAddLayer
|
||||
for i=#layerInstances, 1, -1 do
|
||||
local layer = layer_mt._init(layerInstances[i], @, i, callbacks)
|
||||
table.insert(@layers, layer)
|
||||
if onAddLayer then onAddLayer(layer) end
|
||||
end
|
||||
@loaded = true
|
||||
end,
|
||||
--- Unload the level.
|
||||
-- Images loaded by the level will be freed on the next garbage collection cycle.
|
||||
--
|
||||
-- You can optionally specify some callbacks for the unloading process:
|
||||
--
|
||||
-- * `onAddLayer(layer)` will be called for every new layer unloaded, with the @{Layer} as sole argument
|
||||
-- * `onAddTile(tile)` will be called for every new tile unloaded, with the @{Tile} as sole argument
|
||||
-- * `onAddIntTile(tile)` will be called for every new IntGrid tile unloaded, with the @{IntTile} as sole argument
|
||||
-- * `onAddEntity(entity)` will be called for every new entity unloaded, with the @{Entity} as sole argument
|
||||
--
|
||||
-- @tab[opt] callbacks
|
||||
unload = :(callbacks={})
|
||||
assert(@loaded == true, "level not loaded")
|
||||
let onRemoveLayer = callbacks.onRemoveLayer
|
||||
for _, l in ipairs(@layers) do
|
||||
l:_unloadCallbacks(callbacks)
|
||||
if onRemoveLayer then onRemoveLayer(l) end
|
||||
end
|
||||
@loaded = false
|
||||
@_bgImage = nil
|
||||
@_bgImageQuads = nil
|
||||
@layers = nil
|
||||
end,
|
||||
|
||||
_init = (level, project)
|
||||
let t = {
|
||||
--- @{Project} this level belongs to.
|
||||
project = project,
|
||||
--- Whether this level is currently loaded or not (boolean).
|
||||
loaded = false,
|
||||
--- The level name (string).
|
||||
identifier = level.identifier,
|
||||
--- The level x position (number).
|
||||
x = level.worldX,
|
||||
--- The level y position (number).
|
||||
y = level.worldY,
|
||||
--- The level width (number).
|
||||
width = level.pxWid,
|
||||
--- The level height (number).
|
||||
height = level.pxHei,
|
||||
--- Map of custom fields of the level (table).
|
||||
fields = getFields(level.fieldInstances),
|
||||
--- List of @{Layer}s in the level (table).
|
||||
layers = nil,
|
||||
|
||||
-- private
|
||||
_json = level,
|
||||
_bgColor = parseColor(level.__bgColor),
|
||||
_bgImage = nil
|
||||
}
|
||||
return setmetatable(t, level_mt)
|
||||
end
|
||||
}
|
||||
level_mt.__index = level_mt
|
||||
|
||||
--- Project object.
|
||||
--
|
||||
-- Returned by @{LDtk}.
|
||||
--
|
||||
-- @type Project
|
||||
let project_mt = {
|
||||
_init = (project, directory)
|
||||
assert(project.jsonVersion == "0.9.3", "map made for LDtk version %s":format(project.jsonVersion))
|
||||
let t = {
|
||||
--- List of @{Level}s in this project.
|
||||
levels = nil,
|
||||
|
||||
-- private
|
||||
_directory = directory,
|
||||
_layerDef = nil,
|
||||
_tilesetData = nil,
|
||||
_entityData = nil,
|
||||
}
|
||||
t.levels = [
|
||||
for _, lvl in ipairs(project.levels) do
|
||||
push level_mt._init(lvl, t)
|
||||
end
|
||||
]
|
||||
t._tilesetData = [
|
||||
for _, ts in ipairs(project.defs.tilesets) do
|
||||
@[ts.uid] = {
|
||||
path = directory..ts.relPath
|
||||
}
|
||||
local tilesetData = @[ts.uid]
|
||||
for gridx=0, ts.__cWid-1 do
|
||||
for gridy=0, ts.__cHei-1 do
|
||||
tilesetData[gridx + gridy * ts.__cWid] = {
|
||||
tags = {},
|
||||
data = nil
|
||||
}
|
||||
end
|
||||
end
|
||||
for _, custom in ipairs(ts.customData) do
|
||||
tilesetData[custom.tileId].data = custom.data
|
||||
end
|
||||
for _, tag in ipairs(ts.enumTags) do
|
||||
local value = tag.enumValueId
|
||||
for _, tileId in ipairs(tag.tileIds) do
|
||||
table.insert(tilesetData[tileId].tags, value)
|
||||
tilesetData[tileId].tags[value] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
]
|
||||
t._layerDef = [
|
||||
for _, lay in ipairs(project.defs.layers) do
|
||||
@[lay.uid] = {
|
||||
intGridValues = nil
|
||||
}
|
||||
local layerDef = @[lay.uid]
|
||||
if lay.__type == "IntGrid" then
|
||||
layerDef.intGridValues = [
|
||||
for _, v in ipairs(lay.intGridValues) do
|
||||
@[v.value] = {
|
||||
color = parseColor(v.color),
|
||||
identifier = v.identifier
|
||||
}
|
||||
end
|
||||
]
|
||||
end
|
||||
end
|
||||
]
|
||||
t._entityData = [
|
||||
for _, ent in ipairs(project.defs.entities) do
|
||||
@[ent.uid] = {
|
||||
color = parseColor(ent.color),
|
||||
width = ent.width,
|
||||
height = ent.height
|
||||
}
|
||||
end
|
||||
]
|
||||
return setmetatable(t, project_mt)
|
||||
end
|
||||
}
|
||||
project_mt.__index = project_mt
|
||||
|
||||
--- Custom fields.
|
||||
-- @section fields
|
||||
|
||||
--- Module.
|
||||
-- `ubiquitousse.ldtk` returns a single function, @{LDtk}.
|
||||
-- @section module
|
||||
|
||||
--- Load a LDtk project.
|
||||
-- @string path to LDtk project file (.ldtk)
|
||||
-- @treturn Project the loaded LDtk project
|
||||
-- @function LDtk
|
||||
return (file)
|
||||
return project_mt._init(readJson(file), file:match("^(.-)[^%/%\\]+$"))
|
||||
end
|
||||
|
|
@ -97,7 +97,7 @@ let signal = {
|
|||
|
||||
--- Call this function to hook signal.event signals to the current backend.
|
||||
-- For LÖVE, this means overriding every existing LÖVE callback. If a callback is already defined, the new one will call the old function along with the signal:emit.
|
||||
-- @impl love
|
||||
-- @require love
|
||||
registerEvents = ()
|
||||
local callbacks = { -- everything except run, errorhandler, threaderror
|
||||
"displayrotated", "draw", "load", "lowmemory", "quit", "update",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue