-
-
Save damncabbage/aa46cdc494dd1cf49cbfbc5922376de0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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