map editor
This commit is contained in:
parent
44334fc385
commit
113c6d105a
15 changed files with 344 additions and 26 deletions
21
client/css/editor.css
Normal file
21
client/css/editor.css
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
canvas {
|
||||||
|
box-shadow: inset 0 0 1px red;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar {
|
||||||
|
background-color: #191919;
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
border: 1px solid;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mapgen {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
#export {
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
|
@ -70,4 +70,9 @@ input {
|
||||||
border: solid 2px #fff;
|
border: solid 2px #fff;
|
||||||
padding: .25rem;
|
padding: .25rem;
|
||||||
margin-bottom: .215rem;
|
margin-bottom: .215rem;
|
||||||
|
box-sizing:content-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
padding: .25rem;
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 8 KiB |
|
@ -11,7 +11,7 @@
|
||||||
<div id="center">
|
<div id="center">
|
||||||
<form id="join" autocomplete="off">
|
<form id="join" autocomplete="off">
|
||||||
<input type="text" id="room_code" name="room_code" placeholder="Room Code">
|
<input type="text" id="room_code" name="room_code" placeholder="Room Code">
|
||||||
<input type="text" id="name" name="name" placeholder="Player Name">
|
<input type="text" id="player_name" name="name" placeholder="Player Name">
|
||||||
<input type="submit" value="Join!"/>
|
<input type="submit" value="Join!"/>
|
||||||
</form>
|
</form>
|
||||||
<div id="lobby">
|
<div id="lobby">
|
||||||
|
|
|
@ -17,8 +17,8 @@ lobby.style.display = "none";
|
||||||
join.onsubmit = function (event) {
|
join.onsubmit = function (event) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const room_code = this.elements.room_code.value.trim();
|
const room_code = document.getElementById("room_code").value;
|
||||||
const player_name = this.elements.name.value.trim();
|
const player_name = document.getElementById("player_name").value;
|
||||||
if (room_code == '') {
|
if (room_code == '') {
|
||||||
alert('Please enter a room code');
|
alert('Please enter a room code');
|
||||||
return;
|
return;
|
||||||
|
|
35
client/mapeditor.html
Normal file
35
client/mapeditor.html
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="css/main.css"/>
|
||||||
|
<link rel="stylesheet" href="css/editor.css"/>
|
||||||
|
<script>var exports = {};</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<img src="img/atlas.png" id="atlas" style="display: none;"/>
|
||||||
|
<canvas id="canvas" style="display: none;"></canvas>
|
||||||
|
<style id="style"></style>
|
||||||
|
<div id="center">
|
||||||
|
<form id="mapgen" autocomplete="off">
|
||||||
|
<input type="text" id="width" name="width" placeholder="Map Width">
|
||||||
|
<input type="text" id="height" name="height" placeholder="Map Height">
|
||||||
|
<input type="submit" value="Create"/>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div id="sidebar">
|
||||||
|
<p>W: Place Wall</p>
|
||||||
|
<p>G: Place Ghost Wall</p>
|
||||||
|
<p>F: Place Food</p>
|
||||||
|
<p>1: Place Pac Spawn 1</p>
|
||||||
|
<p>2: Place Pac Spawn 2</p>
|
||||||
|
<p>3: Place Pac Spawn 3</p>
|
||||||
|
<p>4: Place Pac Spawn 4</p>
|
||||||
|
<p>T: Place THICC Dot</p>
|
||||||
|
<p>I: Place Initial Dot</p>
|
||||||
|
<p>C: Clear Tile</p>
|
||||||
|
<p>Q: Toggle Sidebar</p>
|
||||||
|
<input type="button" id="export" value="Export Map">
|
||||||
|
</div>
|
||||||
|
<script src="js/editor.js" type="module"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
166
client/src/editor.ts
Normal file
166
client/src/editor.ts
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
import { genMap } from "./map.js"
|
||||||
|
import { startGraphicsUpdater } from "./renderer.js"
|
||||||
|
import { GameState, Vec2, ATLAS_TILE_WIDTH, Tile } from "./types.js"
|
||||||
|
|
||||||
|
const mapgen = document.getElementById("mapgen")
|
||||||
|
const sidebar = document.getElementById("sidebar")
|
||||||
|
sidebar.style.display = "none"
|
||||||
|
|
||||||
|
mapgen.onsubmit = async function(event) {
|
||||||
|
event.preventDefault()
|
||||||
|
|
||||||
|
const width_str = (<HTMLInputElement>document.getElementById("width")).value
|
||||||
|
const height_str = (<HTMLInputElement>document.getElementById("height")).value
|
||||||
|
|
||||||
|
const width = parseInt(width_str)
|
||||||
|
const height = parseInt(height_str)
|
||||||
|
|
||||||
|
if (!width || width < 3 || !height || height < 3) {
|
||||||
|
alert('Invalid numbers or dimensions too small')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
mapgen.style.display = "none"
|
||||||
|
|
||||||
|
runMapEditor(width, height)
|
||||||
|
}
|
||||||
|
|
||||||
|
const startKeyListener = () => {
|
||||||
|
|
||||||
|
let keys = {}
|
||||||
|
|
||||||
|
window.addEventListener("keydown", ev => {
|
||||||
|
if(ev.repeat) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ev.code == "KeyQ") {
|
||||||
|
if (sidebar.style.display === "none") {
|
||||||
|
sidebar.style.display = ""
|
||||||
|
} else {
|
||||||
|
sidebar.style.display = "none"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
keys[ev.code] = true
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener("keyup", ev => {
|
||||||
|
if (ev.repeat) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
keys[ev.code] = false
|
||||||
|
})
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
return keys
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const trackMouseMovement = () => {
|
||||||
|
|
||||||
|
let pos: Vec2 = {x : 0, y: 0}
|
||||||
|
|
||||||
|
window.addEventListener("mousemove", ev => {
|
||||||
|
pos = {x: ev.x, y: ev.y}
|
||||||
|
})
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
return pos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getTilePos = (width: number, height: number, mousePos: Vec2): Vec2 => {
|
||||||
|
|
||||||
|
const canvas = document.getElementById("canvas") as HTMLCanvasElement
|
||||||
|
|
||||||
|
const canvasRect = canvas.getBoundingClientRect()
|
||||||
|
|
||||||
|
let posX = mousePos.x - canvasRect.x
|
||||||
|
let posY = mousePos.y - canvasRect.y
|
||||||
|
|
||||||
|
let percentX = posX / canvasRect.width
|
||||||
|
let percentY = posY / canvasRect.height
|
||||||
|
|
||||||
|
return {
|
||||||
|
x: Math.floor(percentX * width),
|
||||||
|
y: Math.floor(percentY * height)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkInputs = (pressed: {[key: string]: boolean}): Tile => {
|
||||||
|
|
||||||
|
if (pressed["KeyW"]) {
|
||||||
|
return Tile.WALL
|
||||||
|
} else if (pressed["KeyG"]) {
|
||||||
|
return Tile.GHOST_WALL
|
||||||
|
} else if (pressed["KeyF"]) {
|
||||||
|
return Tile.FOOD
|
||||||
|
} else if (pressed["Digit1"]) {
|
||||||
|
return Tile.PLAYER_SPAWN_1
|
||||||
|
} else if (pressed["Digit2"]) {
|
||||||
|
return Tile.PLAYER_SPAWN_2
|
||||||
|
} else if (pressed["Digit3"]) {
|
||||||
|
return Tile.PLAYER_SPAWN_3
|
||||||
|
} else if (pressed["Digit4"]) {
|
||||||
|
return Tile.PLAYER_SPAWN_4
|
||||||
|
} else if (pressed["KeyT"]) {
|
||||||
|
return Tile.THICC_DOT
|
||||||
|
} else if (pressed["KeyI"]) {
|
||||||
|
return Tile.INITIAL_DOT
|
||||||
|
} else if (pressed["KeyC"]) {
|
||||||
|
return Tile.EMPTY
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkBounds = (tilePos: Vec2, width: number, height: number) => {
|
||||||
|
if (tilePos.x < 0 || tilePos.x >= width || tilePos.y < 0 || tilePos.y >= height) return false
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
const runMapEditor = (width: number, height: number) => {
|
||||||
|
|
||||||
|
sidebar.style.display = ""
|
||||||
|
|
||||||
|
let data: number[] = new Array(width * height).fill(0)
|
||||||
|
|
||||||
|
genMap(width, height, data, Tile.EMPTY)
|
||||||
|
|
||||||
|
let state: GameState = {
|
||||||
|
started: true,
|
||||||
|
input: {},
|
||||||
|
players: {},
|
||||||
|
items: {},
|
||||||
|
mapId: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
let frame = 0
|
||||||
|
const updateGraphics = startGraphicsUpdater()
|
||||||
|
const getInput = startKeyListener()
|
||||||
|
const getMousePos = trackMouseMovement()
|
||||||
|
|
||||||
|
const loop = () => {
|
||||||
|
|
||||||
|
const mousePos = getMousePos()
|
||||||
|
const tilePos = getTilePos(width, height, mousePos)
|
||||||
|
|
||||||
|
const pressed = getInput()
|
||||||
|
const tile = checkInputs(pressed)
|
||||||
|
|
||||||
|
if (tile !== undefined && checkBounds(tilePos, width, height)) {
|
||||||
|
let current = data[tilePos.y * width + tilePos.x];
|
||||||
|
if (current != tile) {
|
||||||
|
data[tilePos.y * width + tilePos.x] = tile
|
||||||
|
genMap(width, height, data, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateGraphics(state, frame, true)
|
||||||
|
|
||||||
|
requestAnimationFrame(loop)
|
||||||
|
}
|
||||||
|
|
||||||
|
requestAnimationFrame(loop)
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
import { getMap } from "../map.js"
|
import { getMap } from "../map.js"
|
||||||
import { Vec2, Map, Rotation, Key, Player, GameState } from "../types.js"
|
import { Vec2, Map, Rotation, Key, Player, GameState, Tile } from "../types.js"
|
||||||
|
|
||||||
const MOVE_SPEED = .1
|
const MOVE_SPEED = .1
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ const getTile = (
|
||||||
): number => {
|
): number => {
|
||||||
let x = Math.round(pos.x + ox)
|
let x = Math.round(pos.x + ox)
|
||||||
let y = Math.round(pos.y + oy)
|
let y = Math.round(pos.y + oy)
|
||||||
if (x < 0 || x >= map.width || y < 0 || y >= map.height) return 1
|
if (x < 0 || x >= map.width || y < 0 || y >= map.height) return Tile.WALL
|
||||||
return map.data[y * map.width + x]
|
return map.data[y * map.width + x]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,13 +73,11 @@ const incrementPos = (
|
||||||
pos.x -= speed
|
pos.x -= speed
|
||||||
break
|
break
|
||||||
case Rotation.EAST:
|
case Rotation.EAST:
|
||||||
pos.y += speed
|
pos.x += speed
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let i = 0
|
|
||||||
|
|
||||||
const updateMovementForPlayer = (
|
const updateMovementForPlayer = (
|
||||||
map: Map,
|
map: Map,
|
||||||
player: Player,
|
player: Player,
|
||||||
|
@ -91,7 +89,7 @@ const updateMovementForPlayer = (
|
||||||
let currentPosition = player.pos
|
let currentPosition = player.pos
|
||||||
|
|
||||||
let turningFrontTile = getTileFrontWithRot(map, currentPosition, inputRot)
|
let turningFrontTile = getTileFrontWithRot(map, currentPosition, inputRot)
|
||||||
if (turningFrontTile == 1 || turningFrontTile == 2) {
|
if (turningFrontTile == Tile.WALL || turningFrontTile == Tile.GHOST_WALL) {
|
||||||
inputRot = Rotation.NOTHING
|
inputRot = Rotation.NOTHING
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +107,7 @@ const updateMovementForPlayer = (
|
||||||
incrementPos(movePos, moveRot, MOVE_SPEED)
|
incrementPos(movePos, moveRot, MOVE_SPEED)
|
||||||
|
|
||||||
let frontTile = getTileFrontWithRot(map, currentPosition, moveRot)
|
let frontTile = getTileFrontWithRot(map, currentPosition, moveRot)
|
||||||
if (frontTile != 1 && frontTile != 2) {
|
if (frontTile != Tile.WALL && frontTile != Tile.GHOST_WALL) {
|
||||||
player.pos = movePos
|
player.pos = movePos
|
||||||
player.moving = true
|
player.moving = true
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -33,7 +33,7 @@ export const updatePlayers = (data: GameState, input: Input) => {
|
||||||
data.players[added] ||= {
|
data.players[added] ||= {
|
||||||
pos: {x: 1, y: 1},
|
pos: {x: 1, y: 1},
|
||||||
inputRotation: Rotation.EAST,
|
inputRotation: Rotation.EAST,
|
||||||
moveRotation: Rotation.EAST,
|
moveRotation: Rotation.NOTHING,
|
||||||
moving: false,
|
moving: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,8 @@ lobby.style.display = "none"
|
||||||
join.onsubmit = async function(event) {
|
join.onsubmit = async function(event) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
|
||||||
const room_code = this.elements.room_code.value.trim()
|
const room_code = (<HTMLInputElement>document.getElementById("room_code")).value
|
||||||
const player_name = this.elements.name.value.trim()
|
const player_name = (<HTMLInputElement>document.getElementById("player_name")).value
|
||||||
|
|
||||||
if (room_code == '') {
|
if (room_code == '') {
|
||||||
alert('Please enter a room code')
|
alert('Please enter a room code')
|
||||||
|
|
|
@ -126,6 +126,24 @@ export const genItems = (map: Map): Items => {
|
||||||
let mapData: Maps = {}
|
let mapData: Maps = {}
|
||||||
let id: number = 0
|
let id: number = 0
|
||||||
|
|
||||||
|
export const genMap = (
|
||||||
|
width: number,
|
||||||
|
height: number,
|
||||||
|
data: number[],
|
||||||
|
mapId: number,
|
||||||
|
): Map => {
|
||||||
|
|
||||||
|
mapData[mapId] = {
|
||||||
|
data: structuredClone(data),
|
||||||
|
walls: genWalls(width, height, data),
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
id: mapId
|
||||||
|
}
|
||||||
|
|
||||||
|
return mapData[mapId]
|
||||||
|
}
|
||||||
|
|
||||||
export const loadMap = (
|
export const loadMap = (
|
||||||
width: number,
|
width: number,
|
||||||
height: number,
|
height: number,
|
||||||
|
|
|
@ -52,7 +52,6 @@ export class Game {
|
||||||
* If the frame is ahead of the current latest frame, the game will be run until that frame.
|
* If the frame is ahead of the current latest frame, the game will be run until that frame.
|
||||||
*/
|
*/
|
||||||
setInput(frame: number, input: Input) {
|
setInput(frame: number, input: Input) {
|
||||||
console.log('input', frame, input)
|
|
||||||
this.editFrame(frame, (index: number): void => {
|
this.editFrame(frame, (index: number): void => {
|
||||||
let past = this.history[index - 1];
|
let past = this.history[index - 1];
|
||||||
if(index === 0) {
|
if(index === 0) {
|
||||||
|
@ -66,7 +65,6 @@ export class Game {
|
||||||
}
|
}
|
||||||
|
|
||||||
setData(frame: number, data: GameState) {
|
setData(frame: number, data: GameState) {
|
||||||
console.log('data', frame, data)
|
|
||||||
this.editFrame(frame, (index: number): void => {
|
this.editFrame(frame, (index: number): void => {
|
||||||
this.history[index] = {
|
this.history[index] = {
|
||||||
data,
|
data,
|
||||||
|
|
|
@ -80,7 +80,7 @@ export function multiplayer(
|
||||||
function update(input: PlayerInput, frame: number) {
|
function update(input: PlayerInput, frame: number) {
|
||||||
if(input === undefined) { // used to update the game locally
|
if(input === undefined) { // used to update the game locally
|
||||||
if(hasState) {
|
if(hasState) {
|
||||||
applyInput({})
|
applyInput({frame})
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import { getMap } from "./map.js";
|
import { getMap } from "./map.js";
|
||||||
import { Items, Players, Rotation, ItemType, Map, Wall, GameState } from "./types.js";
|
import { Items, Players, Rotation, ItemType, Map, Wall, GameState, Tile, ATLAS_TILE_WIDTH } from "./types.js";
|
||||||
|
|
||||||
const ATLAS_TILE_WIDTH = 32
|
|
||||||
|
|
||||||
const update_style = (width: number, height: number) => {
|
const update_style = (width: number, height: number) => {
|
||||||
|
|
||||||
|
@ -257,20 +255,82 @@ const draw_map_canvas = (
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const draw_debug_sprites = (
|
||||||
|
ctx: CanvasRenderingContext2D,
|
||||||
|
atlas: CanvasImageSource,
|
||||||
|
map: Map
|
||||||
|
) => {
|
||||||
|
|
||||||
|
for (let y = 0; y < map.height; y++) {
|
||||||
|
for (let x = 0; x < map.width; x++) {
|
||||||
|
|
||||||
|
let tile_type = map.data[y * map.width + x]
|
||||||
|
|
||||||
|
|
||||||
|
let atlas_index: [number, number];
|
||||||
|
switch (tile_type) {
|
||||||
|
case Tile.EMPTY:
|
||||||
|
case Tile.WALL:
|
||||||
|
continue
|
||||||
|
case Tile.GHOST_WALL:
|
||||||
|
atlas_index = [4, 0]
|
||||||
|
break
|
||||||
|
case Tile.FOOD:
|
||||||
|
atlas_index = [3, 0]
|
||||||
|
break
|
||||||
|
case Tile.PLAYER_SPAWN_1:
|
||||||
|
atlas_index = [3, 1]
|
||||||
|
break
|
||||||
|
case Tile.PLAYER_SPAWN_2:
|
||||||
|
atlas_index = [4, 1]
|
||||||
|
break
|
||||||
|
case Tile.PLAYER_SPAWN_3:
|
||||||
|
atlas_index = [3, 2]
|
||||||
|
break
|
||||||
|
case Tile.PLAYER_SPAWN_4:
|
||||||
|
atlas_index = [4, 2]
|
||||||
|
break
|
||||||
|
case Tile.THICC_DOT:
|
||||||
|
atlas_index = [4, 3]
|
||||||
|
break
|
||||||
|
case Tile.INITIAL_DOT:
|
||||||
|
atlas_index = [3, 3]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_sprite (
|
||||||
|
ctx,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
1,
|
||||||
|
atlas,
|
||||||
|
atlas_index,
|
||||||
|
ATLAS_TILE_WIDTH,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let map_canvas = document.createElement("canvas")
|
let map_canvas = document.createElement("canvas")
|
||||||
const draw_map = (
|
const draw_map = (
|
||||||
ctx: CanvasRenderingContext2D,
|
ctx: CanvasRenderingContext2D,
|
||||||
atlas: CanvasImageSource,
|
atlas: CanvasImageSource,
|
||||||
map: Map,
|
map: Map,
|
||||||
last: number | undefined
|
last: number | undefined,
|
||||||
|
editor: boolean
|
||||||
) => {
|
) => {
|
||||||
|
|
||||||
if (map.id !== last) {
|
if (map.id !== last || editor) {
|
||||||
map_canvas.width = map.width * ATLAS_TILE_WIDTH
|
map_canvas.width = map.width * ATLAS_TILE_WIDTH
|
||||||
map_canvas.height = map.height * ATLAS_TILE_WIDTH
|
map_canvas.height = map.height * ATLAS_TILE_WIDTH
|
||||||
|
|
||||||
let map_ctx = map_canvas.getContext("2d")
|
let map_ctx = map_canvas.getContext("2d")
|
||||||
draw_map_canvas(map_ctx, atlas, map)
|
draw_map_canvas(map_ctx, atlas, map)
|
||||||
|
if (editor) {
|
||||||
|
draw_debug_sprites(map_ctx, atlas, map)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.drawImage (
|
ctx.drawImage (
|
||||||
|
@ -292,7 +352,8 @@ export const startGraphicsUpdater = () => {
|
||||||
*/
|
*/
|
||||||
return (
|
return (
|
||||||
data: GameState,
|
data: GameState,
|
||||||
frame: number
|
frame: number,
|
||||||
|
editor: boolean = false
|
||||||
) => {
|
) => {
|
||||||
|
|
||||||
let map = getMap(data.mapId)
|
let map = getMap(data.mapId)
|
||||||
|
@ -308,7 +369,7 @@ export const startGraphicsUpdater = () => {
|
||||||
let ctx = canvas.getContext("2d")
|
let ctx = canvas.getContext("2d")
|
||||||
ctx.clearRect(0, 0, canvas.width, canvas.height)
|
ctx.clearRect(0, 0, canvas.width, canvas.height)
|
||||||
|
|
||||||
draw_map(ctx, atlas, map, last_map_drawn)
|
draw_map(ctx, atlas, map, last_map_drawn, editor)
|
||||||
draw_items(ctx, atlas, data.items)
|
draw_items(ctx, atlas, data.items)
|
||||||
draw_players(ctx, atlas, data.players, frame)
|
draw_players(ctx, atlas, data.players, frame)
|
||||||
update_style(map.width, map.height)
|
update_style(map.width, map.height)
|
||||||
|
|
|
@ -1,4 +1,20 @@
|
||||||
|
|
||||||
|
export const ATLAS_TILE_WIDTH = 32
|
||||||
|
|
||||||
|
export enum Tile {
|
||||||
|
EMPTY,
|
||||||
|
WALL,
|
||||||
|
GHOST_WALL,
|
||||||
|
FOOD,
|
||||||
|
PLAYER_SPAWN_1,
|
||||||
|
PLAYER_SPAWN_2,
|
||||||
|
PLAYER_SPAWN_3,
|
||||||
|
PLAYER_SPAWN_4,
|
||||||
|
GHOST_SPAWN,
|
||||||
|
THICC_DOT,
|
||||||
|
INITIAL_DOT
|
||||||
|
}
|
||||||
|
|
||||||
export enum Wall {
|
export enum Wall {
|
||||||
EMPTY,
|
EMPTY,
|
||||||
WALL_HZ,
|
WALL_HZ,
|
||||||
|
@ -63,8 +79,8 @@ export type Player = {
|
||||||
pos: Vec2,
|
pos: Vec2,
|
||||||
moveRotation: Rotation,
|
moveRotation: Rotation,
|
||||||
inputRotation: Rotation,
|
inputRotation: Rotation,
|
||||||
name?: string,
|
moving: boolean,
|
||||||
moving: boolean
|
name?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PlayerInput = {
|
export type PlayerInput = {
|
||||||
|
|
Loading…
Reference in a new issue