graphical output in code blocks

This commit is contained in:
りき萌 2024-02-18 00:29:58 +01:00
parent 565b6a0520
commit 51de33c2b5
13 changed files with 351 additions and 57 deletions

View file

@ -40,7 +40,7 @@ styles = ["tairu.css"]
</canvas>
% id = "01HPJ8GHDEC0Z334M04MTNADV9"
- for each tile, we can assign a bitset of cardinal directions like so:
- for each tile we can assign a bitset of cardinal directions, based on which tiles it should connect to - like so:
<canvas
is="tairu-editor-cardinal-directions"
@ -372,22 +372,29 @@ styles = ["tairu.css"]
- and it's even possible to autogenerate most of them given just a few smaller 4x4 pieces - but for now, let's not go down that path.\
maybe another time.
% id = "01HPWJB4Y047YGYAP6XQXJ3576"
- so we only need to draw 47 tiles, but to actually display them in a game we still need to pack them into an image.
% id = "01HPWJB4Y0QX6YR6TQKZ7T1C2E"
- we *could* use a similar approach to the 16 tile version, but that would leave us with lots of wasted space!
% id = "01HPWJB4Y0HKGSDABB56CNFP9H"
- think that with this redundancy elimination approach most of the tiles will never even be looked up by the renderer, because the bit combinations will be collapsed into a more canonical form before the lookup.
% id = "01HPWJB4Y0705RWPFB89V23M1P"
- we could also use the approach I mentioned briefly [here][branch:01HPQCCV4RB65D5Q4RANJKGC0D], which involves introducing a lookup table - which sounds reasonable, so let's do it!
% id = "01HPWJB4Y0F9JGXQDAAVC3ERG1"
- I don't want to write the lookup table by hand, so let's generate it! I'll reuse the redundancy elimination code from before to make this easier.
% id = "01HPWJB4Y0HTV32T4WMKCKWTVA"
- we'll start by obtaining our ordinal directions array again:
```javascript ordinal-directions
export let xToConnectionBitSet = ordinalDirections();
```
% id = "01HPWJB4Y03WYYZ3VTW27GP7Z3"
- then we'll turn that array upside down... in other words, invert the index-value relationship, so that we can look up which X position in the tile strip to use for a specific connection combination.
remember that our array has only 256 values, so it should be pretty cheap to represent using a `Uint8Array`:
@ -399,6 +406,7 @@ styles = ["tairu.css"]
}
```
% id = "01HPWJB4Y0CWQB9EZG6C91A0H0"
- and there we go! we now have a mapping from our bitset to positions within the tile strip. try to play around with the code example to see which bitsets correspond to which position!
```javascript ordinal-directions
@ -408,8 +416,10 @@ styles = ["tairu.css"]
4
```
% id = "01HPWJB4Y09P9Q3NGN59XWX2X9"
+ for my own (and your) convenience, here's a complete list of *all* the possible combinations in order.
% id = "01HPWJB4Y01VJFMHYEC1WZ353W"
- ```javascript ordinal-directions
function toString(bitset) {
if (bitset == 0) return "0";
@ -480,15 +490,18 @@ styles = ["tairu.css"]
46 => E | SE | S | SW | W | NW | N | NE
```
% id = "01HPWJB4Y0NMP35M9138DV3P8W"
- with the lookup table generated, we are now able to prepare a tile strip like before - except now it's even more tedious work arranging the pieces together :ralsei_dead:
anyways I spent like 20 minutes doing that by hand, and now we have a neat tile strip just like before, except way longer:
![horizontal tile strip of 47 8x8 pixel metal tiles][pic:01HPW47SHMSVAH7C0JR9HWXWCM]
% id = "01HPWJB4Y0J3DHQV5F9GD3VNQ8"
- now let's hook it up to our tileset renderer! TODO literate program.
% template = true
id = "01HPWJB4Y00ARHBGDF2HTQQ4SD"
- with the capability to render with 47-tile tilesets, our examples suddenly look a whole lot better!
<canvas

View file

@ -0,0 +1,133 @@
%% title = "the treehouse sandbox"
scripts = ["components/literate-programming.js"]
% id = "01HPWJB4Y5ST6AEK9VDYNS865P"
- the sandbox is a framework for playing around with code
% id = "01HPWJB4Y5HSDMEHNJXVET212V"
- one might call it "literate programming" and indeed that's the name used inside the code
% id = "01HPWJB4Y583X6RXD060RZJ7WA"
- it's based on JavaScript; basically, you write scripts in JavaScript that may embed output into the parent page
% id = "01HPWJB4Y56KH9MVC7Y5DDJ0CH"
- this is a bit of documentation on how to use its features
% id = "01HPWJB4Y5G4XXDE4ZPY3SWPXP"
+ ### basic usage
% id = "01HPWJB4Y5JG6SGV3A5SS6V0JY"
- the smallest building block is a module. each code block is a separate ES module, and therefore it has separate imports and exports.
% id = "01HPWJB4Y5HDEGNVRE307ND6H3"
- for example, in the example below, the two code blocks cannot access each other's variables:
```javascript module-separation-broken
let myVariable = 1;
```
```javascript module-separation-broken
console.log(myVariable);
```
```output module-separation-broken
ReferenceError: myVariable is not defined
```
% id = "01HPWJB4Y574NADEWXYWZR8C6C"
- to fix this, export the variable:
```javascript module-separation-works
export let myVariable = 1;
```
```javascript module-separation-works
console.log(myVariable);
```
```output module-separation-works
1
```
% id = "01HPWJB4Y5GDMQTG6F6K4TDYWA"
+ ### outputting text
% id = "01HPWJB4Y55S28PVMBD4FKK98C"
- for code blocks which are followed by an `Output` block, such as [this one], it is possible to use `console.log` to output text to the console:
```javascript text-output
console.log("Hello, world!");
```
```output text-output
Hello, world!
```
% id = "01HPWJB4Y5CMHY36HW8EPTBSYG"
- `console.warn`, `console.error`, etc. are not supported right now. sorry.
% id = "01HPWJB4Y5CXAMYHGWSG72FP4J"
- code blocks are generally tied together when I say so. for example, you can access variables `export`ed from the above code blocks here; try making this example compile without touching this code block:
```javascript text-output
console.log(x + 1);
```
```output text-output
3
```
% id = "01HPWJB4Y54R6ZB0GHCXRF674M"
- you'll notice that if you edit the first code block in this section, both the code blocks' outputs get updated automatically. neat, huh?
% id = "01HPWJB4Y57BVC7H5N94FREGRK"
+ ### outputting graphics
% id = "01HPWJB4Y5CB5MSBWMG58VMR2G"
- some code blocks allow for graphical output. such as this one:
```javascript graphical-output
import { Sketch } from "treehouse/sandbox.js";
let sketch = new Sketch(200, 200);
sketch.ctx.fillStyle = "white";
sketch.ctx.fillRect(0, 0, sketch.canvas.width, sketch.canvas.height);
sketch.ctx.strokeStyle = "black";
sketch.ctx.strokeRect(32, 32, 32, 32);
```
<th-literate-program data-mode="graphics" data-program="graphical-output"></th-literate-program>
% id = "01HPWJB4Y5ER6SAQZ17ZFH8RK7"
- `Sketch` is an API for drawing things using HTML `<canvas>`.
% id = "01HPWJB4Y5MRKCXRNSRFG7PVP5"
- the act of creating a `Sketch` using `new` causes a new `<canvas>` to be created.
% id = "01HPWJB4Y5HZG6QH5N6N2Q9Z99"
- this `<canvas>` can be accessed using the sketch's `canvas` field, and the canvas's 2D drawing context is accessible using the `ctx` field.
% id = "01HPWJB4Y5ANS55R32X7GJP1N7"
- this API wraps a lower-level message-passing API which is used to communicate with the main page, to let it set things like the sandbox `<iframe>`'s size (as well as make it visible).
see the source code for details.
% id = "01HPWJB4Y5H9DKZT2ZA8PWNV99"
+ ### known issues
% id = "01HPWJB4Y56FPNHJNVGJQ57DWH"
- the code editors are very janky on Firefox right now.
% id = "01HPWJB4Y5T2GA42SJ80JNY2FK"
- the sandbox uses CodeJar to facilitate code editing, and to do this it uses `contenteditable` attributes.
% id = "01HPWJB4Y5H9M4W0ZYYPVWQ6MY"
- I love CodeJar for its simplicity. it brings you text editing, and you bring your own everything else. so I'd love to
% id = "01HPWJB4Y5WWPJXSWQDCMG6J32"
- however, for non-janky text editing, CodeJar uses `contenteditable="plaintext-only"`, which is only supported on Chromium-based browsers.
% id = "01HPWJB4Y5ZJC1P0M6D3VNM0SF"
- I may patch it at some point to support regular `contenteditable` better at some point, but it's not a priority right now.
% id = "01HPWJB4Y52XZJRRZ41F1XK0ZT"
- the sandbox is only used for small, editable, interactive code examples and is not intended to be a fully fledged IDE.