docs: Upgrade documentation site (#1365)

This commit is contained in:
Pasha Stetsenko
2022-02-12 22:50:13 -08:00
committed by GitHub
parent 3e0589730c
commit 12cf8f7096
47 changed files with 1460 additions and 497 deletions

View File

@ -3,14 +3,14 @@
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
import docutils
import os
# -- Project information -----------------------------------------------------
project = 'Flame'
copyright = '2021, Blue Fire Team'
author = 'Blue Fire Team'
root_doc = "index"
@ -47,17 +47,8 @@ exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', 'summary.md']
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages.
html_theme = "sphinx_book_theme"
# See https://sphinx-book-theme.readthedocs.io/en/latest/customize/index.html
html_theme_options = {
"logo_only": True,
"path_to_docs": "doc",
"repository_branch": "main",
"repository_url": "https://github.com/flame-engine/flame",
"use_edit_page_button": True,
"use_repository_button": True,
}
html_theme = "flames"
html_theme_options = {}
html_title = "Flame"
html_logo = "images/logo_flame.png"
html_favicon = "images/favicon.ico"
@ -68,6 +59,66 @@ pygments_style = 'monokai'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['images', 'styles', 'scripts']
html_css_files = ['custom.css']
html_static_path = ['images', 'scripts', 'theme']
html_js_files = ['versions.js']
# -- Custom setup ------------------------------------------------------------
class TitleCollector(docutils.nodes.SparseNodeVisitor):
def __init__(self, document):
self.level = 0
self.titles = []
super().__init__(document)
def visit_section(self, node):
title_class = docutils.nodes.title
self.level += 1
if node.children and isinstance(node.children[0], title_class):
title = node.children[0].astext()
node_id = node.get("ids")[0]
self.titles.append([title, node_id, self.level])
def depart_section(self, node):
self.level -= 1
def get_local_toc(document):
if not document:
return ""
visitor = TitleCollector(document)
document.walkabout(visitor)
titles = visitor.titles
if not titles:
return ""
levels = sorted(set(item[2] for item in titles))
if levels.index(titles[0][2]) != 0:
return document.reporter.error(
"First title on the page is not <h1/>")
del titles[0] # remove the <h1> title
h1_seen = False
ul_level = 0
html_text = "<div id='toc-local' class='list-group'>\n"
html_text += " <div class='header'><i class='fa fa-list'></i> Contents</div>\n"
for title, node_id, level in titles:
if level <= 1:
return document.reporter.error("More than one <h1> title on the page")
html_text += f" <a href='#{node_id}' class='list-group-item level-{level-1}'>{title}</a>\n"
html_text += "</div>\n"
return html_text
# Emitted when the HTML builder has created a context dictionary to render
# a template with this can be used to add custom elements to the context.
def on_html_page_context(app, pagename, templatename, context, doctree):
context["get_local_toc"] = lambda: get_local_toc(doctree)
def setup(app):
this_dir = os.path.dirname(__file__)
theme_dir = os.path.abspath(os.path.join(this_dir, 'theme'))
app.add_css_file('flames.css')
app.add_html_theme('flames', theme_dir)
app.connect("html-page-context", on_html_page_context)

View File

@ -2,5 +2,4 @@ linkify-it-py>=1.0
myst-parser>=0.15.2
pygments>=2.10
sphinx>=4.2
sphinx-book-theme>=0.1.4
sphinxcontrib-mermaid>=0.7.1

View File

@ -10,7 +10,7 @@ function getCurrentDocVersion() {
return parts[1];
}
}
return '--';
return 'local';
}
// Given a list of versions (as plain strings), convert them into HTML <A/>
@ -24,7 +24,11 @@ function convertVersionsToHtmlLinks(versionsList, currentVersion) {
if (version === currentVersion) {
classes += ' selected';
}
out += `<a href="/${version}/"><button class="${classes}">${version}</button></a>`;
out += `<a href="/${version}/">
<button class="${classes}">
<i class="fa fa-code-branch"></i> ${version}
</button>
</a>`;
}
return out;
}
@ -32,15 +36,21 @@ function convertVersionsToHtmlLinks(versionsList, currentVersion) {
function buildVersionsMenu(data) {
const currentVersion = getCurrentDocVersion();
const versionButtons = convertVersionsToHtmlLinks(data.split('\n'), currentVersion);
$('div.topbar-main').append(`
<div class="dropdown-buttons-trigger" id="versions-menu">
<button class="btn btn-secondary topbarbtn">
<span class="tag">version:</span>
$('div.versions-placeholder').append(`
<div id="versions-menu" tabindex="-1">
<div class="btn">
<i class="fa fa-code-branch"></i>
<span class="version-id">${currentVersion}</span>
</button>
<div class="dropdown-buttons">${versionButtons}</div>
</div>
<div class="dropdown-buttons">
<div class="header">View documentation for version:</div>
${versionButtons}
</div>
</div>
`);
$("#versions-menu").on("click blur", function() {
$(this).toggleClass("active");
});
}
// Start loading the versions list as soon as possible, don't wait for DOM
@ -51,5 +61,9 @@ const versionsRequest = $.get(
// Now wait for DOM to finish loading
$(function() {
// Lastly, wait for versions to finish loading too.
versionsRequest.then(buildVersionsMenu);
versionsRequest.then(buildVersionsMenu)
.fail(function() {
console.log("Failed to load versions.txt, using default version list");
buildVersionsMenu("local\nmain\n1.0.0\n");
});
});

View File

@ -1,367 +0,0 @@
:root {
--pst-color-inline-code: 255, 140, 50;
--pst-color-link: 100, 150, 200;
--pst-color-preformatted-background: 50, 50, 50;
--pst-color-primary: 240, 240, 240;
--pst-color-sidebar-caption: 250, 250, 255;
--pst-color-sidebar-link: 150, 160, 170;
--pst-color-sidebar-link-active: 80, 190, 255;
--pst-color-text-base: 211, 211, 211;
--pst-color-toc-link: 130, 130, 130;
}
body,
.topbar .topbar-main {
background-color: #202225;
color: #d3d3d3;
}
.topbar .topbar-main {
padding-left: 0 !important;
}
.topbar .topbar-main button.topbarbtn {
background-color: #484848;
color: #020202;
}
.scrolled .topbar {
box-shadow: none;
}
.scrolled .topbar-main {
box-shadow: 0 3px 6px 0 #000000AA;
}
main.bd-content {
padding-left: 0 !important;
}
main.bd-content > #main-content {
margin: 0;
padding: 0;
}
main.bd-content > #main-content > div {
background: #333;
flex: 1;
max-width: calc(100% - 18vw + 15px);
padding: 20px 25px !important;
}
#site-navigation {
background-color: #202225;
border: none;
overflow: hidden;
}
#site-navigation:hover {
overflow-y: scroll;
padding-right: 7px;
}
#site-navigation::-webkit-scrollbar {
width: 8px;
}
#site-navigation::-webkit-scrollbar-track {
background: #202225;
}
#site-navigation::-webkit-scrollbar-thumb,
#site-navigation::-webkit-scrollbar-thumb:vertical {
background: #000;
}
#navbar-toggler {
background: #484848;
color: #020202;
height: calc(100% - 3px);
min-width: 40px;
}
#navbar-toggler:focus, #navbar-toggler:hover {
background: #666;
outline: none;
}
#navbar-toggler i {
left: 9px;
top: 5px;
}
.topbar div.dropdown-buttons-trigger:hover > button {
background: #666;
}
.topbar div.dropdown-buttons-trigger div.dropdown-buttons {
max-width: inherit;
transform: inherit;
}
.topbar div.dropdown-buttons-trigger:hover div.dropdown-buttons {
background: #505050;
border-radius: 6px;
display: flex;
flex-direction: column;
padding: 2px 0;
}
.topbar div.dropdown-buttons-trigger:hover div.dropdown-buttons button.topbarbtn {
border: none !important;
color: #ccc;
margin: 2px 4px;
min-width: 130px !important;
text-align: left;
white-space: nowrap;
width: fill-available;
width: -moz-fill-available;
width: -webkit-fill-available;
}
.topbar div.dropdown-buttons-trigger:hover div.dropdown-buttons button.topbarbtn:hover {
background: #ffffff33;
}
.topbar div.dropdown-buttons-trigger:hover div.dropdown-buttons button.topbarbtn.selected {
background: #ffffff22;
color: #fff;
outline: 1px solid #777;
}
.topbar-main button.topbarbtn.btn-secondary:focus,
.topbar-main button.topbarbtn.btn-secondary:active:focus {
box-shadow: none;
}
#versions-menu button span.tag {
font-size: 75%;
}
.navbar_extra_footer {
display: none;
}
div.navbar-brand-box {
padding: .5em 0 1em 0;
}
div.navbar-brand-box a.navbar-brand {
display: flex;
align-items: center;
}
div.navbar-brand-box a.navbar-brand img {
max-width: 100%;
margin: 0;
}
pre {
background: #424242;
border: none;
box-shadow: 0px 0px 3px black;
color: #888;
position: relative;
}
code {
background-color: #282828;
border-radius: 3pt;
color: #FFC479;
padding: 2pt 3pt;
}
div[class^="highlight-"] pre:before {
background: black;
border-bottom-left-radius: 5px;
border-top-right-radius: 5px;
color: #58d0ff;
font-size: 80%;
padding: 1px 8px;
position: absolute;
right: 0;
top: 0;
}
div.highlight-console pre:before {
content: "bash";
color: #666;
}
div.highlight-dart pre:before {
content: "dart";
}
div.highlight-yaml pre:before {
content: "yaml";
color: #5f5;
}
div.highlight-text pre:before {
content: "text";
color: #666;
}
/* Cancel some of the existing styles */
#site-navigation nav ul.nav li a, #site-navigation nav ul.nav ul li a {
color: rgba(var(--pst-color-sidebar-link), 1);
}
#site-navigation nav ul.nav a:hover, #site-navigation nav ul.nav li.active>a, #site-navigation nav ul.nav li.active>a:hover {
color: rgba(var(--pst-color-sidebar-link-active), 1);
}
div.bd-toc.show {
background: #202225;
flex: initial;
max-width: 18vw;
width: 18vw;
}
.bd-toc div.onthispage, .bd-toc .toc-entry a {
border: none;
color: rgba(var(--pst-color-toc-link), 1);
}
.bd-toc nav {
background: inherit;
overflow-x: clip;
}
.bd-toc nav > .nav {
border: none;
}
nav.bd-links p.caption {
margin-bottom: 0.2em;
}
main.bd-content #main-content h1 {
color: rgba(var(--pst-color-h1), 1);
}
main.bd-content #main-content h2 {
color: rgba(var(--pst-color-h2), 1);
}
main.bd-content #main-content h3 {
color: rgba(var(--pst-color-h3), 1);
}
main.bd-content #main-content h4 {
color: rgba(var(--pst-color-h4), 1);
}
main.bd-content #main-content h5 {
color: rgba(var(--pst-color-h5), 1);
}
#site-navigation h1.site-logo {
color: rgba(var(--pst-color-h1), 1);
}
.form-control {
background-color: transparent;
}
.topbar {
background-color: #3a3a3a;
}
.tocsection {
border-color: black;
}
.bd-sidebar .nav li>a {
padding: .1rem 1.5rem;
}
footer.footer {
border: none;
font-size: 85%;
font-style: italic;
opacity: 30%;
}
/* Search-related elements */
form.bd-search #search-input {
border-bottom-color: #ffe689;
color: #ffe689;
opacity: 50%;
}
form.bd-search #search-input:focus {
background: none;
border-bottom: none;
border-radius: 6px;
box-shadow: 0 0 5px 1px #ffe689;
opacity: 1.0;
}
form.bd-search i.icon.fa-search {
color: #a99a2f;
}
form.bd-search:focus-within .form-control::placeholder,
form.bd-search:focus-within i.icon.fa-search {
opacity: 25%;
}
.highlighted {
background: #ffe000;
color: black;
padding: 2px 4px;
border-radius: 4px;
}
h1#search-documentation,
h1#search-documentation ~ p,
h1#search-documentation ~ form,
h1#search-documentation ~ noscript {
display: none;
}
p.search-summary {
opacity: 35%;
}
div#search-results > h2 {
margin-top: 0;
}
/* Previous/next buttons */
main.bd-content #main-content .prev-next-area {
background: #202225;
height: 105px;
margin: 0 -25px -20px -25px;
padding: 20px 0;
}
main.bd-content #main-content .prev-next-area a.left-prev {
border-radius: 100px 0 0 100px;
padding-left: 15px;
padding-right: 20px;
}
main.bd-content #main-content .prev-next-area a.right-next {
border-radius: 0 100px 100px 0;
padding-left: 20px;
padding-right: 15px;
}
main.bd-content #main-content .prev-next-area a.left-prev > i,
main.bd-content #main-content .prev-next-area a.right-next > i {
font-size: 200%;
}
main.bd-content #main-content .prev-next-area a.right-next .prevnext-label,
main.bd-content #main-content .prev-next-area a.left-prev .prevnext-label {
color: #808080;
}
main.bd-content #main-content .prev-next-area a.right-next:hover .prevnext-label,
main.bd-content #main-content .prev-next-area a.left-prev:hover .prevnext-label {
color: #BBB;
}
main.bd-content #main-content .prev-next-area a.right-next:hover .prevnext-title,
main.bd-content #main-content .prev-next-area a.left-prev:hover .prevnext-title {
color: #8CE4FF;
}
main.bd-content #main-content .prev-next-area a.left-prev:hover,
main.bd-content #main-content .prev-next-area a.right-next:hover {
background: #484848;
box-shadow: 1px 1px 2px #000;
text-decoration: none;
}
main.bd-content #main-content .prev-next-area a:hover p.prev-next-title {
text-decoration: none;
}

View File

@ -0,0 +1,327 @@
/*
* Originally from:
* -----------------------------------------------------------------------------
* doctools.js
* ~~~~~~~~~~~
*
* Sphinx JavaScript utilities for all documentation.
*
* :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
* -----------------------------------------------------------------------------
*/
/**
* select a different prefix for underscore
*/
$u = _.noConflict();
/**
* make the code below compatible with browsers without
* an installed firebug like debugger
if (!window.console || !console.firebug) {
var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
"dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
"profile", "profileEnd"];
window.console = {};
for (var i = 0; i < names.length; ++i)
window.console[names[i]] = function() {};
}
*/
/**
* small helper function to urldecode strings
*/
jQuery.urldecode = function(x) {
return decodeURIComponent(x).replace(/\+/g, ' ');
};
/**
* small helper function to urlencode strings
*/
jQuery.urlencode = encodeURIComponent;
/**
* This function returns the parsed url parameters of the
* current request. Multiple values per key are supported,
* it will always return arrays of strings for the value parts.
*/
jQuery.getQueryParameters = function(s) {
if (typeof s === 'undefined')
s = document.location.search;
var parts = s.substr(s.indexOf('?') + 1).split('&');
var result = {};
for (var i = 0; i < parts.length; i++) {
var tmp = parts[i].split('=', 2);
var key = jQuery.urldecode(tmp[0]);
var value = jQuery.urldecode(tmp[1]);
if (key in result)
result[key].push(value);
else
result[key] = [value];
}
return result;
};
/**
* highlight a given string on a jquery object by wrapping it in
* span elements with the given class name.
*/
jQuery.fn.highlightText = function(text, className, index) {
function highlight(node, addItems) {
if (node.nodeType === 3) {
var val = node.nodeValue;
var pos = val.toLowerCase().indexOf(text);
if (pos >= 0 &&
!jQuery(node.parentNode).hasClass(className) &&
!jQuery(node.parentNode).hasClass("nohighlight")) {
var span;
var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg");
if (isInSVG) {
span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
} else {
span = document.createElement("span");
span.className = className + " i" + index;
}
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
node.parentNode.insertBefore(span, node.parentNode.insertBefore(
document.createTextNode(val.substr(pos + text.length)),
node.nextSibling));
node.nodeValue = val.substr(0, pos);
if (isInSVG) {
var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
var bbox = node.parentElement.getBBox();
rect.x.baseVal.value = bbox.x;
rect.y.baseVal.value = bbox.y;
rect.width.baseVal.value = bbox.width;
rect.height.baseVal.value = bbox.height;
rect.setAttribute('class', className);
addItems.push({
"parent": node.parentNode,
"target": rect});
}
}
}
else if (!jQuery(node).is("button, select, textarea")) {
jQuery.each(node.childNodes, function() {
highlight(this, addItems);
});
}
}
var addItems = [];
var result = this.each(function() {
highlight(this, addItems);
});
for (var i = 0; i < addItems.length; ++i) {
jQuery(addItems[i].parent).before(addItems[i].target);
}
return result;
};
/*
* backward compatibility for jQuery.browser
* This will be supported until firefox bug is fixed.
*/
if (!jQuery.browser) {
jQuery.uaMatch = function(ua) {
ua = ua.toLowerCase();
var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
/(webkit)[ \/]([\w.]+)/.exec(ua) ||
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
/(msie) ([\w.]+)/.exec(ua) ||
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
[];
return {
browser: match[ 1 ] || "",
version: match[ 2 ] || "0"
};
};
jQuery.browser = {};
jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;
}
/**
* Small JavaScript module for the documentation.
*/
var Documentation = {
init : function() {
this.fixFirefoxAnchorBug();
this.highlightSearchWords();
this.initIndexTable();
if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) {
this.initOnKeyListeners();
}
},
/**
* i18n support
*/
TRANSLATIONS : {},
PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; },
LOCALE : 'unknown',
// gettext and ngettext don't access this so that the functions
// can safely bound to a different name (_ = Documentation.gettext)
gettext : function(string) {
var translated = Documentation.TRANSLATIONS[string];
if (typeof translated === 'undefined')
return string;
return (typeof translated === 'string') ? translated : translated[0];
},
ngettext : function(singular, plural, n) {
var translated = Documentation.TRANSLATIONS[singular];
if (typeof translated === 'undefined')
return (n == 1) ? singular : plural;
return translated[Documentation.PLURALEXPR(n)];
},
addTranslations : function(catalog) {
for (var key in catalog.messages)
this.TRANSLATIONS[key] = catalog.messages[key];
this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
this.LOCALE = catalog.locale;
},
/**
* add context elements like header anchor links
*/
addContextElements : function() {
$('div[id] > :header:first').each(function() {
$('<a class="headerlink">\u00B6</a>').
attr('href', '#' + this.id).
attr('title', _('Permalink to this headline')).
appendTo(this);
});
$('dt[id]').each(function() {
$('<a class="headerlink">\u00B6</a>').
attr('href', '#' + this.id).
attr('title', _('Permalink to this definition')).
appendTo(this);
});
},
/**
* workaround a firefox stupidity
* see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075
*/
fixFirefoxAnchorBug : function() {
if (document.location.hash && $.browser.mozilla)
window.setTimeout(function() {
document.location.href += '';
}, 10);
},
/**
* highlight the search words provided in the url in the text
*/
highlightSearchWords : function() {
var params = $.getQueryParameters();
var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
if (terms.length) {
var body = $('div[role="main"]');
if (!body.length) {
body = $('body');
}
var hbox = $("#highlight-content");
window.setTimeout(function() {
$.each(terms, function(i) {
var text = this.toLowerCase();
body.highlightText(text, 'highlighted', i);
hbox.append($('<span>' + text + '</span>').click(function(){
$(this).toggleClass("off");
Documentation.toggleSearchWord(i);
}));
});
}, 10);
$("div.highlight-box").show();
$("div.highlight-box button.close").click(Documentation.hideSearchWords);
}
},
/**
* init the domain index toggle buttons
*/
initIndexTable : function() {
var togglers = $('img.toggler').click(function() {
var src = $(this).attr('src');
var idnum = $(this).attr('id').substr(7);
$('tr.cg-' + idnum).toggle();
if (src.substr(-9) === 'minus.png')
$(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
else
$(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
}).css('display', '');
if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
togglers.click();
}
},
toggleSearchWord : function(i) {
$('span.highlighted.i' + i).toggleClass('off');
},
/**
* helper function to hide the search marks again
*/
hideSearchWords : function() {
$('span.highlighted').removeClass('highlighted');
$("div.highlight-box").fadeOut(300);
},
/**
* make the url absolute
*/
makeURL : function(relativeURL) {
return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
},
/**
* get the current relative url
*/
getCurrentURL : function() {
var path = document.location.pathname;
var parts = path.split(/\//);
$.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
if (this === '..')
parts.pop();
});
var url = parts.join('/');
return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
},
initOnKeyListeners: function() {
$(document).keydown(function(event) {
var activeElementType = document.activeElement.tagName;
// don't navigate when in search box or textarea
if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT'
&& !event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey) {
switch (event.keyCode) {
case 37: // left
var prevHref = $('link[rel="prev"]').prop('href');
if (prevHref) {
window.location.href = prevHref;
return false;
}
case 39: // right
var nextHref = $('link[rel="next"]').prop('href');
if (nextHref) {
window.location.href = nextHref;
return false;
}
}
}
});
}
};
// quick alias for translations
_ = Documentation.gettext;
$(document).ready(function() {
Documentation.init();
});

View File

@ -0,0 +1,703 @@
:root {
--document-width: 900px;
--document-x-margin: clamp(10px, 2.5vw, 30px);
--document-padding: min(40px, 4vw);
--font-sans: 'Ubuntu', Roboto, Helvetica Neue, Arial, sans-serif;
--font-mono: "SF Mono", Menlo, monospace;
--font-awesome: 'Font Awesome 5 Solid';
--highlight-color: 255, 233, 92;
--left-menu-width: clamp(250px, 25vw, 330px);
--right-menu-width: 240px;
--top-menu-height: 50px;
color-scheme: dark; /* makes scrollbars dark */
}
@media (max-width: 900px) {
:root {
--left-menu-width: min(320px, 80vw);
}
}
body {
background-color: #484848;
color: #b8b8b8;
font-family: var(--font-sans);
font-size: 15px;
line-height: 1.5;
margin: 0;
padding: 0;
position: relative; /* needed by Scrollspy */
text-align: left;
}
a {
color: #ffbb3e;
text-decoration: none;
}
a:hover {
color: #ddbb99;
}
a.reference.external::after {
content: "\f35d";
font-family: var(--font-awesome);
font-size: 60%;
opacity: 60%;
padding-left: 2px;
position: relative;
top: -5px;
}
code {
background-color: #181818;
border-radius: 3pt;
color: #8b9fb1;
font-family: var(--font-mono);
font-size: 85%;
padding: 2pt 3pt;
}
p {
margin-top: 0;
}
div.expander {
flex: 1;
}
/*----------------------------------------------------------------------------*
* Top navigation bar
*----------------------------------------------------------------------------*/
div.top-bar {
align-items: center;
background: #303030;
box-shadow: 0px 3px 7px #00000066, 0 1px 2px #000000bf;
box-sizing: border-box;
display: flex;
height: var(--top-menu-height);
margin-left: auto;
margin-right: auto;
padding: 5px 15px;
position: fixed;
top: 0;
width: 100%;
z-index: 100;
}
div.top-bar .logo_image img {
height: calc(var(--top-menu-height) * 0.65);
position: relative;
top: 3px; /* correct for logo having slightly asymmetrical spacing */
}
div.top-bar .btn {
align-items: center;
background-color: transparent;
border: none;
border-radius: 0.25rem;
color: #ffd78d;
cursor: pointer;
display: inline-flex;
font-size: 1rem;
font-weight: 400;
height: 40px;
justify-content: center;
transition: color .15s ease-in-out, background-color .15s ease-in-out;
user-select: none;
width: 40px;
}
div.top-bar .btn:hover {
background-color: #b7b7b740;
}
div.top-bar #github-button,
div.top-bar #discord-button {
font-size: 1.4em;
}
div.top-bar #menu-button {
display: none;
}
@media (max-width: 900px) {
div.top-bar #menu-button {
display: inline-block;
margin-left: -8px;
margin-right: 8px;
}
div.top-bar #menu-button.active {
background-color: #8d7a39;
}
}
/*----------------------------------------------------------------------------*
* Version menu
*----------------------------------------------------------------------------*/
#versions-menu {
position: relative;
}
#versions-menu > .btn {
padding: 0 8px;
width: auto;
}
#versions-menu.active > .btn {
background-color: #8d7a39;
}
#versions-menu > .btn > .version-id {
color: #ffe95c;
font-weight: bold;
padding: 0 0 0 6px;
}
#versions-menu > .dropdown-buttons {
display: none;
}
#versions-menu.active > .dropdown-buttons {
background: #383838;
border-radius: 4px;
box-shadow: 1px 1px 4px black;
box-sizing: border-box;
display: flex;
flex-direction: column;
padding: 4px;
position: absolute;
right: 0;
top: calc(var(--top-menu-height) - 4px);
}
#versions-menu.active > .dropdown-buttons .header {
font-size: 80%;
font-style: italic;
min-width: 200px;
opacity: 0.6;
}
#versions-menu.active > .dropdown-buttons > a > button {
justify-content: flex-start;
min-width: 60px;
width: fill-available;
width: -moz-fill-available;
width: -webkit-fill-available;
}
#versions-menu.active > .dropdown-buttons > a > button > i.fa {
padding-right: 6px;
}
/*----------------------------------------------------------------------------*
* Left sidebar area
*----------------------------------------------------------------------------*/
div.sidebar-left-bg {
background: #383838;
bottom: 0;
box-shadow: 2px 0 4px #000000a1;
contain: strict;
position: fixed;
top: 0;
width: var(--left-menu-width);
z-index: 50;
}
div.sidebar-left {
bottom: 0;
box-sizing: border-box;
overflow: hidden;
padding: 10px 0 0 12px;
position: fixed;
top: calc(var(--top-menu-height) + 10px);
width: var(--left-menu-width);
z-index: 60;
}
div.sidebar-left:hover {
overflow-y: auto;
}
/* On small displays the sidebar becomes hidden and can be toggled via a menu
button. */
@media (max-width: 900px) {
div.sidebar-left-area {
position: absolute;
left: calc(0px - var(--left-menu-width));
transition: left 0.3s;
}
div.sidebar-left-area:not(.active) .sidebar-left-bg {
box-shadow: none;
}
div.sidebar-left-area.active {
left: 0;
}
}
#search-form {
position: relative;
margin: 0;
padding: 12px 12px 12px 0;
}
#search-form #search-input {
background: #2c2c2c;
border: none;
border-radius: 6px;
color: #ffe689;
height: calc(1.5em + 0.75rem + 2px);
line-height: 1.5;
opacity: 50%;
padding: 0.375rem 0.75rem 0.375rem 35px;
width: 100%;
}
#search-form #search-input:focus {
background: #303030;
border-bottom: none;
box-shadow: inset 0 0 5px 1px #1c1c1c;
opacity: 1.0;
outline: none;
}
#search-form i.icon.fa-search {
color: #a99a2f;
left: 9px;
position: absolute;
top: 21px;
}
#search-form:focus-within .form-control::placeholder,
#search-form:focus-within i.icon.fa-search {
opacity: 50%;
}
div.nav-left {
margin-bottom: 70px;
}
div.nav-left ul {
display: none;
padding: 0 0 0 16px;
}
div.nav-left ul.current,
div.nav-left > ul {
display: block;
}
div.nav-left li {
list-style-type: none;
position: relative;
margin: 0;
}
div.nav-left li > a {
border-radius: 5px 0 0 5px;
color: #9d9175;
display: block;
font-size: 13px;
margin-left: -15px;
padding: 2px 0 2px 15px;
text-decoration: none;
}
div.nav-left li > a:hover {
background-color: #303030;
}
div.nav-left li > a:not(:only-child)::before {
color: #ffbb3e;
content: "\f0da";
font-family: var(--font-awesome);
font-size: 70%;
font-weight: 900;
left: -9px;
position: absolute;
top: 5px;
}
div.nav-left li > a:not(:only-child):not(.current):hover::before {
color: #fff;
}
div.nav-left li.current > ul {
display: block;
}
div.nav-left li.current > a.current {
background: #222;
color: #aaa;
margin-left: -14px;
padding-left: 15px;
position: relative;
z-index: 40;
}
div.nav-left li.current > a:not(:only-child)::before {
content: "\f0d7";
left: -10px;
}
div.nav-left li.current > a.current:not(:only-child)::before {
left: 4px;
}
div.nav-left li.current > ul {
display: block;
}
/*----------------------------------------------------------------------------*
* Right sidebar area
*----------------------------------------------------------------------------*/
div.sidebar-right {
flex: 5;
height: calc(100vh - 25px - var(--top-menu-height));
margin-right: 20px;
max-width: var(--right-menu-width);
position: sticky;
top: calc(25px + var(--top-menu-height));
}
@media (max-width: 1200px) {
div.sidebar-right {
display: none;
}
}
div.nav-right > #toc-local {
display: flex;
flex-direction: column;
margin: 0 0 0 6px;
max-width: var(--right-menu-width);
padding: 0 0 0 10px;
}
div.nav-right > #toc-local > div.header {
font-weight: bold;
white-space: nowrap;
}
div.nav-right > #toc-local > a.list-group-item {
border: none;
border-left: 4px solid transparent;
color: #9d9175;
display: block;
font-size: 13px;
line-height: 1.2;
list-style-type: none;
padding: 4px 0 4px 6px;
text-decoration: none;
margin-left: -9px;
}
div.nav-right > #toc-local > a.list-group-item.level-2 {
padding-left: 15px;
padding-top: 0px;
font-size: 12px;
}
div.nav-right > #toc-local > a.list-group-item.active {
border-left-color: #4684b6;
color: #212529;
}
div.nav-right > #toc-local > a.list-group-item:hover {
color: white;
text-decoration: none;
}
/*----------------------------------------------------------------------------*
* Main area
*----------------------------------------------------------------------------*/
body > div.main-area {
display: flex;
margin-bottom: 0;
margin-left: var(--left-menu-width);
margin-right: 0;
margin-top: var(--top-menu-height);
min-height: calc(100vh - var(--top-menu-height));
}
@media (max-width: 900px){
body > div.main-area {
margin-left: 0;
}
body > div.main-area > div.document-wrapper {
margin: 0;
}
body > div.main-area > div.expander {
display: none;
}
}
div.document-wrapper {
flex: 25;
max-width: var(--document-width);
min-width: min(95vw, calc(var(--document-width) * 2/3));
margin-bottom: 25px;
margin-left: var(--document-x-margin);
margin-top: 25px;
}
div.document {
background-color: #282828;
color: #c0c0c0;
border-radius: 2pt;
box-shadow: 2px 2px 3px 0 #000;
padding: var(--document-padding);
}
div.copyright {
font-size: 12px;
margin-top: 3px;
opacity: 0.5;
}
div.document h1 {
border-bottom: 1px solid #555;
color: #ccc;
font-size: 2em;
font-weight: bold;
margin: 0 0 0.6em 0;
}
div.document h2 {
font-size: 1.5em;
margin: 1.5em 0 .5em 0;
}
div.document h3 {
font-size: 1.25em;
margin: 1.3em 0 .5em 0;
}
div.document :is(h1, h2, h3, h4) > a.headerlink {
display: none;
font-size: 60%;
visibility: hidden;
}
div.document :is(h1, h2, h3, h4) > a.headerlink::after {
content: "\f0c1";
font-family: var(--font-awesome);
left: -3px;
position: relative;
top: -2px;
visibility: visible;
}
div.document :is(h1, h2, h3, h4):hover > a.headerlink {
display: initial;
}
div.document :is(h1, h2, h3, h4) > code {
background: none;
color: inherit;
padding: 0;
}
/*----------------------------------------------------------------------------*
* Previous/next buttons
*----------------------------------------------------------------------------*/
.prev-next-area {
display: flex;
padding: 20px 0;
}
.prev-next-area > a {
align-items: center;
color: #bbb;
display: flex;
padding: 10px;
max-width: 45%;
overflow-x: hidden;
}
.prev-next-area > a.left-prev {
border-radius: 100px 0 0 100px;
padding-left: 15px;
}
.prev-next-area > a.right-next {
border-radius: 0 100px 100px 0;
padding-right: 15px;
}
.prev-next-area > a:hover {
background: #323232;
box-shadow: 1px 1px 2px #000;
}
.prev-next-area > a > i {
font-size: 200%;
font-weight: bold;
}
.prev-next-area > a > .prev-next-info {
flex-direction: column;
margin: 0 0.5em;
}
.prev-next-area > a > .prev-next-info > p {
margin: 0 0.3em;
line-height: 1.3em;
}
.prev-next-area > a > .prev-next-info > p.prev-next-subtitle {
color: #888;
}
.prev-next-area > a:hover > .prev-next-info > p.prev-next-title {
color: #8CE4FF;
}
/*----------------------------------------------------------------------------*
* Code
*----------------------------------------------------------------------------*/
pre {
background: #202020;
border: none;
border-radius: 0.4em;
box-shadow: 0px 0px 3px black;
color: #888;
font-size: 85%;
line-height: 125%;
margin: 0;
padding: 10px;
position: relative;
}
div[class^="highlight-"] pre:before {
background: black;
border-bottom-left-radius: 5px;
border-top-right-radius: 5px;
color: #58d0ff;
font-size: 80%;
padding: 1px 8px;
position: absolute;
right: 0;
top: 0;
}
div.highlight-console pre:before {
content: "bash";
color: #666;
}
div.highlight-dart pre:before {
content: "dart";
}
div.highlight-yaml pre:before {
content: "yaml";
color: #5f5;
}
div.highlight-text pre:before {
content: "text";
color: #666;
}
/*----------------------------------------------------------------------------*
* Search elements
*----------------------------------------------------------------------------*/
/* On the search page the first header is H2 instead of H1 */
div#search-results > h2 {
margin-top: 0;
}
p.search-summary {
opacity: 35%;
}
span.highlighted {
background: inherit; /* undo style from basic.css */
}
span.highlighted:not(.off) {
background: #ffe000;
color: black;
padding: 2px 4px;
border-radius: 4px;
}
div.highlight-box {
background: black linear-gradient(rgba(var(--highlight-color), 100%),
rgba(var(--highlight-color), 85%),
rgba(var(--highlight-color), 50%));
border: 1px solid #5a441b;
border-style: none solid;
box-sizing: border-box;
display: flex;
height: 100%;
left: calc(var(--left-menu-width) + var(--document-x-margin));
margin: 0;
padding: 3px 8px;
position: absolute;
top: 0;
}
@media (max-width: 900px) {
div.highlight-box {
left: 54px;
}
}
div.highlight-box div.title {
color: rgba(0, 0, 0, 0.7);
font-size: 12px;
font-variant: small-caps;
line-height: 16px;
opacity: 0.5;
}
div.highlight-box div.content {
display: flex;
}
div.highlight-box div.content > span {
background: rgb(var(--highlight-color));
border: 1px solid rgba(0, 0, 0, 0.6);
border-radius: 6px;
color: #000;
cursor: pointer;
margin-right: 4px;
padding: 1px 6px 2px 6px;
user-select: none;
}
div.highlight-box div.content > span.off {
background: none;
border-style: dashed;
}
div.highlight-box button.close {
background: transparent;
border: none;
color: black;
cursor: pointer;
font-size: 20px;
margin: 0 0 0 20px;
}

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,152 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>{{ title|striptags|e + " &#8212; "|safe + docstitle|e }}</title>
{%- block css %}
<!-- Stylesheets -->
{%- for css in css_files %}
{{ css_tag(css) }}
{%- endfor %}
{%- endblock %}
{%- block scripts %}
<!-- Scripts -->
{%- for js in script_files %}
{{ js_tag(js) }}
{%- endfor %}
<!--script src="searchindex.js" defer></script-->
{%- endblock %}
{%- block links %}
<!-- Links -->
{%- if pageurl %}
<link rel="canonical" href="{{ pageurl|e }}" />
{%- endif %}
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Ubuntu:ital,wght@0,400;0,700;1,400;1,700&display=swap">
<link rel="preload" as="font" type="font/woff2" crossorigin="" href="{{ pathto('_static/fontawesome/fa-brands-400.woff2', 1) }}">
<link rel="preload" as="font" type="font/woff2" crossorigin="" href="{{ pathto('_static/fontawesome/fa-solid-900.woff2', 1) }}">
<link rel="stylesheet" href="{{ pathto('_static/fontawesome/all.min.css', 1) }}">
<link rel="shortcut icon" href="{{ pathto('_static/favicon.ico', 1)|e }}"/>
{%- if hasdoc('genindex') %}
<link rel="index" title="{{ _('Index') }}" href="{{ pathto('genindex') }}" />
{%- endif %}
{%- if hasdoc('search') %}
<link rel="search" title="{{ _('Search') }}" href="{{ pathto('search') }}" />
{%- endif %}
{%- if hasdoc('copyright') %}
<link rel="copyright" title="{{ _('Copyright') }}" href="{{ pathto('copyright') }}" />
{%- endif %}
{%- if next %}
<link rel="next" title="{{ next.title|striptags|e }}" href="{{ next.link|e }}" />
{%- endif %}
{%- if prev %}
<link rel="prev" title="{{ prev.title|striptags|e }}" href="{{ prev.link|e }}" />
{%- endif %}
{%- endblock %}
</head>
<body data-spy="scroll" data-target="#toc-local" data-offset="80">
<div class="top-bar">
<button id="menu-button" class="btn" title="Toggle menu"><i class="fa fa-bars"></i></button>
<script type="text/javascript">
jQuery(function(){
$("#menu-button").click(function() {
$(this).toggleClass("active");
$(".sidebar-left-area").toggleClass("active");
});
});
</script>
<a href="{{pathto('index')}}" class="logo_image">
<img src="{{pathto('_static/logo_flame.png', 1)}}">
</a>
<div class="highlight-box" role="alert" style="display:none">
<div>
<div class="title">highlighted:</div>
<div class="content" id="highlight-content"></div>
</div>
<button type="button" class="close" data-dismiss="alert" aria-label="Dismiss">×</button>
</div>
<div class="expander"></div>
<div class="versions-placeholder"></div>
<a href="https://discord.com/channels/509714518008528896/516639688581316629" id="discord-button"
class="btn" title="Flame Discord channel">
<i class="fab fa-discord"></i>
</a>
<a href="https://github.com/flame-engine/flame/" id="github-button" class="btn"
title="GitHub repository">
<i class="fab fa-github"></i>
</a>
</div>
<div class="sidebar-left-area">
<div class="sidebar-left-bg"></div>
<div class="sidebar-left">
<div class="searchbox" role="search">
<form id="search-form" action="{{ pathto('search') }}" method="get">
<i class="icon fa fa-search"></i>
<input type="search" class="form-control" id="search-input" name="q"
placeholder="Search the docs..." autocomplete="off" />
</form>
</div>
<div class="nav-left" role="navigation" aria-label="Main">
{{ toctree(maxdepth=0, collapse=False, includehidden=True, titles_only=True) }}
</div>
</div>
</div>
<div class="main-area">
<div class="document-wrapper">
<div class="document" role="main">
{% block body %} {% endblock %}
</div>
<div class="copyright">
The content on this page is licensed under the <a href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0 License</a>,
and code samples under the <a href="https://raw.githubusercontent.com/flame-engine/flame/main/LICENSE">MIT License</a>.
</div>
<div class="prev-next-area">
{%- if prev %}
<a class="left-prev" id="prev-link" href="{{ prev.link|e }}" title="previous page">
<i class="fa fa-angle-left"></i>
<div class="prev-next-info">
<p class="prev-next-subtitle">Previous:</p>
<p class="prev-next-title">{{ prev.title|striptags|e }}</p>
</div>
</a>
{%- endif %}
<div class='expander'></div>
{%- if next %}
<a class="right-next" id="next-link" href="{{ next.link|e }}" title="next page">
<div class="prev-next-info">
<p class="prev-next-subtitle">Next:</p>
<p class="prev-next-title">{{ next.title|striptags|e }}</p>
</div>
<i class="fa fa-angle-right"></i>
</a>
{%- endif %}
</div>
</div>
<div class="sidebar-right">
{# Local table of contents #}
<div class="nav-right" role="navigation" aria-label="table of contents">
{{ get_local_toc() }}
</div>
</div>
<div class="expander"></div>
</div>
{% block footer %}
{% endblock %}
</body>
</html>

View File

@ -0,0 +1,38 @@
{#
basic/search.html
~~~~~~~~~~~~~~~~~
Template for the search page.
:copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
#}
{%- extends "layout.html" %}
{% set title = 'Search' %}
{%- block scripts %}
{{ super() }}
<script type="text/javascript" src="{{ pathto('_static/searchtools.js', 1) }}"></script>
<script type="text/javascript" src="{{ pathto('_static/language_data.js', 1) }}"></script>
{%- endblock %}
{% block footer %}
<script type="text/javascript">
jQuery(function() { Search.loadIndex("{{ pathto('searchindex.js', 1) }}"); });
</script>
{# this is used when loading the search index using $.ajax fails,
such as on Chrome for documents on localhost #}
<script type="text/javascript" id="searchindexloader"></script>
{{ super() }}
{% endblock %}
{% block body %}
<noscript>
<div id="fallback" class="alert alert-info">
Please turn on JavaScript to enable the search functionality.
</div>
</noscript>
<div id="search-results">
</div>
{% endblock %}

View File

@ -0,0 +1,12 @@
[theme]
inherit = basic
style = flames.css
pygments_style = sphinx
[options]
logo =
collapse_navigation = True
sticky_navigation = True
navigation_depth = 4
includehidden = True
titles_only =

View File

@ -209,7 +209,7 @@ screen in both x and y axis, so for our first item in our list (`Vector2(0, 1)`)
on the middle of the top wall of the bounding box, since the coordinate system here is defined from
the center of the polygon.
![An example of how to define a polygon shape](images/polygon_shape.png)
![An example of how to define a polygon shape](../images/polygon_shape.png)
In the image you can see how the polygon shape formed by the purple arrows is defined by the red
arrows.

View File

@ -1,6 +1,6 @@
# Components
![Component tree](images/component_tree.png)
![Component tree](../images/component_tree.png)
This diagram might look intimidating, but don't worry, it is not as complex as it looks.
@ -14,7 +14,7 @@ Every `Component` has a few methods that you can optionally implement, which are
`FlameGame` class. If you are not using `FlameGame`, you can use these methods on your own game loop
if you wish.
![Component Lifecycle Diagram](images/component_lifecycle.png)
![Component Lifecycle Diagram](../images/component_lifecycle.png)
The `onGameResize` method is called whenever the screen is resized, and once in the beginning when
the component is added to the game via the `add` method.
@ -103,8 +103,8 @@ performance benefits to gain from it. The `register` call is usually done in `on
Example:
```dart
Future<void> onLoad async {
await super.onLoad();
@override
Future<void> onLoad() async {
children.register<PositionComponent>();
}
```
@ -113,6 +113,7 @@ In the example above a query is registered for `PositionComponent`s, and an exam
the registered component type can be seen below.
```dart
@override
void update(double dt) {
final allPositionComponents = components.query<PositionComponent>();
}
@ -185,7 +186,7 @@ that the `position`, `angle` and `scale` will be relative to the parents state.
So if you, for example, wanted to position a child 50 logical pixels above the center of the parent
you would do this:
```
```dart
final parent = PositionComponent(
position: Vector2(100, 100),
size: Vector2(100, 100),
@ -261,7 +262,7 @@ this.player = SpriteAnimationComponent(
```
If you have a sprite sheet, you can use the `sequenced` constructor from the `SpriteAnimationData`
class (check more details on [Images &gt; Animation](images.md#Animation)):
class (check more details on [Images &gt; Animation](rendering/images.md#animation)):
```dart
final size = Vector2.all(64.0);
@ -628,7 +629,7 @@ final diamond = PolygonComponent.fromPoints(vertices);
## SpriteBodyComponent
See [SpriteBodyComponent](forge2d.md#SpriteBodyComponent) in the Forge2D documentation.
See [SpriteBodyComponent](../other_modules/forge2d.md#spritebodycomponent) in the Forge2D documentation.
## TiledComponent
@ -664,11 +665,11 @@ planes of each cuboid in your tile. Basically, it's the height of the front-most
cuboid; normally it's half (default) or a quarter of the tile size. On the image below you can see
the height colored in the darker tone:
![An example of how to determine the tileHeight](images/tile-height-example.png)
![An example of how to determine the tileHeight](../images/tile-height-example.png)
This is an example of how a quarter-length map looks like:
![An example of a isometric map with selector](images/isometric.png)
![An example of a isometric map with selector](../images/isometric.png)
Flame's Example app contains a more in-depth example, featuring how to parse coordinates to make a
selector. The code can be found

View File

@ -62,7 +62,7 @@ There are multiple effect controllers provided by the Flame framework as well:
- [`SequenceEffectController`](#sequenceeffectcontroller)
- [`SpeedEffectController`](#speedeffectcontroller)
- [`DelayedEffectController`](#delayedeffectcontroller)
- [`NoiseEffectController`](#noiseffectcontroller)
- [`NoiseEffectController`](#noiseeffectcontroller)
- [`RandomEffectController`](#randomeffectcontroller)
- [`SineEffectController`](#sineeffectcontroller)
- [`ZigzagEffectController`](#zigzageffectcontroller)

17
doc/flame/flame.md Normal file
View File

@ -0,0 +1,17 @@
# flame
```{eval-rst}
.. toctree::
:hidden:
File structure <structure.md>
Game loop <game.md>
Components <components.md>
Platforms <platforms.md>
Collision detection <collision_detection.md>
Effects <effects.md>
Camera & Viewport <camera_and_viewport.md>
Inputs <inputs/inputs.md>
Rendering <rendering/rendering.md>
Other <other/other.md>
```

View File

@ -67,7 +67,7 @@ simply by doing `yourComponent.remove();`.
## Lifecycle
![Game Lifecycle Diagram](images/component_lifecycle.png)
![Game Lifecycle Diagram](../images/component_lifecycle.png)
When a game first is added to a Flutter widget tree the following lifecycle methods will be called
in order: `onGameResize`, `onLoad` and `onMount`. After that it goes on to call `update` and
@ -95,11 +95,11 @@ however, be set to `true` to enable debug features for the components of the gam
the value of this variable is passed through to its components when they are added to the game, so
if you change the `debugMode` at runtime, it will not affect already added components by default.
To read more about the `debugMode` on Flame, please refer to the [Debug Docs](debug.md)
To read more about the `debugMode` on Flame, please refer to the [Debug Docs](other/debug.md)
# Low-level Game API
## Low-level Game API
![Game low-level API](images/game_mixin.png)
![Game low-level API](../images/game_mixin.png)
The `Game` mixin is a low-level API that can be used when you want to implement the functionality of
how the game engine should be structured. `Game` does not implement any `update` or
@ -142,7 +142,7 @@ main() {
}
```
# GameLoop
## Game Loop
The `GameLoop` module is a simple abstraction over the game loop concept. Basically most games are
built upon two methods:
@ -153,7 +153,7 @@ built upon two methods:
The `GameLoop` is used by all of Flame's `Game` implementations.
# Pause/Resuming game execution
## Pause/Resuming game execution
A Flame `Game` can be paused and resumed in two ways:
@ -163,7 +163,7 @@ A Flame `Game` can be paused and resumed in two ways:
When pausing a Flame `Game`, the `GameLoop` is effectively paused, meaning that no updates or new
renders will happen until it is resumed.
# Flutter Widgets and Game instances
## Flutter Widgets and Game instances
Since a Flame game can be wrapped in a widget, it is quite easy to use it alongside other Flutter
widgets. But still, there is the Widgets Overlay API that makes things even easier.

View File

@ -0,0 +1,10 @@
# Inputs
```{eval-rst}
.. toctree::
:hidden:
Gesture input <gesture-input.md>
Keyboard input <keyboard-input.md>
Other inputs <other-inputs.md>
```

10
doc/flame/other/other.md Normal file
View File

@ -0,0 +1,10 @@
# Other
```{eval-rst}
.. toctree::
:hidden:
Debugging <debug.md>
Utils <util.md>
Widgets <widgets.md>
```

View File

@ -23,7 +23,7 @@ is expanded both ways.
The `NineTileBox` widget implements a `Container` using that standard. This pattern is also
implemented as a component in the `NineTileBoxComponent` so that you can add this feature directly
to your `FlameGame`. To get to know more about this, check the component docs
[here](components.md#ninetileboxcomponent).
[here](../components.md#ninetileboxcomponent).
Here you can find an example of how to use it (without using the `NineTileBoxComponent`):
@ -60,7 +60,7 @@ SpriteButton.asset(
## SpriteWidget
`SpriteWidget` is a widget used to display a [Sprite](images.md#sprite) inside a widget
`SpriteWidget` is a widget used to display a [Sprite](../rendering/images.md#sprite) inside a widget
tree.
This is how to use it:
@ -74,7 +74,7 @@ SpriteWidget.asset(
## SpriteAnimationWidget
`SpriteAnimationWidget` is a widget used to display [SpriteAnimations](images.md#animation) inside
`SpriteAnimationWidget` is a widget used to display [SpriteAnimations](../rendering/images.md#animation) inside
a widget tree.
This is how to use it:

View File

@ -0,0 +1,12 @@
# Rendering
```{eval-rst}
.. toctree::
:hidden:
Images, sprites and animations <images.md>
Text rendering <text.md>
Colors and palette <palette.md>
Particles <particles.md>
Layers <layers.md>
```

View File

@ -1,14 +1,16 @@
# Structure
Flame has a proposed structure for your project that includes the standard Flutter `assets` directory in addition to two children: `audio` and `images`.
Flame has a proposed structure for your project that includes the standard Flutter `assets`
directory in addition to two children: `audio` and `images`.
If using the following example code:
```dart
void main() {
FlameAudio.play('explosion.mp3');
Flame.images.load('player.png');
Flame.images.load('enemy.png');
}
```
The file structure Flame would expect to find the files in would be:

View File

@ -0,0 +1,9 @@
# flame_audio
```{eval-rst}
.. toctree::
:hidden:
General audio <audio.md>
Background music <bgm.md>
```

View File

@ -1,5 +1,10 @@
```{include} README.md
```
```{eval-rst}
.. include:: toc.rst
.. toctree::
:hidden:
flame <flame/flame.md>
flame_audio <flame_audio/flame_audio.md>
Other Modules <other_modules/other_modules.md>
```

View File

@ -119,7 +119,7 @@ An implementation example can be seen in the
## Viewport and Camera
`Forge2DGame` is using an implementation of the normal Flame `Viewport` and `Camera`, which can be
read more about [here](camera_and_viewport.md).
read more about [here](../flame/camera_and_viewport.md).
If you see your screen as a window and the outside as the Forge2D world, then the `Viewport` is the
part of the world outside that you can see through the window, so the parts that you can see on

View File

@ -0,0 +1,11 @@
# Other Modules
```{eval-rst}
.. toctree::
:hidden:
Forge2D <forge2d.md>
Oxygen <oxygen.md>
Tiled <tiled.md>
Splash screen <splash_screen.md>
```

View File

@ -1,37 +1,37 @@
- [Getting started](/)
- Basic concepts
- [File structure](structure.md)
- [Game loop](game.md)
- [Components](components.md)
- [Platforms](platforms.md)
- [Collision detection](collision_detection.md)
- [Effects](effects.md)
- [Camera & Viewport](camera_and_viewport.md)
- [File structure](flame/structure.md)
- [Game loop](flame/game.md)
- [Components](flame/components.md)
- [Platforms](flame/platforms.md)
- [Collision detection](flame/collision_detection.md)
- [Effects](flame/effects.md)
- [Camera & Viewport](flame/camera_and_viewport.md)
- Inputs
- [Gesture Input](gesture-input.md)
- [Keyboard Input](keyboard-input.md)
- [Other Inputs](other-inputs.md)
- [Gesture Input](flame/inputs/gesture-input.md)
- [Keyboard Input](flame/inputs/keyboard-input.md)
- [Other Inputs](flame/inputs/other-inputs.md)
- Audio
- [General Audio](audio.md)
- [Looping Background Music](bgm.md)
- [General Audio](flame_audio/audio.md)
- [Looping Background Music](flame_audio/bgm.md)
- Rendering
- [Images, Sprites and Animations](images.md)
- [Text Rendering](text.md)
- [Colors and the Palette](palette.md)
- [Particles](particles.md)
- [Layers](layers.md)
- [Images, Sprites and Animations](flame/rendering/images.md)
- [Text Rendering](flame/rendering/text.md)
- [Colors and the Palette](flame/rendering/palette.md)
- [Particles](flame/rendering/particles.md)
- [Layers](flame/rendering/layers.md)
- Other Modules
- [Util](util.md)
- [Widgets](widgets.md)
- [Forge2D](forge2d.md)
- [Oxygen](oxygen.md)
- [Tiled](tiled.md)
- [Debugging](debug.md)
- [Splash screen](splash_screen.md)
- [Util](flame/other/util.md)
- [Widgets](flame/other/widgets.md)
- [Forge2D](other_modules/forge2d.md)
- [Oxygen](other_modules/oxygen.md)
- [Tiled](other_modules/tiled.md)
- [Debugging](flame/other/debug.md)
- [Splash screen](other_modules/splash_screen.md)
- [Tutorials](https://github.com/flame-engine/flame/tree/main/tutorials)

View File

@ -1,49 +0,0 @@
.. toctree::
:caption: Basic concepts
:hidden:
File structure <structure.md>
Game loop <game.md>
Components <components.md>
Platforms <platforms.md>
Collision detection <collision_detection.md>
Effects <effects.md>
Camera & Viewport <camera_and_viewport.md>
.. toctree::
:caption: Inputs
:hidden:
Gesture input <gesture-input.md>
Keyboard input <keyboard-input.md>
Other inputs <other-inputs.md>
.. toctree::
:caption: Audio
:hidden:
General audio <audio.md>
Background music <bgm.md>
.. toctree::
:caption: Rendering
:hidden:
Images, sprites and animations <images.md>
Text rendering <text.md>
Colors and palette <palette.md>
Particles <particles.md>
Layers <layers.md>
.. toctree::
:caption: Other Modules
:hidden:
Util <util.md>
Widgets <widgets.md>
Forge2D <forge2d.md>
Oxygen <oxygen.md>
Tiled <tiled.md>
Debugging <debug.md>
Splash screen <splash_screen.md>

View File

@ -63,14 +63,11 @@ mixin BlocComponent<B extends BlocBase<S>, S> on Component {
}
}
/// {@template flame_bloc_game}
/// An enhanced [FlameGame] that has the capability to listen
/// and emit changes to a [Bloc] state.
///
/// {@endtemplate}
class FlameBlocGame extends FlameGame {
/// FlameBlocGame constructor with an optional [Camera] as a parameter to
///FlameGame.
/// FlameGame
FlameBlocGame({Camera? camera}) : super(camera: camera);
/// Contains a list of all of the [BlocComponent]s with an active

View File

@ -2,7 +2,6 @@ name: flame_test
description: A package with classes to help testing applications using Flame
version: 1.1.0
homepage: https://github.com/flame-engine/flame/tree/main/packages/flame_test
publish_to: none
environment:
sdk: ">=2.14.0 <3.0.0"