This commit is contained in:
Theis Pieter Hollebeek 2025-10-13 14:43:53 +02:00
parent 8a069d28e3
commit 0c2143dea4
8 changed files with 186 additions and 262 deletions

View File

@ -10,8 +10,9 @@ function injectIntoTemplate(name: string, rendered: string): string {
"<head>", "<head>",
[ [
`<title>${name}</title>`, `<title>${name}</title>`,
'<script src="header_ids.js" defer></script>', '<script src="headers.js" defer></script>',
'<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/default.min.css">', '<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/base16/gruvbox-dark-hard.css">',
'<link rel="stylesheet" href="style.css">',
], ],
"</head>", "</head>",
"<body>", "<body>",

View File

@ -1,11 +1,33 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html>
<head> <head>
<meta charset="UTF-8"> <title>Redirecting</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="refresh" content="2; url=-" />
<title>Karlkoder Docs</title> <style>
:root {
color-scheme: light dark;
}
body {
margin: 0;
min-height: 100vh;
font-family: monospace;
font-size: 1.2rem;
display: grid;
justify-items: center;
align-content: center;
}
pre,
p {
width: max-content;
}
a {
color: inherit;
}
</style>
</head> </head>
<body> <body>
<h1>Docs</h1> <p>Redirecting to <a href="-">docs</a>.</p>
</body> </body>
</html> </html>

View File

@ -13,7 +13,7 @@ A type of string.
Represents HTML colors. This includes Represents HTML colors. This includes
[named colors](https://developer.mozilla.org/en-US/docs/Web/CSS/named-color) such as `blue`, `red`, [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 `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. [`lib.rgb(r,g,b)`](#Lib-rgb) to generate a properly formatted rgb color code.
Example: Example:
@ -106,7 +106,9 @@ lib.startGameFunction(loopFunction);
## Lib ## Lib
### `lib.println(msg: string) -> void` ### `println`
`lib.println(msg: string) -> void`
Print a message the debug console. Print a message the debug console.
@ -117,19 +119,23 @@ lib.println("Hello world!");
lib.println("It is a thursday."); lib.println("It is a thursday.");
``` ```
``` ```ini
[console] [console]
Hello world! Hello world!
It is a thursday. It is a thursday.
``` ```
### `lib.startGameLoop(loopFunction: LoopFunc) -> void` ### `startGameLoop`
`lib.startGameLoop(loopFunction: LoopFunc) -> void`
Registers a gameloop function, that is called on every tick. Registers a gameloop function, that is called on every tick.
See also: [`Models.LoopFunc`](#Models-LoopFunc) See also: [`Models.LoopFunc`](#Models-LoopFunc)
### `lib.isPressed(key: Key) -> bool` ### `isPressed`
`lib.isPressed(key: Key) -> bool`
Returns whether or not `key` is currently pressed. Returns whether or not `key` is currently pressed.
@ -149,7 +155,9 @@ lib.startGameLoop(function (deltaT) {
}); });
``` ```
### `lib.onPress(key: Key, handlerFunction: KeyEventFunc) -> void` ### `onPress`
`lib.onPress(key: Key, handlerFunction: KeyEventFunc) -> void`
Calls `handlerFunction` whenever `key` is pressed. Calls `handlerFunction` whenever `key` is pressed.
@ -169,11 +177,15 @@ lib.onRelease(" ", function () {
}); });
``` ```
### `lib.onRelease(key: Key, handlerFunction: KeyEventFunc) -> void` ### `onRelease`
The opposite of [`lib.onPress`](#Lib-lib.onPress) `lib.onRelease(key: Key, handlerFunction: KeyEventFunc) -> void`
### `lib.rgb(red: number, green: number, blue: number) -> Color` The opposite of [`lib.onPress`](#Lib-onPress)
### `rgb`
`lib.rgb(red: number, green: number, blue: number) -> Color`
Generates a correctly formatted [`Color`](#Models-Color) value based on `red`, `green` and `blue` Generates a correctly formatted [`Color`](#Models-Color) value based on `red`, `green` and `blue`
@ -185,7 +197,9 @@ Example:
lib.drawRect(100, 0, 100, 100, lib.rgb(192, 127, 172)); lib.drawRect(100, 0, 100, 100, lib.rgb(192, 127, 172));
``` ```
### `lib.clear(color: Color) -> void` ### `clear`
`lib.clear(color: Color) -> void`
Paints the entire screen `color`. Paints the entire screen `color`.
@ -204,7 +218,9 @@ lib.startGameLoop(function () {
}); });
``` ```
### `lib.drawSprite(x: number, y: number, width: number, height: number, name: string) -> void` ### `drawSprite`
`lib.drawSprite(x: number, y: number, width: number, height: number, name: string) -> void`
Draws a sprite imported in the sprite editor. Draws a sprite imported in the sprite editor.
@ -219,7 +235,9 @@ lib.startGameLoop(function () {
}); });
``` ```
### `lib.drawRect(x: number, y: number, width: number, height: number, color: Color) -> void` ### `drawRect`
`lib.drawRect(x: number, y: number, width: number, height: number, color: Color) -> void`
Fills a rect with [`Color`](#Models-Color). Fills a rect with [`Color`](#Models-Color).

5
docs/src/index.md Normal file
View File

@ -0,0 +1,5 @@
# Docs
## Gamelib
[Link to Gamelib docs](gamelib)

View File

@ -1,235 +0,0 @@
# Gamelib
## 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)` 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`
([link](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` 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);
```
## Functions
### `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`
### `lib.isPressed(key: Key) -> bool`
Returns whether or not `key` is currently pressed.
See also: `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.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.rgb(red: number, green: number, blue: number) -> Color`
Generates a correctly formatted `Color` value based on `red`, `green` and `blue`
See also: `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`
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`.
See also: `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);
});
```

View File

@ -7,13 +7,22 @@ function renderTableOfContents() {
const ancestors = []; const ancestors = [];
for (const header of headers) { for (const header of headers) {
if (header.textContent === "Contents") {
continue;
}
const depth = parseInt(header.tagName.slice(1)) - 1; const depth = parseInt(header.tagName.slice(1)) - 1;
while (ancestors.length >= depth) { while (ancestors.length >= depth) {
ancestors.pop(); ancestors.pop();
} }
const li = document.createElement("li"); const li = document.createElement("li");
const a = document.createElement("a"); const a = document.createElement("a");
a.textContent = header.textContent; if (header.querySelector("code") !== null) {
const code = document.createElement("code");
code.textContent = header.textContent;
a.append(code);
} else {
a.textContent = header.textContent;
}
a.href = `#${header.id}`; a.href = `#${header.id}`;
const ul = document.createElement("ul"); const ul = document.createElement("ul");
li.replaceChildren(a, ul); li.replaceChildren(a, ul);
@ -29,21 +38,39 @@ function renderTableOfContents() {
root.replaceChildren(list); root.replaceChildren(list);
} }
function groupHeadersInDiv(headerTag) {
const firstElement = document.querySelector(headerTag);
if (firstElement === null) {
return;
}
let container = document.createElement("div");
firstElement.replaceWith(container);
container.append(firstElement);
while (true) {
const sib = container.nextSibling;
if (sib === null) {
break;
}
if (sib.nodeName === headerTag.toUpperCase()) {
container = document.createElement("div");
sib.replaceWith(container);
}
container.append(sib);
}
}
function slugify(elements) { function slugify(elements) {
console.log(elements); console.log(elements);
return elements return elements
.map((element, i) => { .map((element, i) => {
if (i === 0) return null; if (i === 0) return null;
const content = element.textContent.trim(); return element.textContent.trim();
if (content.startsWith("lib.")) {
const [name] = content.match(/^lib\.[^\(]+/);
return name.trim();
}
return content;
}) })
.filter((x) => x !== null) .filter((x) => x !== null)
.join("-"); .join("-");
} }
function attachIdToHeaders() { function attachIdToHeaders() {
const headers = document.querySelectorAll("h1,h2,h3,h4,h5,h6"); const headers = document.querySelectorAll("h1,h2,h3,h4,h5,h6");
const ancestors = []; const ancestors = [];
@ -59,3 +86,4 @@ function attachIdToHeaders() {
attachIdToHeaders(); attachIdToHeaders();
renderTableOfContents(); renderTableOfContents();
groupHeadersInDiv("h2");

84
docs/static/style.css vendored Normal file
View File

@ -0,0 +1,84 @@
*, ::before, *::after {
box-sizing: border-box;
}
:root {
color-scheme: dark;
}
body {
font-family: system-ui;
color: white;
background-color: #141414;
padding: 1rem;
max-width: 90%;
margin: 0 auto;
}
h1 {
font-size: 2.5rem;
}
h2 {
font-size: 2rem;
}
h3 {
font-size: 1rem;
}
h4 {
font-size: 0.5rem;
}
a {
font-weight: bold;
color: white;
}
a:has(code) {
color: #d5c4a1;
}
p code {
color: #d5c4a1;
background-color: #1d2021;
padding: 0.25rem 0.5rem;
border-radius: 0.5rem;
font-size: 1rem;
}
pre code {
border-radius: 0.5rem;
font-size: 1rem;
}
h1, h2, h3, h4, h5, h6 {
color: black;
isolation: isolate;
position: relative;
max-width: max-content;
&::before {
content: "";
position: absolute;
top: -0.25em;
bottom: -0.25em;
right: -1em;
left: -999rem;
z-index: -1;
border-radius: 0.5rem;
background-color: #ccc;
}
}
h2 {
position: sticky;
top: 0;
z-index: 10;
}
table-of-contents > ul {
list-style: none;
padding-left: 0;
font-size: 1.25rem;
}

View File

@ -110,7 +110,8 @@ function loop(deltaT) {
lib.startGameLoop(loop); lib.startGameLoop(loop);
</pre> </pre
>
</div> </div>
</section> </section>
</div> </div>