Skip to content

Instantly share code, notes, and snippets.

@damncabbage
Created September 20, 2018 11:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save damncabbage/aa46cdc494dd1cf49cbfbc5922376de0 to your computer and use it in GitHub Desktop.
Save damncabbage/aa46cdc494dd1cf49cbfbc5922376de0 to your computer and use it in GitHub Desktop.
import Phaser from "phaser";
import tiny_dungeon from "../assets/tiny_dungeon_world.png";
import DungeonFactory from "dungeon-factory";
import Mrpas from "mrpas";
const width = 61;
const height = 41;
const Tiles = {
World: {
Black: 0x60,
Wall: {
Brown: {
Horizontal: [0x10, 0x10, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15],
Vertical: [0x16, 0x16, 0x17, 0x18, 0x19]
}
},
Floor: {
Dirt: [0x50, 0x51, 0x52, 0x53, 0x54, 0x55],
Stone: [0x40, 0x40, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45]
},
Door: {
Stone: {
Horizontal: 0xb0,
Vertical: 0xb2
}
}
}
};
function randomTile(tiles: Array<number>): number {
return tiles[Math.floor(Math.random() * tiles.length)];
}
class DefaultScene extends Phaser.Scene {
preload(): void {
this.load.image("tiles", tiny_dungeon);
}
create(): void {
const dungeon = DungeonFactory.generate({
width: height,
height: width
}) as { tiles: Array<Array<any>> };
console.log(dungeon);
const walls = dungeon.tiles.map(row =>
row.map(tile => tile.type === "wall")
);
const map = this.make.tilemap({
tileWidth: 16,
tileHeight: 16,
width: width,
height: height
});
const tiles = map.addTilesetImage("tiles");
const groundLayer = map
.createBlankDynamicLayer("Ground", tiles, 0, 0)
.randomize(0, 0, width, height, Tiles.World.Floor.Stone);
const wallLayer = map.createBlankDynamicLayer("Wall", tiles, 0, 0);
const darkLayer = map
.createBlankDynamicLayer("Dark", tiles, 0, 0)
.fill(Tiles.World.Black);
const fov = new Mrpas(width, height, (x: number, y: number) => {
return walls[y] && !walls[y][x];
});
for (let x = 0; x < width; x++) {
for (let y = 0; y < height; y++) {
const tile = dungeon.tiles[y][x] as any;
if (tile.type === "wall") {
let idx = 0;
if (tile.nesw.east && tile.nesw.east.type !== "wall") {
idx = randomTile(Tiles.World.Wall.Brown.Horizontal);
} else {
idx = randomTile(Tiles.World.Wall.Brown.Vertical);
}
wallLayer.putTileAt(idx, x, y);
}
}
}
this.input.on("pointermove", (pointer: any) => {
const x = Math.floor(pointer.x / 16);
const y = Math.floor(pointer.y / 16);
darkLayer.forEachTile(
t => {
t.alpha = t.alpha < 1 ? 0.7 : 1;
},
this,
0,
0,
width,
height
);
fov.compute(
x,
y,
7,
(x, y) => {
return darkLayer.getTileAt(x, y).alpha < 1;
},
(x, y) => {
darkLayer.getTileAt(x, y).alpha = 0;
}
);
});
const content = [
"Phaser 3 tilemap & FOV experiment.",
"",
"Move mouse over black areas to reveal map!",
"",
"Dungeon generation via npmjs.com/package/dungeon-factory",
"FOV calculation via npmjs.com/package/mrpas",
"Tileset https://www.oryxdesignlab.com/products/tiny-dungeon-tileset"
];
this.add.text(25, 25, content, {
fontFamily: "sans-serif",
color: "#ffffff"
});
}
}
class ReferenceScene extends Phaser.Scene {
preload(): void {
this.load.image("tiles", tiny_dungeon);
}
create(): void {
let level: Array<Array<number>> = [];
for (let y = 0; y < 19; y++) {
level[y] = [];
for (let x = 0; x < 16; x++) {
const idx = y * 16 + x;
level[y][x] = idx;
const text = this.add.text(x * 32, y * 32, idx.toString(16), {
fontSize: 14
});
text.setDepth(10);
}
}
const map = this.make.tilemap({
data: level,
tileWidth: 16,
tileHeight: 16
});
const tiles = map.addTilesetImage("tiles");
const layer = map.createStaticLayer(0, tiles, 0, 0);
layer.setScale(2);
}
}
new Phaser.Game({
type: Phaser.AUTO,
width: width * 16,
height: height * 16,
render: { pixelArt: true },
physics: { default: "arcade", arcade: { gravity: { y: 0 } } },
scene: [DefaultScene]
// scene: [ReferenceScene]
});
function setUpHotReload() {
// @ts-ignore
if (module.hot) {
// @ts-ignore
module.hot.accept(() => {});
// @ts-ignore
module.hot.dispose(() => {
window.location.reload();
});
}
}
setUpHotReload();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment