Skip to content

Commit

Permalink
Tileset convenience methods for adding tiles
Browse files Browse the repository at this point in the history
  • Loading branch information
dustmop committed Dec 16, 2022
1 parent bdac951 commit ae37d1b
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 0 deletions.
89 changes: 89 additions & 0 deletions src/tiles.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ const visualizer = require('./visualizer.js');

class Tileset {
constructor(sizeInfo) {
sizeInfo = sizeInfo || {};

let deserializeData = null;
if (sizeInfo.deserialize) {
let text = sizeInfo.deserialize;
Expand Down Expand Up @@ -75,6 +77,26 @@ class Tileset {
return make;
}

newTile() {
let pitch = this.tileWidth;
let t = new Tile();
t.width = this.tileWidth;
t.height = this.tileHeight;
t.pitch = pitch;
t.data = new Uint8Array(pitch * this.tileHeight);
return t;
}

clear() {
this.data = [];
this._lookupContents = {};
}

isEmpty() {
return this.data.length == 0;
}


_fillContents() {
this.numTiles = this.data.length;
// TODO: _lookupContents
Expand All @@ -99,13 +121,50 @@ class Tileset {
return this.data.length;
}

push(tile) {
return this.add(tile, true);
}

add(tile, allowDups) {
if (!types.isTile(tile)) {
throw new Error(`required: Tile, got ${JSON.stringify(tile)}`);
}
if (tile.width != this.tileWidth) {
throw new Error(`expected: tileWidth ${this.tileWidth} got ${tile.width}`);
}
if (tile.height != this.tileHeight) {
throw new Error(`expected: tileHeight ${this.tileHeight} got ${tile.height}`);
}
allowDups = allowDups || false;

let pitch = tile.pitch;
let key = this._makeKey(tile.data, pitch);
let tileID;

if (!allowDups) {
tileID = this._lookupContents[key];
if (tileID != null) {
return tileID;
}
}

tileID = this.data.length;
this.data.push(tile.clone());
this._lookupContents[key] = tileID;
this.numTiles = this.data.length;
return tileID;
}

/**
* carve up the plane into tiles, add them to this tileset
* @param {Plane} pl - the plane to create tiles from
* @param {bool} allowDups - whether to allow duplicates (or combine them)
* @return {PatternTable} the pattern table for the added tiles
*/
addFrom(pl, allowDups) {
if (!types.isPlane(pl)) {
throw new Error(`addFrom requires a Plane`);
}
if (this.tileHeight > pl.height) {
throw new Error(`Tileset's tile_height is larger than source data`);
}
Expand Down Expand Up @@ -151,6 +210,27 @@ class Tileset {
return new PatternTable(patternData, patternPitch, numTilesX, numTilesY);
}

insertFrom(other, opt) {
if (!types.isTileset(other)) {
throw new Error(`required: Tileset, got ${JSON.stringify(other)}`);
}

let num = (opt || {}).num;
if (!num) {
num = other.length;
}

for (let i = 0; i < num; i++) {
let t = other.get(i);
if (!t) {
t = this.newTile();
}
// allow duplicates
this.push(t);
}
}


all() {
return this.data;
}
Expand Down Expand Up @@ -275,6 +355,15 @@ class Tile {
this.data[k] = v;
}

clone() {
let make = new Tile();
make.width = this.width;
make.height = this.height;
make.pitch = this.pitch;
make.data = this.data;
return make;
}

display() {
for (let j = 0; j < this.height; j++) {
for (let i = 0; i < this.width; i++) {
Expand Down
46 changes: 46 additions & 0 deletions test/tileset.js
Original file line number Diff line number Diff line change
Expand Up @@ -396,4 +396,50 @@ describe('Tileset', function() {
assert.deepEqual(obj, expectSer);
});

it('tileset methods', ()=>{
let tiles = new ra.Tileset({tile_width: 8, tile_height: 8});
assert(tiles.isEmpty());
assert.equal(tiles.length, 0);

// add an empty tile
tiles.add(tiles.newTile());
assert(!tiles.isEmpty());
assert.equal(tiles.length, 1);

// duplicate tile is ignored
tiles.add(tiles.newTile());
assert.equal(tiles.length, 1);

// push will add a dup
tiles.push(tiles.newTile());
assert.equal(tiles.length, 2);

// so will add with allowDups==true
tiles.add(tiles.newTile(), true);
assert.equal(tiles.length, 3);

tiles.clear();
assert(tiles.isEmpty());
assert.equal(tiles.length, 0);
});

it('tileset insertFrom and pattern table', ()=>{
let tiles = new ra.Tileset({tile_width: 4, tile_height: 4});
assert(tiles.isEmpty());
assert.equal(tiles.length, 0);

let image = ra.loadImage('test/testdata/tiles.png');
let more = new ra.Tileset({tile_width: 4, tile_height: 4});
let pattern = more.addFrom(image);

// serialize the pattern table
let obj = pattern.serialize();
let expectSer = '{"width":4,"height":2,"data":[0,1,2,3,4,5,6,7]}';
assert.deepEqual(obj, expectSer);

// insert from method, only take 4
tiles.insertFrom(more, {num: 4});
assert(tiles.length, 4);
});

});

0 comments on commit ae37d1b

Please sign in to comment.