Fix draw order of tiles in a cell once and for all

This commit is contained in:
Eevee (Evelyn Woods) 2020-09-03 10:39:19 -06:00
parent 15d3d43b76
commit 8309b80342
3 changed files with 115 additions and 21 deletions

View File

@ -130,13 +130,13 @@ class Cell extends Array {
// DO NOT use me to remove a tile permanently, only to move it! // DO NOT use me to remove a tile permanently, only to move it!
// Should only be called from Level, which handles some bookkeeping! // Should only be called from Level, which handles some bookkeeping!
_remove(tile) { _remove(tile) {
let layer = this.indexOf(tile); let index = this.indexOf(tile);
if (layer < 0) if (index < 0)
throw new Error("Asked to remove tile that doesn't seem to exist"); throw new Error("Asked to remove tile that doesn't seem to exist");
this.splice(layer, 1); this.splice(index, 1);
tile.cell = null; tile.cell = null;
return layer; return index;
} }
} }
@ -756,12 +756,12 @@ class Level {
remove_tile(tile) { remove_tile(tile) {
let cell = tile.cell; let cell = tile.cell;
let layer = cell._remove(tile); let index = cell._remove(tile);
this.pending_undo.push(() => cell._add(tile, layer)); this.pending_undo.push(() => cell._add(tile, index));
} }
add_tile(tile, cell, layer = null) { add_tile(tile, cell, index = null) {
cell._add(tile, layer); cell._add(tile, index);
this.pending_undo.push(() => cell._remove(tile)); this.pending_undo.push(() => cell._remove(tile));
} }

View File

@ -52,19 +52,16 @@ export class CanvasRenderer {
let yf0 = Math.floor(y0); let yf0 = Math.floor(y0);
let x1 = Math.ceil(x0 + this.viewport_size_x - 1); let x1 = Math.ceil(x0 + this.viewport_size_x - 1);
let y1 = Math.ceil(y0 + this.viewport_size_y - 1); let y1 = Math.ceil(y0 + this.viewport_size_y - 1);
// Draw in layers, so animated objects aren't overdrawn by neighboring terrain // Draw one layer at a time, so animated objects aren't overdrawn by
let any_drawn = true; // neighboring terrain
let i = -1; // XXX layer count hardcoded here
while (any_drawn) { for (let layer = 0; layer < 4; layer++) {
i++;
any_drawn = false;
for (let x = xf0; x <= x1; x++) { for (let x = xf0; x <= x1; x++) {
for (let y = yf0; y <= y1; y++) { for (let y = yf0; y <= y1; y++) {
let cell = this.level.cells[y][x]; for (let tile of this.level.cells[y][x]) {
if (! cell) console.error(x, y); if (tile.type.draw_layer !== layer)
let tile = cell[i]; continue;
if (tile) {
any_drawn = true;
if (tile.type.is_actor) { if (tile.type.is_actor) {
// Handle smooth scrolling // Handle smooth scrolling
let [vx, vy] = tile.visual_position(tic_offset); let [vx, vy] = tile.visual_position(tic_offset);

View File

@ -1,28 +1,40 @@
import { DIRECTIONS } from './defs.js'; import { DIRECTIONS } from './defs.js';
// Draw layers
const LAYER_TERRAIN = 0;
const LAYER_ITEM = 1;
const LAYER_ACTOR = 2;
const LAYER_OVERLAY = 3;
const TILE_TYPES = { const TILE_TYPES = {
// Floors and walls // Floors and walls
floor: { floor: {
draw_layer: LAYER_TERRAIN,
}, },
floor_letter: { floor_letter: {
draw_layer: LAYER_TERRAIN,
load(me, template) { load(me, template) {
me.ascii_code = template.modifier; me.ascii_code = template.modifier;
}, },
}, },
wall: { wall: {
draw_layer: LAYER_TERRAIN,
blocks: true, blocks: true,
}, },
wall_invisible: { wall_invisible: {
draw_layer: LAYER_TERRAIN,
// TODO cc2 seems to make these flicker briefly // TODO cc2 seems to make these flicker briefly
blocks: true, blocks: true,
}, },
wall_appearing: { wall_appearing: {
draw_layer: LAYER_TERRAIN,
blocks: true, blocks: true,
on_bump(me, level, other) { on_bump(me, level, other) {
level.transmute_tile(me, 'wall'); level.transmute_tile(me, 'wall');
}, },
}, },
popwall: { popwall: {
draw_layer: LAYER_TERRAIN,
blocks_monsters: true, blocks_monsters: true,
blocks_blocks: true, blocks_blocks: true,
on_depart(me, level, other) { on_depart(me, level, other) {
@ -30,27 +42,34 @@ const TILE_TYPES = {
}, },
}, },
thinwall_n: { thinwall_n: {
draw_layer: LAYER_OVERLAY,
thin_walls: new Set(['north']), thin_walls: new Set(['north']),
}, },
thinwall_s: { thinwall_s: {
draw_layer: LAYER_OVERLAY,
thin_walls: new Set(['south']), thin_walls: new Set(['south']),
}, },
thinwall_e: { thinwall_e: {
draw_layer: LAYER_OVERLAY,
thin_walls: new Set(['east']), thin_walls: new Set(['east']),
}, },
thinwall_w: { thinwall_w: {
draw_layer: LAYER_OVERLAY,
thin_walls: new Set(['west']), thin_walls: new Set(['west']),
}, },
thinwall_se: { thinwall_se: {
draw_layer: LAYER_OVERLAY,
thin_walls: new Set(['south', 'east']), thin_walls: new Set(['south', 'east']),
}, },
fake_wall: { fake_wall: {
draw_layer: LAYER_TERRAIN,
blocks: true, blocks: true,
on_bump(me, level, other) { on_bump(me, level, other) {
level.transmute_tile(me, 'wall'); level.transmute_tile(me, 'wall');
}, },
}, },
fake_floor: { fake_floor: {
draw_layer: LAYER_TERRAIN,
blocks: true, blocks: true,
on_bump(me, level, other) { on_bump(me, level, other) {
level.transmute_tile(me, 'floor'); level.transmute_tile(me, 'floor');
@ -58,22 +77,29 @@ const TILE_TYPES = {
}, },
// Swivel doors // Swivel doors
swivel_floor: {}, swivel_floor: {
draw_layer: LAYER_TERRAIN,
},
swivel_ne: { swivel_ne: {
draw_layer: LAYER_OVERLAY,
thin_walls: new Set(['north', 'east']), thin_walls: new Set(['north', 'east']),
}, },
swivel_se: { swivel_se: {
draw_layer: LAYER_OVERLAY,
thin_walls: new Set(['south', 'east']), thin_walls: new Set(['south', 'east']),
}, },
swivel_sw: { swivel_sw: {
draw_layer: LAYER_OVERLAY,
thin_walls: new Set(['south', 'west']), thin_walls: new Set(['south', 'west']),
}, },
swivel_nw: { swivel_nw: {
draw_layer: LAYER_OVERLAY,
thin_walls: new Set(['north', 'west']), thin_walls: new Set(['north', 'west']),
}, },
// Locked doors // Locked doors
door_red: { door_red: {
draw_layer: LAYER_TERRAIN,
blocks: true, blocks: true,
on_bump(me, level, other) { on_bump(me, level, other) {
if (other.type.has_inventory && other.take_item('key_red')) { if (other.type.has_inventory && other.take_item('key_red')) {
@ -82,6 +108,7 @@ const TILE_TYPES = {
}, },
}, },
door_blue: { door_blue: {
draw_layer: LAYER_TERRAIN,
blocks: true, blocks: true,
on_bump(me, level, other) { on_bump(me, level, other) {
if (other.type.has_inventory && other.take_item('key_blue')) { if (other.type.has_inventory && other.take_item('key_blue')) {
@ -90,6 +117,7 @@ const TILE_TYPES = {
}, },
}, },
door_yellow: { door_yellow: {
draw_layer: LAYER_TERRAIN,
blocks: true, blocks: true,
on_bump(me, level, other) { on_bump(me, level, other) {
if (other.type.has_inventory && other.take_item('key_yellow')) { if (other.type.has_inventory && other.take_item('key_yellow')) {
@ -98,6 +126,7 @@ const TILE_TYPES = {
}, },
}, },
door_green: { door_green: {
draw_layer: LAYER_TERRAIN,
blocks: true, blocks: true,
on_bump(me, level, other) { on_bump(me, level, other) {
if (other.type.has_inventory && other.take_item('key_green')) { if (other.type.has_inventory && other.take_item('key_green')) {
@ -108,6 +137,7 @@ const TILE_TYPES = {
// Terrain // Terrain
dirt: { dirt: {
draw_layer: LAYER_TERRAIN,
blocks_monsters: true, blocks_monsters: true,
blocks_blocks: true, blocks_blocks: true,
// TODO block melinda only without the hiking boots; can't use ignore because then she wouldn't step on it :S also ignore doesn't apply to blocks anyway. // TODO block melinda only without the hiking boots; can't use ignore because then she wouldn't step on it :S also ignore doesn't apply to blocks anyway.
@ -116,11 +146,13 @@ const TILE_TYPES = {
}, },
}, },
gravel: { gravel: {
draw_layer: LAYER_TERRAIN,
blocks_monsters: true, blocks_monsters: true,
}, },
// Hazards // Hazards
fire: { fire: {
draw_layer: LAYER_TERRAIN,
on_arrive(me, level, other) { on_arrive(me, level, other) {
if (other.type.is_player) { if (other.type.is_player) {
level.fail("Oops! You can't walk on fire without fire boots!"); level.fail("Oops! You can't walk on fire without fire boots!");
@ -132,6 +164,7 @@ const TILE_TYPES = {
}, },
}, },
water: { water: {
draw_layer: LAYER_TERRAIN,
on_arrive(me, level, other) { on_arrive(me, level, other) {
// TODO cc1 allows items under water, i think; water was on the upper layer // TODO cc1 allows items under water, i think; water was on the upper layer
if (other.type.name == 'dirt_block' || other.type.name == 'clone_block') { if (other.type.name == 'dirt_block' || other.type.name == 'clone_block') {
@ -148,11 +181,15 @@ const TILE_TYPES = {
}, },
}, },
turtle: { turtle: {
// XXX well not really because it goes on top of water??
draw_layer: LAYER_TERRAIN,
}, },
ice: { ice: {
draw_layer: LAYER_TERRAIN,
slide_mode: 'ice', slide_mode: 'ice',
}, },
ice_sw: { ice_sw: {
draw_layer: LAYER_TERRAIN,
thin_walls: new Set(['south', 'west']), thin_walls: new Set(['south', 'west']),
slide_mode: 'ice', slide_mode: 'ice',
on_arrive(me, level, other) { on_arrive(me, level, other) {
@ -165,6 +202,7 @@ const TILE_TYPES = {
}, },
}, },
ice_nw: { ice_nw: {
draw_layer: LAYER_TERRAIN,
thin_walls: new Set(['north', 'west']), thin_walls: new Set(['north', 'west']),
slide_mode: 'ice', slide_mode: 'ice',
on_arrive(me, level, other) { on_arrive(me, level, other) {
@ -177,6 +215,7 @@ const TILE_TYPES = {
}, },
}, },
ice_ne: { ice_ne: {
draw_layer: LAYER_TERRAIN,
thin_walls: new Set(['north', 'east']), thin_walls: new Set(['north', 'east']),
slide_mode: 'ice', slide_mode: 'ice',
on_arrive(me, level, other) { on_arrive(me, level, other) {
@ -189,6 +228,7 @@ const TILE_TYPES = {
}, },
}, },
ice_se: { ice_se: {
draw_layer: LAYER_TERRAIN,
thin_walls: new Set(['south', 'east']), thin_walls: new Set(['south', 'east']),
slide_mode: 'ice', slide_mode: 'ice',
on_arrive(me, level, other) { on_arrive(me, level, other) {
@ -201,30 +241,35 @@ const TILE_TYPES = {
}, },
}, },
force_floor_n: { force_floor_n: {
draw_layer: LAYER_TERRAIN,
slide_mode: 'force', slide_mode: 'force',
on_arrive(me, level, other) { on_arrive(me, level, other) {
other.direction = 'north'; other.direction = 'north';
}, },
}, },
force_floor_e: { force_floor_e: {
draw_layer: LAYER_TERRAIN,
slide_mode: 'force', slide_mode: 'force',
on_arrive(me, level, other) { on_arrive(me, level, other) {
other.direction = 'east'; other.direction = 'east';
}, },
}, },
force_floor_s: { force_floor_s: {
draw_layer: LAYER_TERRAIN,
slide_mode: 'force', slide_mode: 'force',
on_arrive(me, level, other) { on_arrive(me, level, other) {
other.direction = 'south'; other.direction = 'south';
}, },
}, },
force_floor_w: { force_floor_w: {
draw_layer: LAYER_TERRAIN,
slide_mode: 'force', slide_mode: 'force',
on_arrive(me, level, other) { on_arrive(me, level, other) {
other.direction = 'west'; other.direction = 'west';
}, },
}, },
force_floor_all: { force_floor_all: {
draw_layer: LAYER_TERRAIN,
slide_mode: 'force', slide_mode: 'force',
// TODO ms: this is random, and an acting wall to monsters (!) // TODO ms: this is random, and an acting wall to monsters (!)
on_arrive(me, level, other) { on_arrive(me, level, other) {
@ -232,6 +277,7 @@ const TILE_TYPES = {
}, },
}, },
bomb: { bomb: {
draw_layer: LAYER_ITEM,
// TODO explode // TODO explode
on_arrive(me, level, other) { on_arrive(me, level, other) {
level.remove_tile(me); level.remove_tile(me);
@ -242,6 +288,7 @@ const TILE_TYPES = {
}, },
}, },
thief_tools: { thief_tools: {
draw_layer: LAYER_TERRAIN,
on_arrive(me, level, other) { on_arrive(me, level, other) {
if (other.inventory) { if (other.inventory) {
for (let [name, count] of Object.entries(other.inventory)) { for (let [name, count] of Object.entries(other.inventory)) {
@ -253,6 +300,7 @@ const TILE_TYPES = {
}, },
}, },
thief_keys: { thief_keys: {
draw_layer: LAYER_TERRAIN,
on_arrive(me, level, other) { on_arrive(me, level, other) {
if (other.inventory) { if (other.inventory) {
for (let [name, count] of Object.entries(other.inventory)) { for (let [name, count] of Object.entries(other.inventory)) {
@ -264,10 +312,12 @@ const TILE_TYPES = {
}, },
}, },
forbidden: { forbidden: {
draw_layer: LAYER_TERRAIN,
}, },
// Mechanisms // Mechanisms
dirt_block: { dirt_block: {
draw_layer: LAYER_ACTOR,
blocks: true, blocks: true,
is_object: true, is_object: true,
is_actor: true, is_actor: true,
@ -275,6 +325,7 @@ const TILE_TYPES = {
ignores: new Set(['fire']), ignores: new Set(['fire']),
}, },
clone_block: { clone_block: {
draw_layer: LAYER_ACTOR,
// TODO is this in any way distinct from dirt block // TODO is this in any way distinct from dirt block
blocks: true, blocks: true,
is_object: true, is_object: true,
@ -282,11 +333,15 @@ const TILE_TYPES = {
is_block: true, is_block: true,
ignores: new Set(['fire']), ignores: new Set(['fire']),
}, },
green_floor: {}, green_floor: {
draw_layer: LAYER_TERRAIN,
},
green_wall: { green_wall: {
draw_layer: LAYER_TERRAIN,
blocks: true, blocks: true,
}, },
cloner: { cloner: {
draw_layer: LAYER_TERRAIN,
blocks: true, blocks: true,
activate(me, level) { activate(me, level) {
let cell = me.cell; let cell = me.cell;
@ -313,6 +368,7 @@ const TILE_TYPES = {
}, },
}, },
trap: { trap: {
draw_layer: LAYER_TERRAIN,
on_arrive(me, level, other) { on_arrive(me, level, other) {
if (! me.open) { if (! me.open) {
level.set_actor_stuck(other, true); level.set_actor_stuck(other, true);
@ -320,6 +376,7 @@ const TILE_TYPES = {
}, },
}, },
teleport_blue: { teleport_blue: {
draw_layer: LAYER_TERRAIN,
connects_to: 'teleport_blue', connects_to: 'teleport_blue',
connect_order: 'backward', connect_order: 'backward',
is_teleporter: true, is_teleporter: true,
@ -327,6 +384,7 @@ const TILE_TYPES = {
}, },
// Buttons // Buttons
button_blue: { button_blue: {
draw_layer: LAYER_TERRAIN,
on_arrive(me, level, other) { on_arrive(me, level, other) {
// Flip direction of all tanks // Flip direction of all tanks
for (let actor of level.actors) { for (let actor of level.actors) {
@ -338,6 +396,7 @@ const TILE_TYPES = {
}, },
}, },
button_green: { button_green: {
draw_layer: LAYER_TERRAIN,
on_arrive(me, level, other) { on_arrive(me, level, other) {
// Swap green floors and walls // Swap green floors and walls
// TODO could probably make this more compact for undo purposes // TODO could probably make this more compact for undo purposes
@ -362,6 +421,7 @@ const TILE_TYPES = {
}, },
}, },
button_brown: { button_brown: {
draw_layer: LAYER_TERRAIN,
connects_to: 'trap', connects_to: 'trap',
connect_order: 'forward', connect_order: 'forward',
on_arrive(me, level, other) { on_arrive(me, level, other) {
@ -388,6 +448,7 @@ const TILE_TYPES = {
}, },
}, },
button_red: { button_red: {
draw_layer: LAYER_TERRAIN,
connects_to: 'cloner', connects_to: 'cloner',
connect_order: 'forward', connect_order: 'forward',
on_arrive(me, level, other) { on_arrive(me, level, other) {
@ -399,6 +460,7 @@ const TILE_TYPES = {
// Critters // Critters
bug: { bug: {
draw_layer: LAYER_ACTOR,
is_actor: true, is_actor: true,
is_object: true, is_object: true,
is_monster: true, is_monster: true,
@ -407,6 +469,7 @@ const TILE_TYPES = {
movement_speed: 4, movement_speed: 4,
}, },
paramecium: { paramecium: {
draw_layer: LAYER_ACTOR,
is_actor: true, is_actor: true,
is_object: true, is_object: true,
is_monster: true, is_monster: true,
@ -415,6 +478,7 @@ const TILE_TYPES = {
movement_speed: 4, movement_speed: 4,
}, },
ball: { ball: {
draw_layer: LAYER_ACTOR,
is_actor: true, is_actor: true,
is_object: true, is_object: true,
is_monster: true, is_monster: true,
@ -423,6 +487,7 @@ const TILE_TYPES = {
movement_speed: 4, movement_speed: 4,
}, },
walker: { walker: {
draw_layer: LAYER_ACTOR,
is_actor: true, is_actor: true,
is_object: true, is_object: true,
is_monster: true, is_monster: true,
@ -431,6 +496,7 @@ const TILE_TYPES = {
movement_speed: 4, movement_speed: 4,
}, },
tank_blue: { tank_blue: {
draw_layer: LAYER_ACTOR,
is_actor: true, is_actor: true,
is_object: true, is_object: true,
is_monster: true, is_monster: true,
@ -439,6 +505,7 @@ const TILE_TYPES = {
movement_speed: 4, movement_speed: 4,
}, },
blob: { blob: {
draw_layer: LAYER_ACTOR,
is_actor: true, is_actor: true,
is_object: true, is_object: true,
is_monster: true, is_monster: true,
@ -447,6 +514,7 @@ const TILE_TYPES = {
movement_speed: 8, movement_speed: 8,
}, },
teeth: { teeth: {
draw_layer: LAYER_ACTOR,
is_actor: true, is_actor: true,
is_object: true, is_object: true,
is_monster: true, is_monster: true,
@ -456,6 +524,7 @@ const TILE_TYPES = {
uses_teeth_hesitation: true, uses_teeth_hesitation: true,
}, },
fireball: { fireball: {
draw_layer: LAYER_ACTOR,
is_actor: true, is_actor: true,
is_object: true, is_object: true,
is_monster: true, is_monster: true,
@ -465,6 +534,7 @@ const TILE_TYPES = {
ignores: new Set(['fire']), ignores: new Set(['fire']),
}, },
glider: { glider: {
draw_layer: LAYER_ACTOR,
is_actor: true, is_actor: true,
is_object: true, is_object: true,
is_monster: true, is_monster: true,
@ -476,33 +546,39 @@ const TILE_TYPES = {
// Keys // Keys
key_red: { key_red: {
draw_layer: LAYER_ITEM,
is_object: true, is_object: true,
is_item: true, is_item: true,
is_key: true, is_key: true,
}, },
key_blue: { key_blue: {
draw_layer: LAYER_ITEM,
is_object: true, is_object: true,
is_item: true, is_item: true,
is_key: true, is_key: true,
}, },
key_yellow: { key_yellow: {
draw_layer: LAYER_ITEM,
is_object: true, is_object: true,
is_item: true, is_item: true,
is_key: true, is_key: true,
}, },
key_green: { key_green: {
draw_layer: LAYER_ITEM,
is_object: true, is_object: true,
is_item: true, is_item: true,
is_key: true, is_key: true,
}, },
// Tools // Tools
cleats: { cleats: {
draw_layer: LAYER_ITEM,
is_object: true, is_object: true,
is_item: true, is_item: true,
is_tool: true, is_tool: true,
item_ignores: new Set(['ice', 'ice_nw', 'ice_ne', 'ice_sw', 'ice_se']), item_ignores: new Set(['ice', 'ice_nw', 'ice_ne', 'ice_sw', 'ice_se']),
}, },
suction_boots: { suction_boots: {
draw_layer: LAYER_ITEM,
is_object: true, is_object: true,
is_item: true, is_item: true,
is_tool: true, is_tool: true,
@ -514,12 +590,14 @@ const TILE_TYPES = {
]), ]),
}, },
fire_boots: { fire_boots: {
draw_layer: LAYER_ITEM,
is_object: true, is_object: true,
is_item: true, is_item: true,
is_tool: true, is_tool: true,
item_ignores: new Set(['fire']), item_ignores: new Set(['fire']),
}, },
flippers: { flippers: {
draw_layer: LAYER_ITEM,
is_object: true, is_object: true,
is_item: true, is_item: true,
is_tool: true, is_tool: true,
@ -528,6 +606,7 @@ const TILE_TYPES = {
// Progression // Progression
player: { player: {
draw_layer: LAYER_ACTOR,
is_actor: true, is_actor: true,
is_player: true, is_player: true,
has_inventory: true, has_inventory: true,
@ -543,10 +622,13 @@ const TILE_TYPES = {
}, },
}, },
player_drowned: { player_drowned: {
draw_layer: LAYER_ACTOR,
}, },
player_burned: { player_burned: {
draw_layer: LAYER_ACTOR,
}, },
chip: { chip: {
draw_layer: LAYER_ITEM,
is_object: true, is_object: true,
is_chip: true, is_chip: true,
is_required_chip: true, is_required_chip: true,
@ -560,6 +642,7 @@ const TILE_TYPES = {
}, },
}, },
chip_extra: { chip_extra: {
draw_layer: LAYER_ITEM,
is_chip: true, is_chip: true,
is_object: true, is_object: true,
blocks_monsters: true, blocks_monsters: true,
@ -572,22 +655,28 @@ const TILE_TYPES = {
}, },
}, },
score_10: { score_10: {
draw_layer: LAYER_ITEM,
is_object: true, is_object: true,
}, },
score_100: { score_100: {
draw_layer: LAYER_ITEM,
is_object: true, is_object: true,
}, },
score_1000: { score_1000: {
draw_layer: LAYER_ITEM,
is_object: true, is_object: true,
}, },
score_2x: { score_2x: {
draw_layer: LAYER_ITEM,
is_object: true, is_object: true,
}, },
hint: { hint: {
draw_layer: LAYER_TERRAIN,
is_hint: true, is_hint: true,
}, },
socket: { socket: {
draw_layer: LAYER_TERRAIN,
blocks: true, blocks: true,
on_bump(me, level, other) { on_bump(me, level, other) {
if (other.type.is_player && level.chips_remaining === 0) { if (other.type.is_player && level.chips_remaining === 0) {
@ -596,6 +685,7 @@ const TILE_TYPES = {
}, },
}, },
exit: { exit: {
draw_layer: LAYER_TERRAIN,
on_arrive(me, level, other) { on_arrive(me, level, other) {
if (other.type.is_player) { if (other.type.is_player) {
level.win(); level.win();
@ -607,6 +697,13 @@ const TILE_TYPES = {
// Tell them all their own names // Tell them all their own names
for (let [name, type] of Object.entries(TILE_TYPES)) { for (let [name, type] of Object.entries(TILE_TYPES)) {
type.name = name; type.name = name;
if (type.draw_layer === undefined ||
type.draw_layer !== Math.floor(type.draw_layer) ||
type.draw_layer >= 4)
{
console.error(`Tile type ${name} has a bad draw layer`);
}
} }
export default TILE_TYPES; export default TILE_TYPES;