moshcode 0.45.0 → 0.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/games-breakout.mjs +5 -1
- package/src/games-draw.mjs +50 -0
- package/src/games-pong.mjs +5 -1
package/package.json
CHANGED
package/src/games-breakout.mjs
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
// decides the angle it leaves at, so the paddle is a steering wheel rather than
|
|
5
5
|
// a wall. Without that you cannot dig a channel up the side of the wall, and
|
|
6
6
|
// digging a channel is the entire reason anybody still plays this.
|
|
7
|
+
import { ballCell } from "./games-draw.mjs";
|
|
7
8
|
import { acid, amber, bone, danger, rgb } from "./ui.mjs";
|
|
8
9
|
|
|
9
10
|
export const WIDTH = 40;
|
|
@@ -197,7 +198,10 @@ export const BREAKOUT = {
|
|
|
197
198
|
}
|
|
198
199
|
|
|
199
200
|
for (let i = 0; i < PADDLE_W; i++) put(state.paddle + i, PADDLE_ROW, bone("▀"));
|
|
200
|
-
|
|
201
|
+
// Drawn on half-rows, so the ball steps the same distance down the wall as
|
|
202
|
+
// it does across it. See games-draw.mjs.
|
|
203
|
+
const ball = ballCell(state.ball.x, state.ball.y);
|
|
204
|
+
put(ball.col, ball.row, (state.stuck ? amber : bone)(ball.glyph));
|
|
201
205
|
|
|
202
206
|
return grid.map((row) => row.map((cell) => cell ?? " ").join(""));
|
|
203
207
|
},
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Shared drawing for the things in the arcade that move on a diagonal.
|
|
2
|
+
//
|
|
3
|
+
// A terminal cell is about twice as tall as it is wide, so a board drawn one
|
|
4
|
+
// object per cell has half the resolution going down that it has going across.
|
|
5
|
+
// For a ball that is not a rounding detail, it is the whole reason the motion
|
|
6
|
+
// looks wrong. Two things fall out of it, and both of them read as bad physics
|
|
7
|
+
// rather than as a coarse grid:
|
|
8
|
+
//
|
|
9
|
+
// A step sideways moves the ball one pixel and a step down moves it two, so the
|
|
10
|
+
// same ball appears to travel faster down the board than across it, and a
|
|
11
|
+
// trajectory the maths has at forty-five degrees is drawn at sixty.
|
|
12
|
+
//
|
|
13
|
+
// Worse, the two steps keep their own schedules. Crossing into the next column
|
|
14
|
+
// and crossing into the next row almost never land on the same tick, so a ball
|
|
15
|
+
// going diagonally does not move diagonally — it hops sideways, then a tick or
|
|
16
|
+
// two later hops down. Measured on pong, the ball holds a cell for four ticks,
|
|
17
|
+
// four ticks, then two and two as a row change splits one of those spans. That
|
|
18
|
+
// 4-4-2-2 stutter, three or four times a second, is what is left of the jiggle
|
|
19
|
+
// after the clock was fixed.
|
|
20
|
+
//
|
|
21
|
+
// Half blocks fix both. `▀` and `▄` each fill half a cell, which is close to
|
|
22
|
+
// square, so the ball is drawn on a grid with the same pitch both ways: it
|
|
23
|
+
// steps the same distance whichever way it goes, a row is two steps rather than
|
|
24
|
+
// one, and the corner it turns is half as wide. It is also a better ball than
|
|
25
|
+
// `●` was — a square pixel moving on a square grid, rather than a round dot
|
|
26
|
+
// snapping between cells twice its own height apart.
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Where to draw a ball whose true position is (x, y) in board coordinates.
|
|
30
|
+
*
|
|
31
|
+
* `y` is a row centre, so row r covers y from r - 0.5 up to r + 0.5: below the
|
|
32
|
+
* centre the ball is in the top half of the cell, at or above it the bottom.
|
|
33
|
+
* Returns the cell to write into and the half block to write there.
|
|
34
|
+
*/
|
|
35
|
+
export function ballCell(x, y) {
|
|
36
|
+
const col = Math.round(x);
|
|
37
|
+
const row = Math.round(y);
|
|
38
|
+
return { col, row, glyph: y < row ? "▀" : "▄" };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The ball's position in half-rows — the unit it is actually drawn in.
|
|
43
|
+
*
|
|
44
|
+
* Only the tests use this, to assert that a step down the board is the same
|
|
45
|
+
* size as a step across it.
|
|
46
|
+
*/
|
|
47
|
+
export const halfRow = (y) => {
|
|
48
|
+
const row = Math.round(y);
|
|
49
|
+
return y < row ? row * 2 : row * 2 + 1;
|
|
50
|
+
};
|
package/src/games-pong.mjs
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
// A flat return it will always get; one taken off the end of your paddle it will
|
|
8
8
|
// not. That is the whole game, and it is why the angle off the paddle depends on
|
|
9
9
|
// where the ball hit it.
|
|
10
|
+
import { ballCell } from "./games-draw.mjs";
|
|
10
11
|
import { acid, bone, danger, dim } from "./ui.mjs";
|
|
11
12
|
|
|
12
13
|
export const WIDTH = 44;
|
|
@@ -164,7 +165,10 @@ export const PONG = {
|
|
|
164
165
|
|
|
165
166
|
for (const row of paddleRows(state.you)) put(YOU_COL, row, acid("█"));
|
|
166
167
|
for (const row of paddleRows(state.them)) put(THEM_COL, row, danger("█"));
|
|
167
|
-
|
|
168
|
+
// Drawn on half-rows, so the ball steps the same distance up the table as
|
|
169
|
+
// it does across it. See games-draw.mjs.
|
|
170
|
+
const ball = ballCell(state.ball.x, state.ball.y);
|
|
171
|
+
put(ball.col, ball.row, bone(ball.glyph));
|
|
168
172
|
|
|
169
173
|
return grid.map((row, y) => row.map((cell, x) => (
|
|
170
174
|
// The net, which is only there so the middle of the table has a middle.
|