Compare commits
No commits in common. "544a9f36634b772f5f3ec1dcda8b2161ab70e9af" and "8c5f713501a5c6ba3772c285a905d014c7813be0" have entirely different histories.
544a9f3663
...
8c5f713501
@ -3,6 +3,5 @@
|
|||||||
"indentWidth": 4,
|
"indentWidth": 4,
|
||||||
"lineWidth": 100
|
"lineWidth": 100
|
||||||
},
|
},
|
||||||
"exclude": ["./docs"],
|
|
||||||
"lib": ["dom", "dom.iterable", "dom.asynciterable", "deno.ns"]
|
"lib": ["dom", "dom.iterable", "dom.asynciterable", "deno.ns"]
|
||||||
}
|
}
|
||||||
|
|||||||
1
docs/.gitignore
vendored
1
docs/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
-
|
|
||||||
@ -1,70 +0,0 @@
|
|||||||
import { Renderer } from "@libs/markdown";
|
|
||||||
import HighlightPlugin from "@libs/markdown/plugins/highlighting";
|
|
||||||
import { walk } from "@std/fs";
|
|
||||||
import * as pathTools from "@std/path";
|
|
||||||
|
|
||||||
function injectIntoTemplate(name: string, rendered: string): string {
|
|
||||||
let content = [
|
|
||||||
"<!DOCTYPE html>",
|
|
||||||
"<html>",
|
|
||||||
"<head>",
|
|
||||||
[
|
|
||||||
`<title>${name}</title>`,
|
|
||||||
'<script src="header_ids.js" defer></script>',
|
|
||||||
'<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/default.min.css">',
|
|
||||||
],
|
|
||||||
"</head>",
|
|
||||||
"<body>",
|
|
||||||
[
|
|
||||||
rendered,
|
|
||||||
],
|
|
||||||
"</body>",
|
|
||||||
"</html>",
|
|
||||||
];
|
|
||||||
while (content.some((x) => Array.isArray(x))) {
|
|
||||||
content = content.flat();
|
|
||||||
}
|
|
||||||
return content.join("");
|
|
||||||
}
|
|
||||||
|
|
||||||
async function renderMarkdown() {
|
|
||||||
const renderer = await Renderer.with({
|
|
||||||
plugins: [HighlightPlugin],
|
|
||||||
});
|
|
||||||
for await (
|
|
||||||
const entry of walk("src", { exts: [".md"], includeDirs: false })
|
|
||||||
) {
|
|
||||||
const parsed = pathTools.parse(entry.path);
|
|
||||||
parsed.dir = parsed.dir.replace(/^src[\\/]?/, "");
|
|
||||||
parsed.dir = pathTools.join("-", parsed.dir);
|
|
||||||
parsed.ext = ".html";
|
|
||||||
parsed.base = `${parsed.name}${parsed.ext}`;
|
|
||||||
|
|
||||||
await Deno.mkdir(parsed.dir, { recursive: true });
|
|
||||||
const content = await renderer.render(await Deno.readTextFile(entry.path));
|
|
||||||
await Deno.writeTextFile(
|
|
||||||
pathTools.format(parsed),
|
|
||||||
injectIntoTemplate(parsed.name, content),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function copyStaticFiles() {
|
|
||||||
for await (const entry of walk("static", { includeDirs: false })) {
|
|
||||||
const parsed = pathTools.parse(entry.path);
|
|
||||||
parsed.dir = parsed.dir.replace(/^static[\\/]?/, "");
|
|
||||||
parsed.dir = pathTools.join("-", parsed.dir);
|
|
||||||
|
|
||||||
await Deno.mkdir(parsed.dir, { recursive: true });
|
|
||||||
await Deno.copyFile(entry.path, pathTools.format(parsed));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function main() {
|
|
||||||
await renderMarkdown();
|
|
||||||
await copyStaticFiles();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (import.meta.main) {
|
|
||||||
main();
|
|
||||||
}
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"fmt": {
|
|
||||||
"indentWidth": 4,
|
|
||||||
"lineWidth": 100
|
|
||||||
},
|
|
||||||
"imports": {
|
|
||||||
"@libs/markdown": "jsr:@libs/markdown@^2.0.4",
|
|
||||||
"@std/fs": "jsr:@std/fs@^1.0.19",
|
|
||||||
"@std/path": "jsr:@std/path@^1.1.2"
|
|
||||||
},
|
|
||||||
"tasks": {
|
|
||||||
"build": "deno run -A build.ts"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
2073
docs/deno.lock
generated
2073
docs/deno.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,240 +0,0 @@
|
|||||||
# Gamelib
|
|
||||||
|
|
||||||
## Contents
|
|
||||||
|
|
||||||
<table-of-contents></table-of-contents>
|
|
||||||
|
|
||||||
## Models
|
|
||||||
|
|
||||||
### `Color`
|
|
||||||
|
|
||||||
A type of string.
|
|
||||||
|
|
||||||
Represents HTML colors. This includes
|
|
||||||
[named colors](https://developer.mozilla.org/en-US/docs/Web/CSS/named-color) such as `blue`, `red`,
|
|
||||||
`blanchedalmond`, `lavenderblush`, and rgb/hex when used with proper format. You can use
|
|
||||||
[`lib.rgb(r, g, b)`](#Lib-lib.rgb) to generate a properly formatted rgb color code.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
lib.drawRect(0, 0, 100, 100, "blue");
|
|
||||||
lib.drawRect(100, 0, 100, 100, lib.rgb(192, 127, 172));
|
|
||||||
```
|
|
||||||
|
|
||||||
### `Key`
|
|
||||||
|
|
||||||
A type of string.
|
|
||||||
|
|
||||||
Represents JavaScript's
|
|
||||||
[`KeyboardEvent.key`](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) property.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```
|
|
||||||
"Enter": Enter was pressed.
|
|
||||||
"b": Lowercase 'b' was pressed.
|
|
||||||
"B": Uppercase 'B' was pressed (i.e. Shift + B)
|
|
||||||
" ": Spacebar was pressed.
|
|
||||||
```
|
|
||||||
|
|
||||||
/* todo: include a little html tool that listens to key events when focused and outputs what key was
|
|
||||||
pressed */
|
|
||||||
|
|
||||||
### `KeyEventFunc`
|
|
||||||
|
|
||||||
A function with no parameters that is called whenever the appropriate [`Key`](#Models-Key) is
|
|
||||||
pressed / released.
|
|
||||||
|
|
||||||
Works both as a named and anonymous function.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
let playerX = 0;
|
|
||||||
|
|
||||||
// anonymous function
|
|
||||||
lib.onPress("a", function () {
|
|
||||||
playerX -= 20;
|
|
||||||
});
|
|
||||||
|
|
||||||
// named function
|
|
||||||
function dWasPressed() {
|
|
||||||
playerX += 20;
|
|
||||||
}
|
|
||||||
// note the lack of () after dWasPressed - we are not calling the function, we are referring to it as a variable
|
|
||||||
lib.onPress("a", dWasPressed);
|
|
||||||
```
|
|
||||||
|
|
||||||
### `LoopFunc`
|
|
||||||
|
|
||||||
A function with a single parameters (`deltaT`) that is called whenever a game tick should run -
|
|
||||||
usually about 1/60 times a second.
|
|
||||||
|
|
||||||
The `deltaT` parameter describes the time difference between the last tick and now, in seconds.
|
|
||||||
|
|
||||||
The name used for `deltaT` can be anything, it functions as any other function parameter. I.e.
|
|
||||||
`loopFunction(timeSinceLastCall)`, `loopFunction(fooBar)`, etc.
|
|
||||||
|
|
||||||
For example:
|
|
||||||
|
|
||||||
```
|
|
||||||
loopFunction is called at 12:00.24 - deltaT is 0
|
|
||||||
loopFunction is called at 12:00.75 - deltaT is .51
|
|
||||||
loopFunction is called at 12:01.52 - deltaT is .77
|
|
||||||
```
|
|
||||||
|
|
||||||
Works both as a named and anonymous function.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
let playerX = 0;
|
|
||||||
|
|
||||||
// anonymous function
|
|
||||||
lib.startGameLoop(function (deltaT) {
|
|
||||||
playerX += 20 * deltaT;
|
|
||||||
});
|
|
||||||
|
|
||||||
// named function
|
|
||||||
function loopFunction(deltaTime) {
|
|
||||||
playerX += 20 * deltaTime;
|
|
||||||
}
|
|
||||||
// note the lack of () after loopFunction - we are not calling the function, we are using it as a variable
|
|
||||||
lib.startGameFunction(loopFunction);
|
|
||||||
```
|
|
||||||
|
|
||||||
## Lib
|
|
||||||
|
|
||||||
### `lib.println(msg: string) -> void`
|
|
||||||
|
|
||||||
Print a message the debug console.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
lib.println("Hello world!");
|
|
||||||
lib.println("It is a thursday.");
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
[console]
|
|
||||||
Hello world!
|
|
||||||
It is a thursday.
|
|
||||||
```
|
|
||||||
|
|
||||||
### `lib.startGameLoop(loopFunction: LoopFunc) -> void`
|
|
||||||
|
|
||||||
Registers a gameloop function, that is called on every tick.
|
|
||||||
|
|
||||||
See also: [`Models.LoopFunc`](#Models-LoopFunc)
|
|
||||||
|
|
||||||
### `lib.isPressed(key: Key) -> bool`
|
|
||||||
|
|
||||||
Returns whether or not `key` is currently pressed.
|
|
||||||
|
|
||||||
See also: [`Models.Key`](#Models-Key)
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
let playerX = 0;
|
|
||||||
lib.startGameLoop(function (deltaT) {
|
|
||||||
if (lib.isPressed("a")) {
|
|
||||||
playerX -= 20 * deltaT;
|
|
||||||
}
|
|
||||||
if (lib.isPressed("d")) {
|
|
||||||
playerX -= 20 * deltaT;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### `lib.onPress(key: Key, handlerFunction: KeyEventFunc) -> void`
|
|
||||||
|
|
||||||
Calls `handlerFunction` whenever `key` is pressed.
|
|
||||||
|
|
||||||
See also: [`Models.Key`](#Models-Key), [`Models.KeyEventFunc`](#Models-KeyEventFunc)
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
let isJumping = false;
|
|
||||||
|
|
||||||
lib.onPress(" ", function () {
|
|
||||||
isJumping = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
lib.onRelease(" ", function () {
|
|
||||||
isJumping = false;
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### `lib.onRelease(key: Key, handlerFunction: KeyEventFunc) -> void`
|
|
||||||
|
|
||||||
The opposite of [`lib.onPress`](#Lib-lib.onPress)
|
|
||||||
|
|
||||||
### `lib.rgb(red: number, green: number, blue: number) -> Color`
|
|
||||||
|
|
||||||
Generates a correctly formatted [`Color`](#Models-Color) value based on `red`, `green` and `blue`
|
|
||||||
|
|
||||||
See also: [`Models.Color`](#Models-Color)
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
lib.drawRect(100, 0, 100, 100, lib.rgb(192, 127, 172));
|
|
||||||
```
|
|
||||||
|
|
||||||
### `lib.clear(color: Color) -> void`
|
|
||||||
|
|
||||||
Paints the entire screen `color`.
|
|
||||||
|
|
||||||
See also: [`Models.Color`](#Models-Color)
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
function drawClouds() {
|
|
||||||
/* some lib.drawRect(..) or lib.drawSprite(..) */
|
|
||||||
}
|
|
||||||
|
|
||||||
lib.startGameLoop(function () {
|
|
||||||
lib.clear("blue");
|
|
||||||
drawClouds();
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### `lib.drawSprite(x: number, y: number, width: number, height: number, name: string) -> void`
|
|
||||||
|
|
||||||
Draws a sprite imported in the sprite editor.
|
|
||||||
|
|
||||||
/* todo: link to sprite editor docs */
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
lib.startGameLoop(function () {
|
|
||||||
lib.clear("blue");
|
|
||||||
lib.drawSprite(20, 30, 20, 10, "cloud.png");
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### `lib.drawRect(x: number, y: number, width: number, height: number, color: Color) -> void`
|
|
||||||
|
|
||||||
Fills a rect with [`Color`](#Models-Color).
|
|
||||||
|
|
||||||
See also: [`Models.Color`](#Models-Color)
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
function drawCloud(x, y) {
|
|
||||||
lib.drawRect(x, y, 20, 10, "white");
|
|
||||||
}
|
|
||||||
|
|
||||||
lib.startGameLoop(function () {
|
|
||||||
lib.clear("blue");
|
|
||||||
drawCloud(20, 30);
|
|
||||||
drawCloud(50, 35);
|
|
||||||
});
|
|
||||||
```
|
|
||||||
61
docs/static/header_ids.js
vendored
61
docs/static/header_ids.js
vendored
@ -1,61 +0,0 @@
|
|||||||
function renderTableOfContents() {
|
|
||||||
const root = document.querySelector("table-of-contents");
|
|
||||||
|
|
||||||
const list = document.createElement("ul");
|
|
||||||
|
|
||||||
const headers = document.querySelectorAll("h2,h3,h4,h5,h6");
|
|
||||||
|
|
||||||
const ancestors = [];
|
|
||||||
for (const header of headers) {
|
|
||||||
const depth = parseInt(header.tagName.slice(1)) - 1;
|
|
||||||
while (ancestors.length >= depth) {
|
|
||||||
ancestors.pop();
|
|
||||||
}
|
|
||||||
const li = document.createElement("li");
|
|
||||||
const a = document.createElement("a");
|
|
||||||
a.textContent = header.textContent;
|
|
||||||
a.href = `#${header.id}`;
|
|
||||||
const ul = document.createElement("ul");
|
|
||||||
li.replaceChildren(a, ul);
|
|
||||||
const mostRecent = ancestors[ancestors.length - 1];
|
|
||||||
if (mostRecent === undefined) {
|
|
||||||
list.appendChild(li);
|
|
||||||
} else {
|
|
||||||
mostRecent.appendChild(li);
|
|
||||||
}
|
|
||||||
ancestors.push(ul);
|
|
||||||
}
|
|
||||||
|
|
||||||
root.replaceChildren(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
function slugify(elements) {
|
|
||||||
console.log(elements);
|
|
||||||
return elements
|
|
||||||
.map((element, i) => {
|
|
||||||
if (i === 0) return null;
|
|
||||||
const content = element.textContent.trim();
|
|
||||||
if (content.startsWith("lib.")) {
|
|
||||||
const [name] = content.match(/^lib\.[^\(]+/);
|
|
||||||
return name.trim();
|
|
||||||
}
|
|
||||||
return content;
|
|
||||||
})
|
|
||||||
.filter((x) => x !== null)
|
|
||||||
.join("-");
|
|
||||||
}
|
|
||||||
function attachIdToHeaders() {
|
|
||||||
const headers = document.querySelectorAll("h1,h2,h3,h4,h5,h6");
|
|
||||||
const ancestors = [];
|
|
||||||
for (const header of headers) {
|
|
||||||
const depth = parseInt(header.tagName.slice(1));
|
|
||||||
while (ancestors.length >= depth) {
|
|
||||||
ancestors.pop();
|
|
||||||
}
|
|
||||||
ancestors.push(header);
|
|
||||||
if (depth > 1) header.id = slugify(ancestors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
attachIdToHeaders();
|
|
||||||
renderTableOfContents();
|
|
||||||
Loading…
x
Reference in New Issue
Block a user