Skip to content

Commit 0f865a0

Browse files
Added LineType enum, diagonal line and line block
1 parent 347d1d7 commit 0f865a0

2 files changed

Lines changed: 73 additions & 9 deletions

File tree

main.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,26 @@ let mySprite = sprites.create(img`
2424
........................
2525
........................
2626
........................
27-
`, SpriteKind.Player)
28-
tiles.placeOnTile(mySprite, tiles.getTileLocation(2, 2))controller.moveSprite(mySprite)
29-
scene.cameraFollowSprite(mySprite)
27+
`, SpriteKind.Player);
28+
tiles.placeOnTile(mySprite, tiles.getTileLocation(2, 2));
29+
controller.moveSprite(mySprite);
30+
scene.cameraFollowSprite(mySprite);
3031
for (let value of tilesExt.getRandomTilesByType(sprites.castle.tileGrass2, 10)) {
3132
tiles.setTileAt(value, sprites.dungeon.chestClosed)
3233
}
3334
//tilesExt.setTileBetweenLocations(new tiles.Location(0,0,undefined), new tiles.Location(5,6,undefined), sprites.builtin.brick);
35+
36+
// tilesExt.line(
37+
// LineType.Diagonal,
38+
// new tiles.Location(0,0,undefined),
39+
// new tiles.Location(7,5,undefined),
40+
// true,
41+
// (x,y) => tiles.setTileAt(new tiles.Location(x,y,undefined), sprites.builtin.brick));
42+
43+
// tilesExt.line(
44+
// LineType.Diagonal,
45+
// new tiles.Location(0,1,undefined),
46+
// new tiles.Location(7,6,undefined),
47+
// true,
48+
// (x,y) => tiles.setTileAt(new tiles.Location(x,y,undefined), sprites.builtin.brick));
3449
game.debug = true;

tilemapExt.ts

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,59 @@ enum LineType {
55

66
//% blockNamespace=scene
77
namespace tilesExt {
8+
import TL = tiles.Location;
89

10+
/**
11+
* Iterates over a line between two locations. If the handler returns Truelike, then the iteration is stopped
12+
* and the handlers return value is returned, otherwise the iteration runs to completion and returns undefined.
13+
* @param lineType width of maze
14+
* @param l1 start
15+
* @param l2 end
16+
* @param exclusive exclude the endpoints
17+
* @param handler a handler which is invoked for each point
18+
* @returns undefined if the whole line was iterated
19+
*/
20+
//% blickId=tilesExt_line
21+
//% block="A $lineType line from $l1 to $l2 || exclusive $exclusive"
22+
//% exclusive.defl=false
23+
//% inlineInputMode=inline
924
//% l1.shadow=mapgettile
1025
//% l2.shadow=mapgettile
11-
export function coveringLineBetweenTiles<T>(l1: tiles.Location, l2: tiles.Location, exclusive: boolean, handler: (col: number, row: number) => T): T {
26+
//% draggableParameters="reporter"
27+
export function line<T>(lineType: LineType, l1: TL, l2: TL, exclusive: boolean, handler: (col: number, row: number) => T): T {
28+
return lineType === LineType.Diagonal ? diagonalLine(l1,l2,exclusive,handler) :
29+
lineType === LineType.Covering ? coveringLine(l1,l2,exclusive,handler) :
30+
undefined;
31+
}
32+
33+
function lerp(start: number, end: number, t: number) {
34+
return start * (1.0 - t) + t * end;
35+
}
36+
37+
function diagonalLine<T>(l1: TL, l2: TL, exclusive: boolean, handler: (col: number, row: number) => T): T {
38+
const dx = l2.col-l1.col, dy = l2.row-l1.row;
39+
const N = Math.max(Math.abs(dx), Math.abs(dy));
40+
if (N <= 0) {
41+
return exclusive ? undefined : handler(l1.col, l1.row);
42+
} else {
43+
const lastN = N - (exclusive ? 1 : 0);
44+
for (let step = (exclusive ? 1 : 0); step <= lastN; step++) {
45+
let t = step / N;
46+
const res = handler(
47+
Math.round(lerp(l1.col, l2.col, t)),
48+
Math.round(lerp(l1.row, l2.row, t))
49+
);
50+
if (res) return res;
51+
}
52+
}
53+
54+
return undefined;
55+
}
56+
57+
58+
59+
60+
export function coveringLine<T>(l1: TL, l2: TL, exclusive: boolean, handler: (col: number, row: number) => T): T {
1261
// https://www.redblobgames.com/grids/line-drawing/#stepping
1362
const dx = l2.col-l1.col, dy = l2.row-l1.row;
1463
const absx = Math.abs(dx), absy = Math.abs(dy);
@@ -45,16 +94,16 @@ namespace tilesExt {
4594
return undefined;
4695
}
4796

48-
export function isWallBetweenLocations(l1: tiles.Location, l2: tiles.Location, tileMap?: tiles.TileMap): tiles.Location | undefined {
97+
export function isWallBetweenLocations(l1: TL, l2: TL, tileMap?: tiles.TileMap): TL | undefined {
4998
tileMap = tileMap || game.currentScene().tileMap;
50-
return coveringLineBetweenTiles(l1, l2, true, (x,y) => tileMap.isObstacle(x,y) ? new tiles.Location(x,y,l1.tileMap) : undefined);
99+
return coveringLine(l1, l2, true, (x,y) => tileMap.isObstacle(x,y) ? new TL(x,y,l1.tileMap) : undefined);
51100
}
52101

53102

54-
export function setTileBetweenLocations(l1: tiles.Location, l2: tiles.Location, im: Image, tileMap?: tiles.TileMap): void {
103+
export function setTileBetweenLocations(l1: TL, l2: TL, im: Image, tileMap?: tiles.TileMap): void {
55104
tileMap = tileMap || game.currentScene().tileMap;
56105
const index = tileMap.getImageType(im);
57-
coveringLineBetweenTiles(l1, l2, false, (x,y) => tileMap.setTileAt(x,y,index));
106+
coveringLine(l1, l2, false, (x,y) => tileMap.setTileAt(x,y,index));
58107
}
59108

60109

@@ -66,7 +115,7 @@ namespace tilesExt {
66115
//% group=Locations
67116
//% block="array of max $maxCount $tile locations"
68117
//% tile.shadow=tileset_tile_picker
69-
export function getRandomTilesByType(tile: Image, maxCount: number): tiles.Location[] {
118+
export function getRandomTilesByType(tile: Image, maxCount: number): TL[] {
70119
const scene = game.currentScene();
71120
if (!tile || !scene.tileMap)
72121
return undefined;

0 commit comments

Comments
 (0)