Tower class hierarchy
This commit is contained in:
@@ -13,7 +13,7 @@ export class Layer {
|
||||
}
|
||||
|
||||
add_tile(tile_factory: TileFactory): HTMLElement {
|
||||
const elem = tile_factory.get_elem(this.#tileset);
|
||||
const elem = tile_factory.build(this.#tileset).get_elem();
|
||||
elem.style.zIndex = `${this.#level}`;
|
||||
return elem;
|
||||
}
|
||||
|
||||
23
ts/layered_tile.ts
Normal file
23
ts/layered_tile.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { Tile } from './tile.js';
|
||||
|
||||
export class LayeredTile extends Tile {
|
||||
elem: HTMLElement;
|
||||
|
||||
constructor(width: number, height: number, tiles: Tile[]) {
|
||||
super(width, height);
|
||||
|
||||
this.elem.style.position = 'relative';
|
||||
|
||||
for (let i = 0; i < tiles.length; i++) {
|
||||
const tile = tiles[i];
|
||||
const sub = tile.get_elem();
|
||||
this.elem.appendChild(sub);
|
||||
sub.style.width = '100%';
|
||||
sub.style.height = '100%';
|
||||
sub.style.position = 'absolute';
|
||||
sub.style.top = '0';
|
||||
sub.style.left = '0';
|
||||
sub.style.zIndex = `${i}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,42 +1,21 @@
|
||||
import { AnimateDetail, TileFactory } from './tile_factory.js';
|
||||
import { LayeredTile } from './layered_tile.js';
|
||||
import { TileFactory } from './tile_factory.js';
|
||||
|
||||
export class LayeredTileFactory extends TileFactory {
|
||||
tiles: TileFactory[];
|
||||
tile_factories: TileFactory[];
|
||||
|
||||
constructor(tiles: TileFactory[]) {
|
||||
super('', tiles[0].width, tiles[0].height);
|
||||
this.tiles = tiles;
|
||||
constructor(tile_factories: TileFactory[]) {
|
||||
super(tile_factories[0].width, tile_factories[0].height);
|
||||
this.tile_factories = tile_factories;
|
||||
}
|
||||
|
||||
get_elem(tileset: string): HTMLElement {
|
||||
const elem = document.createElement('div');
|
||||
elem.style.gridColumnEnd = `span ${this.width}`;
|
||||
elem.style.gridRowEnd = `span ${this.height}`;
|
||||
elem.style.position = 'relative';
|
||||
build(tileset: string): LayeredTile {
|
||||
const tiles = [];
|
||||
|
||||
for (let i = 0; i < this.tiles.length; i++) {
|
||||
const tile = this.tiles[i];
|
||||
const sub = tile.get_elem(tileset);
|
||||
elem.appendChild(sub);
|
||||
sub.style.width = '100%';
|
||||
sub.style.height = '100%';
|
||||
sub.style.position = 'absolute';
|
||||
sub.style.top = '0';
|
||||
sub.style.left = '0';
|
||||
sub.style.zIndex = `${i}`;
|
||||
for (const tile_factory of this.tile_factories) {
|
||||
tiles.push(tile_factory.build(tileset));
|
||||
}
|
||||
|
||||
elem.addEventListener('animate', (e: CustomEvent<AnimateDetail>) => {
|
||||
for (const sub of elem.children) {
|
||||
sub.dispatchEvent(new CustomEvent('animate', {'detail': e.detail}));
|
||||
}
|
||||
});
|
||||
|
||||
// XXX removeme
|
||||
setInterval(() => {
|
||||
elem.dispatchEvent(new CustomEvent('animate', {'detail': {'name': 'fire'}}));
|
||||
}, 3250);
|
||||
|
||||
return elem;
|
||||
return new LayeredTile(this.width, this.height, tiles);
|
||||
}
|
||||
}
|
||||
|
||||
15
ts/simple_tile.ts
Normal file
15
ts/simple_tile.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { Tile } from './tile.js';
|
||||
|
||||
export class SimpleTile extends Tile {
|
||||
animations: Map<string, [Keyframe[], object]>;
|
||||
|
||||
constructor(width: number, height: number, image_url: string, animations: Map<string, [Keyframe[], object]>) {
|
||||
super(width, height);
|
||||
|
||||
this.elem.style.backgroundImage = `url('${encodeURIComponent(image_url)}')`;
|
||||
this.elem.style.backgroundSize = 'cover';
|
||||
|
||||
this.animations = animations;
|
||||
}
|
||||
}
|
||||
|
||||
51
ts/simple_tile_factory.ts
Normal file
51
ts/simple_tile_factory.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import { SimpleTile } from './simple_tile.js';
|
||||
import { TileFactory } from './tile_factory.js';
|
||||
|
||||
export class SimpleTileFactory extends TileFactory {
|
||||
name: string;
|
||||
animations: Map<string, [Keyframe[], object]>;
|
||||
|
||||
constructor(width: number, height: number, name: string) {
|
||||
super(width, height);
|
||||
this.name = name;
|
||||
this.animations = new Map();
|
||||
}
|
||||
|
||||
add_animation(name: string, keyframes: Keyframe[], options: object) {
|
||||
this.animations.set(name, [keyframes, options]);
|
||||
}
|
||||
|
||||
build(tileset: string): SimpleTile {
|
||||
return new SimpleTile(
|
||||
this.width,
|
||||
this.height,
|
||||
`images/${tileset}/${this.name}.svg`,
|
||||
this.animations,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
function string_to_mask(mask_string: string): boolean[][] {
|
||||
// mask_string: '\n+++\n+++\n'
|
||||
|
||||
const rows = mask_string.trim().split('\n');
|
||||
// rows: ['+++', '+++']
|
||||
|
||||
const mask = [];
|
||||
for (let x = 0; x < rows[0].length; x++) {
|
||||
mask[x] = Array(rows.length);
|
||||
}
|
||||
// mask: [ [ empty, empty ], [ empty, empty ], [ empty, empty ] ]
|
||||
|
||||
for (let y = 0; y < rows.length; y++) {
|
||||
const row = rows[y];
|
||||
for (let x = 0; x < row.length; x++) {
|
||||
const cell = row[x];
|
||||
mask[x][y] = (cell.toUpperCase() == 'X');
|
||||
}
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
*/
|
||||
13
ts/tile.ts
Normal file
13
ts/tile.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
export abstract class Tile {
|
||||
elem: HTMLElement;
|
||||
|
||||
constructor(width: number, height: number) {
|
||||
this.elem = document.createElement('div');
|
||||
this.elem.style.gridColumnEnd = `span ${width}`;
|
||||
this.elem.style.gridRowEnd = `span ${height}`;
|
||||
}
|
||||
|
||||
get_elem(): HTMLElement {
|
||||
return this.elem;
|
||||
}
|
||||
}
|
||||
@@ -1,64 +1,13 @@
|
||||
export interface AnimateDetail {
|
||||
name: string;
|
||||
}
|
||||
import { Tile } from './tile.js';
|
||||
|
||||
export class TileFactory {
|
||||
name: string;
|
||||
export abstract class TileFactory {
|
||||
width: number;
|
||||
height: number;
|
||||
animations: Map<string, [Keyframe[], object]>;
|
||||
|
||||
constructor(name: string, width: number, height: number) {
|
||||
this.name = name;
|
||||
constructor(width: number, height: number) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
this.animations = new Map();
|
||||
}
|
||||
|
||||
add_animation(name: string, keyframes: Keyframe[], options: object) {
|
||||
this.animations.set(name, [keyframes, options]);
|
||||
}
|
||||
|
||||
get_elem(tileset: string): HTMLElement {
|
||||
const elem = document.createElement('div');
|
||||
elem.style.backgroundImage = `url("images/${tileset}/${this.name}.svg")`;
|
||||
elem.style.backgroundSize = 'cover';
|
||||
elem.style.gridColumnEnd = `span ${this.width}`;
|
||||
elem.style.gridRowEnd = `span ${this.height}`;
|
||||
|
||||
elem.addEventListener('animate', (e: CustomEvent<AnimateDetail>) => {
|
||||
const animation = this.animations.get(e.detail.name);
|
||||
if (animation) {
|
||||
elem.animate(animation[0], animation[1]);
|
||||
}
|
||||
});
|
||||
|
||||
return elem;
|
||||
}
|
||||
abstract build(tileset: string): Tile;
|
||||
}
|
||||
|
||||
/*
|
||||
function string_to_mask(mask_string: string): boolean[][] {
|
||||
// mask_string: '\n+++\n+++\n'
|
||||
|
||||
const rows = mask_string.trim().split('\n');
|
||||
// rows: ['+++', '+++']
|
||||
|
||||
const mask = [];
|
||||
for (let x = 0; x < rows[0].length; x++) {
|
||||
mask[x] = Array(rows.length);
|
||||
}
|
||||
// mask: [ [ empty, empty ], [ empty, empty ], [ empty, empty ] ]
|
||||
|
||||
for (let y = 0; y < rows.length; y++) {
|
||||
const row = rows[y];
|
||||
for (let x = 0; x < row.length; x++) {
|
||||
const cell = row[x];
|
||||
mask[x][y] = (cell.toUpperCase() == 'X');
|
||||
}
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
*/
|
||||
|
||||
56
ts/tiles.ts
56
ts/tiles.ts
@@ -1,46 +1,46 @@
|
||||
import { LayeredTileFactory } from './layered_tile_factory.js';
|
||||
import { TileFactory } from './tile_factory.js';
|
||||
import { SimpleTileFactory } from './simple_tile_factory.js';
|
||||
|
||||
// Straight
|
||||
export const ROAD_LR = new TileFactory('road-lr', 6, 4);
|
||||
export const ROAD_TB = new TileFactory('road-tb', 4, 6);
|
||||
// Straig
|
||||
export const ROAD_LR = new SimpleTileFactory(6, 4, 'road-lr');
|
||||
export const ROAD_TB = new SimpleTileFactory(4, 6, 'road-tb');
|
||||
|
||||
// Elbow
|
||||
export const ROAD_BL = new TileFactory('road-bl', 6, 6);
|
||||
export const ROAD_BR = new TileFactory('road-br', 6, 6);
|
||||
export const ROAD_TL = new TileFactory('road-tl', 6, 6);
|
||||
export const ROAD_TR = new TileFactory('road-tr', 6, 6);
|
||||
export const ROAD_BL = new SimpleTileFactory(6, 6, 'road-bl');
|
||||
export const ROAD_BR = new SimpleTileFactory(6, 6, 'road-br');
|
||||
export const ROAD_TL = new SimpleTileFactory(6, 6, 'road-tl');
|
||||
export const ROAD_TR = new SimpleTileFactory(6, 6, 'road-tr');
|
||||
|
||||
// T
|
||||
export const ROAD_BLR = new TileFactory('road-blr', 8, 6);
|
||||
export const ROAD_TLR = new TileFactory('road-tlr', 8, 6);
|
||||
export const ROAD_LTB = new TileFactory('road-ltb', 6, 8);
|
||||
export const ROAD_RTB = new TileFactory('road-rtb', 6, 8);
|
||||
export const ROAD_BLR = new SimpleTileFactory(8, 6, 'road-blr');
|
||||
export const ROAD_TLR = new SimpleTileFactory(8, 6, 'road-tlr');
|
||||
export const ROAD_LTB = new SimpleTileFactory(6, 8, 'road-ltb');
|
||||
export const ROAD_RTB = new SimpleTileFactory(6, 8, 'road-rtb');
|
||||
|
||||
// +
|
||||
export const ROAD_TBLR = new TileFactory('road-tblr', 8, 8);
|
||||
export const ROAD_TBLR = new SimpleTileFactory(8, 8, 'road-tblr');
|
||||
|
||||
// Tower base
|
||||
export const EMPTY = new TileFactory('empty', 4, 2);
|
||||
export const EMPTY = new SimpleTileFactory(4, 2, 'empty');
|
||||
|
||||
// Straight
|
||||
export const RIVER_LR = new TileFactory('river-lr', 6, 4);
|
||||
export const RIVER_TB = new TileFactory('river-tb', 4, 6);
|
||||
export const RIVER_LR = new SimpleTileFactory(6, 4, 'river-lr');
|
||||
export const RIVER_TB = new SimpleTileFactory(4, 6, 'river-tb');
|
||||
|
||||
// Elbow
|
||||
export const RIVER_BR = new TileFactory('river-br', 6, 6);
|
||||
export const RIVER_BL = new TileFactory('river-bl', 6, 6);
|
||||
export const RIVER_TR = new TileFactory('river-tr', 6, 6);
|
||||
export const RIVER_TL = new TileFactory('river-tl', 6, 6);
|
||||
export const RIVER_BR = new SimpleTileFactory(6, 6, 'river-br');
|
||||
export const RIVER_BL = new SimpleTileFactory(6, 6, 'river-bl');
|
||||
export const RIVER_TR = new SimpleTileFactory(6, 6, 'river-tr');
|
||||
export const RIVER_TL = new SimpleTileFactory(6, 6, 'river-tl');
|
||||
|
||||
export const BRIDGE_LR = new TileFactory('bridge-lr', 6, 4);
|
||||
export const BRIDGE_LR = new SimpleTileFactory(6, 4, 'bridge-lr');
|
||||
|
||||
const tower_fireball1_back = new TileFactory('fireball1-back', 4, 4);
|
||||
const tower_fireball1 = new TileFactory('fireball1', 4, 4);
|
||||
const tower_fireball1_front = new TileFactory('fireball1-front', 4, 4);
|
||||
const tower_fireball1_back = new SimpleTileFactory(4, 4, 'fireball1-back');
|
||||
const tower_fireball1 = new SimpleTileFactory(4, 4, 'fireball1');
|
||||
const tower_fireball1_front = new SimpleTileFactory(4, 4, 'fireball1-front');
|
||||
|
||||
for (const tile of [tower_fireball1_back, tower_fireball1_front]) {
|
||||
tile.add_animation(
|
||||
for (const tile_factory of [tower_fireball1_back, tower_fireball1_front]) {
|
||||
tile_factory.add_animation(
|
||||
'fire',
|
||||
[
|
||||
{
|
||||
@@ -74,7 +74,8 @@ export const TOWER_FIREBALL1 = new LayeredTileFactory([
|
||||
tower_fireball1_front,
|
||||
]);
|
||||
|
||||
class Fireball extends TileFactory {
|
||||
/*
|
||||
class Fireball extends SimpleTileFactory {
|
||||
get_elem(tileset: string): HTMLElement {
|
||||
const elem = document.createElement('div');
|
||||
elem.style.gridColumnEnd = `span ${this.width}`;
|
||||
@@ -142,3 +143,4 @@ class Fireball extends TileFactory {
|
||||
}
|
||||
}
|
||||
export const FIREBALL = new Fireball('fireball', 2, 2);
|
||||
*/
|
||||
|
||||
@@ -82,7 +82,6 @@ export function main() {
|
||||
grid.add_tile('bridge', tiles.BRIDGE_LR, 46, 10);
|
||||
|
||||
grid.add_tile('tower', tiles.TOWER_FIREBALL1, 30, 18);
|
||||
grid.add_tile('tower', tiles.FIREBALL, 31, 17);
|
||||
};
|
||||
|
||||
main();
|
||||
|
||||
Reference in New Issue
Block a user