custom map overrides
This commit is contained in:
parent
c66865d431
commit
484409b64d
10 changed files with 115 additions and 45 deletions
|
@ -24,29 +24,3 @@ canvas {
|
|||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
#popup {
|
||||
background-color: #191919;
|
||||
position: absolute;
|
||||
flex-direction: column;
|
||||
padding: .5rem;
|
||||
border: 1px solid #fff;
|
||||
}
|
||||
|
||||
#popup textarea {
|
||||
margin: .5rem 0;
|
||||
height: 5rem;
|
||||
background-color: transparent;
|
||||
color: white;
|
||||
border: 1px solid #fff;
|
||||
}
|
||||
|
||||
#popup input {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#close {
|
||||
width: .3rem;
|
||||
height: .3rem;
|
||||
font-size: .6rem;
|
||||
line-height: 0;
|
||||
}
|
||||
|
|
|
@ -23,16 +23,16 @@ body {
|
|||
}
|
||||
|
||||
#center-inner {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-left: calc(50% - 20rem / 2);
|
||||
max-width: 20rem;
|
||||
}
|
||||
|
||||
#mapeditor {
|
||||
#custommaps, #mapeditor {
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
|
@ -87,3 +87,31 @@ input {
|
|||
p {
|
||||
padding: .25rem;
|
||||
}
|
||||
|
||||
#popup {
|
||||
background-color: #191919;
|
||||
position: absolute;
|
||||
flex-direction: column;
|
||||
padding: .5rem;
|
||||
border: 1px solid #fff;
|
||||
width: 19rem;
|
||||
}
|
||||
|
||||
#popup textarea {
|
||||
margin: .5rem 0;
|
||||
height: 5rem;
|
||||
background-color: transparent;
|
||||
color: white;
|
||||
border: 1px solid #fff;
|
||||
}
|
||||
|
||||
#popup input {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#close {
|
||||
width: .3rem;
|
||||
height: .3rem;
|
||||
font-size: .6rem;
|
||||
line-height: 0;
|
||||
}
|
||||
|
|
|
@ -14,12 +14,24 @@
|
|||
<input type="text" id="player_name" name="name" placeholder="Player Name">
|
||||
<input type="submit" value="Join!"/>
|
||||
</form>
|
||||
<input id="custommaps" type="button" value="Custom Map Overrides">
|
||||
<input id="mapeditor" type="button" value="Map Editor">
|
||||
<div id="lobby" style="display: none;">
|
||||
<span>Players:</span>
|
||||
<div id="players"></div>
|
||||
<input type="button" id="start" value="Start Game"/>
|
||||
</div>
|
||||
<div id="popup" style="display: none">
|
||||
<input type="button" id="close" value="x" style='margin-bottom: .5rem' onclick="document.getElementById('popup').style.display = 'none'">
|
||||
Map 1
|
||||
<textarea id="map1"></textarea>
|
||||
Map 2
|
||||
<textarea id="map2"></textarea>
|
||||
Map 3
|
||||
<textarea id="map3"> </textarea>
|
||||
Map 4
|
||||
<textarea id="map4"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="js/main.js" type="module"></script>
|
||||
|
|
|
@ -33,10 +33,17 @@ export const onLogic = (
|
|||
data.frame = frame
|
||||
random(data)
|
||||
|
||||
let startPressed = updatePlayers(data, input);
|
||||
let startPressed = updatePlayers(data, input)
|
||||
|
||||
let playersLeft = 0
|
||||
for (let id in data.players) {
|
||||
|
||||
let player = data.players[id]
|
||||
|
||||
if (!player) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (player.dead) {
|
||||
player.framesDead++
|
||||
} else {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { GameState, Input, Key, Rotation } from "../types.js"
|
||||
import { checkMap, decompressMap, genMap } from "../map.js"
|
||||
import { GAME_MAP_COUNT, GameState, Input, Key, Rotation, Vec2 } from "../types.js"
|
||||
|
||||
const canPlayerJoin = (data: GameState) => {
|
||||
|
||||
|
@ -16,6 +17,27 @@ const canPlayerJoin = (data: GameState) => {
|
|||
|
||||
}
|
||||
|
||||
const loadMaps = (maps: {[key: number]: string}): boolean => {
|
||||
|
||||
for (let mapId = 0; mapId < GAME_MAP_COUNT; mapId++) {
|
||||
|
||||
let {width, height, data} = decompressMap(maps[mapId])
|
||||
let map = genMap(width, height, data, mapId)
|
||||
let [success, result] = checkMap(map)
|
||||
|
||||
if (!success) {
|
||||
alert(result)
|
||||
return false
|
||||
}
|
||||
|
||||
map.spawns = result as Vec2[]
|
||||
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
export const updatePlayers = (data: GameState, input: Input) => {
|
||||
|
||||
let startPressed = false;
|
||||
|
@ -62,7 +84,13 @@ export const updatePlayers = (data: GameState, input: Input) => {
|
|||
|
||||
}
|
||||
|
||||
startPressed ||= input.players[id].start;
|
||||
if (input.players[id].start) {
|
||||
let maps = input.players[id].maps
|
||||
if (loadMaps(maps)) {
|
||||
startPressed = true
|
||||
}
|
||||
}
|
||||
|
||||
if (input.players[id].key)
|
||||
data.input[id] = input.players[id].key
|
||||
|
||||
|
|
|
@ -7,11 +7,18 @@ import { checkMap, decompressMap, genMap } from "./map.js";
|
|||
const join = document.getElementById("join")
|
||||
const lobby = document.getElementById("lobby")
|
||||
const mapeditor = document.getElementById("mapeditor")
|
||||
const custommaps = document.getElementById("custommaps")
|
||||
const popup = document.getElementById("popup")
|
||||
|
||||
const maps = {
|
||||
[0]: 'MwRgPgTOIDS/dEOU1L1sxgDDX+9CDijSTyzLcFrVabN7EnYXCUnaBOK31xCMyEUSPfg3FZ20trTlTJnPpX4iV6tRLpCOC7bslbVvNQBY41SxesBWE/bYHpTnFPkZjFResG/hpb003RGBEMR0YQQAOSIjYcNDDRntAgNi/Txl/L2CkozgXfWdgtTUANmsQKyrrAHYHFLiI2T1870KgkkzS7N6CLUdmpvbipyV4hv7pQVSe8PGittHllo7J9Z7N5Y9W3Z39uCA'
|
||||
const defaultMaps = {
|
||||
[0]: 'MwRgPgTOIDS/dEOU1L1sxgDDX+9CDijSTyzLcFrVabN7EnYXCUnaBOK31xCMyEUSPfg3FZ20trTlTJnPpX4iV6tRLpCOC7bslbVvNQBY41SxesBWE/bYHpTnFPkZjFResG/hpb003RGBEMR0YQQAOSIjYcNDDRntAgNi/Txl/L2CkozgXfWdgtTUANmsQKyrrAHYHFLiI2T1870KgkkzS7N6CLUdmpvbipyV4hv7pQVSe8PGittHllo7J9Z7N5Y9W3Z39uCA',
|
||||
[1]: 'MwdgPgTMkDQXD5IQRhgBhm5PF97mptvqQalpWkVbdXQ/Uxo5eeTZly97zy5359h/Euzw1mUgbWIzpCynPHS5I9UpgBOGRpGSGyQZh0HVmxWtYGdfMRYZXuBvbs3P5sthSei3Z6y8Xdz9lIM96KwAWLGI42ISUeKTE+IBWf0cHYyFcu2zAuRzXfMUA4I9CXPKI1nF4NGBvYIN4AA4fBzDG7xVAmt8wo2raosK8idLalHNIyfmxq1mWADZU9ZTN5O2YEEzmJea3fMOxsq6Lk96CuZyK+fvDg+uc02mLyxvw2z9h5+KHiwfgCNDV7FUzqxIU8vst6hIFojBkiRvC/llzpioYE0WROuC8biGjIiUA===',
|
||||
[2]: 'MzA+CYEZUgaOHyYly2o+rnEAZb6EFJGknFlFyXHUX15b52pk73NqeeO+zjkAnLQ7kaVUXWGcBLcq3kie2Jou6rGNOhPGi2kvSIWZlfEytOLEA2UsMSALPGYvnbgKxj7im/z9zLdTlzAI0RX2M7HR8/WyCDeM16aTUkYAY/AA5/enTQqUNI9Wi5XzjUkqMkCLtg1JQisPiynOLvOAA2N0hXHrcAdi9dUpyzLgsVOrHpoYz9XQXZ7QMp2rX2RvzxvnKU5bbhhNg91u2zwIzzCT4LpPnC72itdsnXjbePnCA===',
|
||||
[3]: 'MwRgPgTMYgNHD5MS5aAMbXa7zm4BOWfJU8k2YMm0oyiuCgypmtnD17llxX3Gzo9KxIQxHiBzStX552kjIvlc+KiTOmbF2gfRmrB3I1olrjXKbRHDOunXuP6lAFngFPH7yC8BWDQsLM2srS0dbSNQXdXE4CFgEhLilWNxiYRCkOUTYAA5cuBzrTNFwoKjcpJtoh1qnEpNkHAaI0oqjADYfL18e7wB2OqV6yMYm+3Gp80DlYLbZtKNGsTHhrLM7CdSFMIqXZaoF1qdhDJ2t012dvbmbiJWbF2pNm1XL8s+lz84gA=='
|
||||
}
|
||||
|
||||
export var maps = {}
|
||||
|
||||
join.onsubmit = async function(event) {
|
||||
event.preventDefault()
|
||||
|
||||
|
@ -27,19 +34,18 @@ join.onsubmit = async function(event) {
|
|||
alert('Please enter a player name')
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
for (let mapId = 0; mapId < GAME_MAP_COUNT; mapId++) {
|
||||
let {width, height, data} = decompressMap(maps[0]) // for now
|
||||
let map = genMap(width, height, data, mapId)
|
||||
let [success, result] = checkMap(map)
|
||||
|
||||
if (!success) {
|
||||
alert(result)
|
||||
return
|
||||
let id = 'map' + (mapId+1)
|
||||
let content = (document.getElementById(id) as HTMLTextAreaElement).value.trim()
|
||||
console.log(id, content)
|
||||
if (content.length > 0) {
|
||||
maps[mapId] = content
|
||||
} else {
|
||||
maps[mapId] = defaultMaps[mapId]
|
||||
}
|
||||
|
||||
map.spawns = result as Vec2[]
|
||||
|
||||
}
|
||||
|
||||
startGame(room_code, player_name)
|
||||
|
@ -49,6 +55,10 @@ mapeditor.onclick = function() {
|
|||
window.location.href = 'mapeditor.html'
|
||||
}
|
||||
|
||||
custommaps.onclick = function() {
|
||||
popup.style.display = 'flex'
|
||||
}
|
||||
|
||||
const onLoad = (startData: Frame) => {
|
||||
|
||||
if (startData.data.started) {
|
||||
|
@ -64,6 +74,8 @@ const onLoad = (startData: Frame) => {
|
|||
|
||||
join.style.display = "none"
|
||||
mapeditor.style.display = "none"
|
||||
custommaps.style.display = "none"
|
||||
popup.style.display = "none"
|
||||
lobby.style.display = ""
|
||||
|
||||
return true
|
||||
|
@ -88,6 +100,7 @@ const startGame = (code: string, name: string) => {
|
|||
{
|
||||
start: false,
|
||||
key: Key.NOTHING,
|
||||
maps: {},
|
||||
name
|
||||
}
|
||||
)
|
||||
|
|
|
@ -114,7 +114,7 @@ export class Game {
|
|||
onLoad: (startFrame: Frame) => boolean,
|
||||
onFrame: (data: Frame, frame: number) => void,
|
||||
onLogic: (pastData: GameState, input: Input, frame: number) => GameState,
|
||||
data: PlayerInput = { start: false, key: Key.NOTHING }
|
||||
data: PlayerInput = { start: false, key: Key.NOTHING, maps: {}}
|
||||
): void {
|
||||
|
||||
const fps = 60;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { Key, KeyMap, PlayerInput } from "../types.js"
|
||||
import { maps as definedMaps } from '../main.js'
|
||||
|
||||
let pressed = {}
|
||||
|
||||
|
@ -62,9 +63,15 @@ export const startInputListener = (keymap: KeyMap): () => PlayerInput => {
|
|||
let s = start;
|
||||
start = false;
|
||||
|
||||
let maps = {}
|
||||
if (s) {
|
||||
maps = definedMaps
|
||||
}
|
||||
|
||||
return {
|
||||
key,
|
||||
start: s,
|
||||
maps
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -194,6 +194,7 @@ export type Player = {
|
|||
export type PlayerInput = {
|
||||
start: boolean,
|
||||
key: Key,
|
||||
maps: {[key: number]: string}
|
||||
name?: string
|
||||
}
|
||||
|
||||
|
|
|
@ -7,9 +7,9 @@ RUN apk add musl-dev
|
|||
RUN cargo build --release
|
||||
|
||||
FROM node:alpine AS builder-ts
|
||||
RUN npm install typescript
|
||||
COPY client /app/
|
||||
WORKDIR /app
|
||||
RUN npm install typescript
|
||||
RUN npx tsc
|
||||
|
||||
FROM alpine
|
||||
|
|
Loading…
Reference in a new issue