summaryrefslogtreecommitdiff
path: root/client/src
diff options
context:
space:
mode:
Diffstat (limited to 'client/src')
-rw-r--r--client/src/editor.ts56
-rw-r--r--client/src/lib/lz-string.ts505
-rw-r--r--client/src/logic/logic.ts50
-rw-r--r--client/src/main.ts5
-rw-r--r--client/src/map.ts76
-rw-r--r--client/src/renderer.ts24
-rw-r--r--client/src/types.ts26
7 files changed, 636 insertions, 106 deletions
diff --git a/client/src/editor.ts b/client/src/editor.ts
index 77088ce..1abaad4 100644
--- a/client/src/editor.ts
+++ b/client/src/editor.ts
@@ -1,11 +1,11 @@
-import { genMap } from "./map.js"
+import { genMap, compressMap, decompressMap } from "./map.js"
import { startGraphicsUpdater } from "./renderer.js"
import { GameState, Vec2, Tile } from "./types.js"
const mapgen = document.getElementById("mapgen")
const sidebar = document.getElementById("sidebar")
-mapgen.onsubmit = async function(event) {
+mapgen.onsubmit = async (event) => {
event.preventDefault()
const width_str = (<HTMLInputElement>document.getElementById("width")).value
@@ -86,31 +86,33 @@ const getTilePos = (width: number, height: number, mousePos: Vec2): Vec2 => {
}
-const checkInputs = (pressed: {[key: string]: boolean}): Tile => {
+const checkInputs = (pressed: {[key: string]: boolean}): [Tile, boolean] => {
if (pressed["KeyW"]) {
- return Tile.WALL
+ return [Tile.WALL, false]
} else if (pressed["KeyG"]) {
- return Tile.GHOST_WALL
+ return [Tile.GHOST_WALL, false]
+ } else if (pressed["KeyH"]) {
+ return [Tile.GHOST_SPAWN, true]
} else if (pressed["KeyF"]) {
- return Tile.FOOD
+ return [Tile.FOOD, false]
} else if (pressed["Digit1"]) {
- return Tile.PLAYER_SPAWN_1
+ return [Tile.PLAYER_SPAWN_1, true]
} else if (pressed["Digit2"]) {
- return Tile.PLAYER_SPAWN_2
+ return [Tile.PLAYER_SPAWN_2, true]
} else if (pressed["Digit3"]) {
- return Tile.PLAYER_SPAWN_3
+ return [Tile.PLAYER_SPAWN_3, true]
} else if (pressed["Digit4"]) {
- return Tile.PLAYER_SPAWN_4
+ return [Tile.PLAYER_SPAWN_4, true]
} else if (pressed["KeyT"]) {
- return Tile.THICC_DOT
+ return [Tile.THICC_DOT, false]
} else if (pressed["KeyI"]) {
- return Tile.INITIAL_DOT
+ return [Tile.INITIAL_DOT, false]
} else if (pressed["KeyC"]) {
- return Tile.EMPTY
+ return [Tile.EMPTY, false]
}
- return undefined
+ return [undefined, undefined]
}
const checkBounds = (tilePos: Vec2, width: number, height: number) => {
@@ -124,7 +126,7 @@ const runMapEditor = (width: number, height: number) => {
let data: number[] = new Array(width * height).fill(0)
- genMap(width, height, data, Tile.EMPTY)
+ let map = genMap(width, height, data, Tile.EMPTY)
let state: GameState = {
started: true,
@@ -145,13 +147,19 @@ const runMapEditor = (width: number, height: number) => {
const tilePos = getTilePos(width, height, mousePos)
const pressed = getInput()
- const tile = checkInputs(pressed)
+ const [tile, unique] = checkInputs(pressed)
if (tile !== undefined && checkBounds(tilePos, width, height)) {
let current = data[tilePos.y * width + tilePos.x];
- if (current != tile) {
+ if (current != tile && (current == Tile.EMPTY || tile == Tile.EMPTY)) {
+ if (unique) {
+ data = data.map(t => {
+ if (t == tile) return Tile.EMPTY
+ else return t
+ })
+ }
data[tilePos.y * width + tilePos.x] = tile
- genMap(width, height, data, 0)
+ map = genMap(width, height, data, 0)
}
}
@@ -162,4 +170,16 @@ const runMapEditor = (width: number, height: number) => {
requestAnimationFrame(loop)
+ document.getElementById("export").onclick = () => {
+ let encoded = compressMap(map)
+ document.getElementById("textarea").textContent = encoded
+ document.getElementById("popup").style.display = 'flex'
+
+ console.log(decompressMap(encoded))
+ }
+
+ document.getElementById("copy").onclick = () => {
+ navigator.clipboard.writeText(document.getElementById("textarea").textContent)
+ }
+
}
diff --git a/client/src/lib/lz-string.ts b/client/src/lib/lz-string.ts
new file mode 100644
index 0000000..68270d0
--- /dev/null
+++ b/client/src/lib/lz-string.ts
@@ -0,0 +1,505 @@
+export namespace LZString {
+ // private property
+ var f = String.fromCharCode;
+ var keyStrBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+ var keyStrUriSafe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$";
+ var baseReverseDic = {};
+
+ function getBaseValue(alphabet: any, character: any) {
+ if (!baseReverseDic[alphabet]) {
+ baseReverseDic[alphabet] = {};
+ for (var i = 0; i < alphabet.length; i++) {
+ baseReverseDic[alphabet][alphabet.charAt(i)] = i;
+ }
+ }
+ return baseReverseDic[alphabet][character];
+ }
+
+ export function compressToBase64(input:string) {
+ if (input == null) return "";
+ var res = _compress(input, 6, function (a: any) {
+ return keyStrBase64.charAt(a);
+ });
+ switch (res.length % 4) { // To produce valid Base64
+ default: // When could this happen ?
+ case 0:
+ return res;
+ case 1:
+ return res + "===";
+ case 2:
+ return res + "==";
+ case 3:
+ return res + "=";
+ }
+ }
+
+ export function decompressFromBase64(input:string) {
+ if (input == null) return "";
+ if (input == "") return null;
+ return _decompress(input.length, 32, function (index: any) {
+ return getBaseValue(keyStrBase64, input.charAt(index));
+ });
+ }
+
+ export function compressToUTF16(input:string) {
+ if (input == null) return "";
+ return _compress(input, 15, function (a: any) {
+ return f(a + 32);
+ }) + " ";
+ }
+
+ export function decompressFromUTF16(compressed:string) {
+ if (compressed == null) return "";
+ if (compressed == "") return null;
+ return _decompress(compressed.length, 16384, function (index: any) {
+ return compressed.charCodeAt(index) - 32;
+ });
+ }
+
+ //compress into uint8array (UCS-2 big endian format)
+ export function compressToUint8Array(uncompressed:string) {
+ var compressed = compress(uncompressed);
+ var buf = new Uint8Array(compressed.length * 2); // 2 bytes per character
+
+ for (var i = 0, TotalLen = compressed.length; i < TotalLen; i++) {
+ var current_value = compressed.charCodeAt(i);
+ buf[i * 2] = current_value >>> 8;
+ buf[i * 2 + 1] = current_value % 256;
+ }
+ return buf;
+ }
+
+ //decompress from uint8array (UCS-2 big endian format)
+ export function decompressFromUint8Array(compressed: any) {
+ if (compressed === null || compressed === undefined) {
+ return decompress(compressed);
+ } else {
+ var buf = new Array(compressed.length / 2); // 2 bytes per character
+ for (var i = 0, TotalLen = buf.length; i < TotalLen; i++) {
+ buf[i] = compressed[i * 2] * 256 + compressed[i * 2 + 1];
+ }
+
+ var result = [];
+ buf.forEach(function (c) {
+ result.push(f(c));
+ });
+ return decompress(result.join(''));
+
+ }
+
+ }
+
+
+ //compress into a string that is already URI encoded
+ export function compressToEncodedURIComponent(input:string) {
+ if (input == null) return "";
+ return _compress(input, 6, function (a: any) {
+ return keyStrUriSafe.charAt(a);
+ });
+ }
+
+ //decompress from an output of compressToEncodedURIComponent
+ export function decompressFromEncodedURIComponent(input:string) {
+ if (input == null) return "";
+ if (input == "") return null;
+ input = input.replace(/ /g, "+");
+ return _decompress(input.length, 32, function (index: any) {
+ return getBaseValue(keyStrUriSafe, input.charAt(index));
+ });
+ }
+
+ export function compress(uncompressed:string) {
+ return _compress(uncompressed, 16, function (a: any) {
+ return f(a);
+ });
+ }
+
+ function _compress(uncompressed: any, bitsPerChar: any, getCharFromInt: any) {
+ if (uncompressed == null) return "";
+ var i: any, value: any,
+ context_dictionary = {},
+ context_dictionaryToCreate = {},
+ context_c = "",
+ context_wc = "",
+ context_w = "",
+ context_enlargeIn = 2, // Compensate for the first entry which should not count
+ context_dictSize = 3,
+ context_numBits = 2,
+ context_data = [],
+ context_data_val = 0,
+ context_data_position = 0,
+ ii: any;
+
+ for (ii = 0; ii < uncompressed.length; ii += 1) {
+ context_c = uncompressed.charAt(ii);
+ if (!Object.prototype.hasOwnProperty.call(context_dictionary, context_c)) {
+ context_dictionary[context_c] = context_dictSize++;
+ context_dictionaryToCreate[context_c] = true;
+ }
+
+ context_wc = context_w + context_c;
+ if (Object.prototype.hasOwnProperty.call(context_dictionary, context_wc)) {
+ context_w = context_wc;
+ } else {
+ if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate, context_w)) {
+ if (context_w.charCodeAt(0) < 256) {
+ for (i = 0; i < context_numBits; i++) {
+ context_data_val = (context_data_val << 1);
+ if (context_data_position == bitsPerChar - 1) {
+ context_data_position = 0;
+ context_data.push(getCharFromInt(context_data_val));
+ context_data_val = 0;
+ } else {
+ context_data_position++;
+ }
+ }
+ value = context_w.charCodeAt(0);
+ for (i = 0; i < 8; i++) {
+ context_data_val = (context_data_val << 1) | (value & 1);
+ if (context_data_position == bitsPerChar - 1) {
+ context_data_position = 0;
+ context_data.push(getCharFromInt(context_data_val));
+ context_data_val = 0;
+ } else {
+ context_data_position++;
+ }
+ value = value >> 1;
+ }
+ } else {
+ value = 1;
+ for (i = 0; i < context_numBits; i++) {
+ context_data_val = (context_data_val << 1) | value;
+ if (context_data_position == bitsPerChar - 1) {
+ context_data_position = 0;
+ context_data.push(getCharFromInt(context_data_val));
+ context_data_val = 0;
+ } else {
+ context_data_position++;
+ }
+ value = 0;
+ }
+ value = context_w.charCodeAt(0);
+ for (i = 0; i < 16; i++) {
+ context_data_val = (context_data_val << 1) | (value & 1);
+ if (context_data_position == bitsPerChar - 1) {
+ context_data_position = 0;
+ context_data.push(getCharFromInt(context_data_val));
+ context_data_val = 0;
+ } else {
+ context_data_position++;
+ }
+ value = value >> 1;
+ }
+ }
+ context_enlargeIn--;
+ if (context_enlargeIn == 0) {
+ context_enlargeIn = Math.pow(2, context_numBits);
+ context_numBits++;
+ }
+ delete context_dictionaryToCreate[context_w];
+ } else {
+ value = context_dictionary[context_w];
+ for (i = 0; i < context_numBits; i++) {
+ context_data_val = (context_data_val << 1) | (value & 1);
+ if (context_data_position == bitsPerChar - 1) {
+ context_data_position = 0;
+ context_data.push(getCharFromInt(context_data_val));
+ context_data_val = 0;
+ } else {
+ context_data_position++;
+ }
+ value = value >> 1;
+ }
+
+
+ }
+ context_enlargeIn--;
+ if (context_enlargeIn == 0) {
+ context_enlargeIn = Math.pow(2, context_numBits);
+ context_numBits++;
+ }
+ // Add wc to the dictionary.
+ context_dictionary[context_wc] = context_dictSize++;
+ context_w = String(context_c);
+ }
+ }
+
+ // Output the code for w.
+ if (context_w !== "") {
+ if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate, context_w)) {
+ if (context_w.charCodeAt(0) < 256) {
+ for (i = 0; i < context_numBits; i++) {
+ context_data_val = (context_data_val << 1);
+ if (context_data_position == bitsPerChar - 1) {
+ context_data_position = 0;
+ context_data.push(getCharFromInt(context_data_val));
+ context_data_val = 0;
+ } else {
+ context_data_position++;
+ }
+ }
+ value = context_w.charCodeAt(0);
+ for (i = 0; i < 8; i++) {
+ context_data_val = (context_data_val << 1) | (value & 1);
+ if (context_data_position == bitsPerChar - 1) {
+ context_data_position = 0;
+ context_data.push(getCharFromInt(context_data_val));
+ context_data_val = 0;
+ } else {
+ context_data_position++;
+ }
+ value = value >> 1;
+ }
+ } else {
+ value = 1;
+ for (i = 0; i < context_numBits; i++) {
+ context_data_val = (context_data_val << 1) | value;
+ if (context_data_position == bitsPerChar - 1) {
+ context_data_position = 0;
+ context_data.push(getCharFromInt(context_data_val));
+ context_data_val = 0;
+ } else {
+ context_data_position++;
+ }
+ value = 0;
+ }
+ value = context_w.charCodeAt(0);
+ for (i = 0; i < 16; i++) {
+ context_data_val = (context_data_val << 1) | (value & 1);
+ if (context_data_position == bitsPerChar - 1) {
+ context_data_position = 0;
+ context_data.push(getCharFromInt(context_data_val));
+ context_data_val = 0;
+ } else {
+ context_data_position++;
+ }
+ value = value >> 1;
+ }
+ }
+ context_enlargeIn--;
+ if (context_enlargeIn == 0) {
+ context_enlargeIn = Math.pow(2, context_numBits);
+ context_numBits++;
+ }
+ delete context_dictionaryToCreate[context_w];
+ } else {
+ value = context_dictionary[context_w];
+ for (i = 0; i < context_numBits; i++) {
+ context_data_val = (context_data_val << 1) | (value & 1);
+ if (context_data_position == bitsPerChar - 1) {
+ context_data_position = 0;
+ context_data.push(getCharFromInt(context_data_val));
+ context_data_val = 0;
+ } else {
+ context_data_position++;
+ }
+ value = value >> 1;
+ }
+
+
+ }
+ context_enlargeIn--;
+ if (context_enlargeIn == 0) {
+ context_enlargeIn = Math.pow(2, context_numBits);
+ context_numBits++;
+ }
+ }
+
+ // Mark the end of the stream
+ value = 2;
+ for (i = 0; i < context_numBits; i++) {
+ context_data_val = (context_data_val << 1) | (value & 1);
+ if (context_data_position == bitsPerChar - 1) {
+ context_data_position = 0;
+ context_data.push(getCharFromInt(context_data_val));
+ context_data_val = 0;
+ } else {
+ context_data_position++;
+ }
+ value = value >> 1;
+ }
+
+ // Flush the last char
+ while (true) {
+ context_data_val = (context_data_val << 1);
+ if (context_data_position == bitsPerChar - 1) {
+ context_data.push(getCharFromInt(context_data_val));
+ break;
+ } else context_data_position++;
+ }
+ return context_data.join('');
+ }
+
+ export function decompress(compressed:string) {
+ if (compressed == null) return "";
+ if (compressed == "") return null;
+ return _decompress(compressed.length, 32768, function (index: any) {
+ return compressed.charCodeAt(index);
+ });
+ }
+
+ function _decompress(length: any, resetValue: any, getNextValue: any) {
+ var dictionary = [],
+ next: any,
+ enlargeIn = 4,
+ dictSize = 4,
+ numBits = 3,
+ entry = "",
+ result = [],
+ i: any,
+ w: any,
+ bits: any, resb: any, maxpower: any, power: any,
+ c: any,
+ data = {
+ val: getNextValue(0),
+ position: resetValue,
+ index: 1
+ };
+
+ for (i = 0; i < 3; i += 1) {
+ dictionary[i] = i;
+ }
+
+ bits = 0;
+ maxpower = Math.pow(2, 2);
+ power = 1;
+ while (power != maxpower) {
+ resb = data.val & data.position;
+ data.position >>= 1;
+ if (data.position == 0) {
+ data.position = resetValue;
+ data.val = getNextValue(data.index++);
+ }
+ bits |= (resb > 0 ? 1 : 0) * power;
+ power <<= 1;
+ }
+
+ switch (next = bits) {
+ case 0:
+ bits = 0;
+ maxpower = Math.pow(2, 8);
+ power = 1;
+ while (power != maxpower) {
+ resb = data.val & data.position;
+ data.position >>= 1;
+ if (data.position == 0) {
+ data.position = resetValue;
+ data.val = getNextValue(data.index++);
+ }
+ bits |= (resb > 0 ? 1 : 0) * power;
+ power <<= 1;
+ }
+ c = f(bits);
+ break;
+ case 1:
+ bits = 0;
+ maxpower = Math.pow(2, 16);
+ power = 1;
+ while (power != maxpower) {
+ resb = data.val & data.position;
+ data.position >>= 1;
+ if (data.position == 0) {
+ data.position = resetValue;
+ data.val = getNextValue(data.index++);
+ }
+ bits |= (resb > 0 ? 1 : 0) * power;
+ power <<= 1;
+ }
+ c = f(bits);
+ break;
+ case 2:
+ return "";
+ }
+ dictionary[3] = c;
+ w = c;
+ result.push(c);
+ while (true) {
+ if (data.index > length) {
+ return "";
+ }
+
+ bits = 0;
+ maxpower = Math.pow(2, numBits);
+ power = 1;
+ while (power != maxpower) {
+ resb = data.val & data.position;
+ data.position >>= 1;
+ if (data.position == 0) {
+ data.position = resetValue;
+ data.val = getNextValue(data.index++);
+ }
+ bits |= (resb > 0 ? 1 : 0) * power;
+ power <<= 1;
+ }
+
+ switch (c = bits) {
+ case 0:
+ bits = 0;
+ maxpower = Math.pow(2, 8);
+ power = 1;
+ while (power != maxpower) {
+ resb = data.val & data.position;
+ data.position >>= 1;
+ if (data.position == 0) {
+ data.position = resetValue;
+ data.val = getNextValue(data.index++);
+ }
+ bits |= (resb > 0 ? 1 : 0) * power;
+ power <<= 1;
+ }
+
+ dictionary[dictSize++] = f(bits);
+ c = dictSize - 1;
+ enlargeIn--;
+ break;
+ case 1:
+ bits = 0;
+ maxpower = Math.pow(2, 16);
+ power = 1;
+ while (power != maxpower) {
+ resb = data.val & data.position;
+ data.position >>= 1;
+ if (data.position == 0) {
+ data.position = resetValue;
+ data.val = getNextValue(data.index++);
+ }
+ bits |= (resb > 0 ? 1 : 0) * power;
+ power <<= 1;
+ }
+ dictionary[dictSize++] = f(bits);
+ c = dictSize - 1;
+ enlargeIn--;
+ break;
+ case 2:
+ return result.join('');
+ }
+
+ if (enlargeIn == 0) {
+ enlargeIn = Math.pow(2, numBits);
+ numBits++;
+ }
+
+ if (dictionary[c]) {
+ entry = dictionary[c];
+ } else {
+ if (c === dictSize) {
+ entry = w + w.charAt(0);
+ } else {
+ return null;
+ }
+ }
+ result.push(entry);
+
+ // Add w+entry[0] to the dictionary.
+ dictionary[dictSize++] = w + entry.charAt(0);
+ enlargeIn--;
+
+ w = entry;
+
+ if (enlargeIn == 0) {
+ enlargeIn = Math.pow(2, numBits);
+ numBits++;
+ }
+ }
+ }
+};
diff --git a/client/src/logic/logic.ts b/client/src/logic/logic.ts
index 1cca2b7..dd6e21d 100644
--- a/client/src/logic/logic.ts
+++ b/client/src/logic/logic.ts
@@ -1,10 +1,13 @@
-import { genItems, loadMap, getMap } from "../map.js";
+import { genItems, genMap, getMap, decompressMap } from "../map.js";
import { updatePlayers } from "./players.js"
import { updateUI } from "./ui.js"
import { updateMovement } from "./movement.js"
import { updateItems } from "./items.js"
import { GameState, Input } from "../types.js";
+const maps = {
+ [0]: 'EwRgPqYgNDew+TEuW6AGT2u59mPI/PeLZclSys1AhSgThJcJb2bdq7p5rupV2DYaVFCKI9HwFDiWACyxyK5WpCqArOPSCeuqfUnzDwaGbMyT3FAGZT0ABznD9ybWv0LLq61kz4S0M9WRMANnVVDUi1AHYdQxt+dyNEhJNiNk8A3npkiVSmcUEM6E5C/wL86rlivLqxaVymltggA='
+}
export const InitialState: GameState = {
started: false,
@@ -32,7 +35,7 @@ export const onLogic = (
}
if (startPressed && !data.started) {
- initMap(data)
+ initMap(data, 0)
data.started = true;
}
@@ -40,41 +43,16 @@ export const onLogic = (
}
-const initMap = (data: GameState) => {
-
- document.getElementById("lobby").style.display = "none"
-
- data.mapId = 0
+const initMap = (gameData: GameState, mapId: number) => {
- if (getMap(0)) return
+ gameData.mapId = mapId
- let width = 21
- let height = 21
- let m_data = [
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,
- 1,0,1,1,1,0,1,1,1,0,1,0,1,1,1,0,1,1,1,0,1,
- 1,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,1,
- 1,0,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,0,1,0,1,
- 1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,
- 1,0,1,1,1,0,1,0,1,1,1,1,1,0,1,0,1,1,1,0,1,
- 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
- 1,1,1,0,1,0,1,0,1,1,1,1,1,0,1,0,1,0,1,1,1,
- 1,0,0,0,0,0,1,0,1,2,2,2,1,0,1,0,0,0,0,0,1,
- 1,0,1,1,1,0,1,0,1,2,2,2,1,0,1,0,1,1,1,0,1,
- 1,0,0,0,0,0,1,0,1,2,2,2,1,0,1,0,0,0,0,0,1,
- 1,1,1,0,1,0,1,0,1,1,2,1,1,0,1,0,1,0,1,1,1,
- 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
- 1,0,1,1,1,0,1,0,1,1,1,1,1,0,1,0,1,1,1,0,1,
- 1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,
- 1,0,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,0,1,0,1,
- 1,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,1,
- 1,0,1,1,1,0,1,1,1,0,1,0,1,1,1,0,1,1,1,0,1,
- 1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
- ]
-
- loadMap(width, height, m_data) // cursed temp thing
- data.items = genItems(getMap(0))
+ let map = getMap(mapId)
+ if (!map) {
+ let {width, height, data} = decompressMap(maps[mapId])
+ map = genMap(width, height, data, mapId)
+ }
+
+ gameData.items = genItems(map)
}
diff --git a/client/src/main.ts b/client/src/main.ts
index 7ac13a3..b5ea424 100644
--- a/client/src/main.ts
+++ b/client/src/main.ts
@@ -1,7 +1,7 @@
import { Game } from "./net/game.js";
import { InitialState, onLogic } from "./logic/logic.js";
import { startGraphicsUpdater } from "./renderer.js";
-import { GameKeyMap, Frame, Key } from "./types.js";
+import { GameKeyMap, Frame, Key, Player } from "./types.js";
const join = document.getElementById("join")
const lobby = document.getElementById("lobby")
@@ -42,7 +42,7 @@ const onLoad = (startData: Frame) => {
return false
}
- let players = Object.values(startData.data.players).filter(p => { return p !== null && p.name !== undefined })
+ let players = Object.values(startData.data.players).filter((p: Player): boolean => p !== null && p.name !== undefined)
if (players.length >= 4) {
alert('Room is full')
return false
@@ -59,7 +59,6 @@ const onFrame = (data: Frame, frame: number) => {
}
-
const startGame = (code: string, name: string) => {
const game = new Game(3000)
diff --git a/client/src/map.ts b/client/src/map.ts
index d26c467..1ad6d63 100644
--- a/client/src/map.ts
+++ b/client/src/map.ts
@@ -1,4 +1,5 @@
-import { Wall, ItemType, Map, Maps, Items } from "./types.js"
+import { Wall, ItemType, Map, Maps, Items, Tile } from "./types.js"
+import { LZString } from "./lib/lz-string.js"
export const getItemKey = (
x: number,
@@ -90,6 +91,8 @@ const genWalls = (
return walls
}
+const canItem = (tile: Tile): boolean => tile != Tile.WALL && tile != Tile.GHOST_WALL && tile != Tile.GHOST_SPAWN
+
export const genItems = (map: Map): Items => {
let width = map.width
@@ -101,21 +104,35 @@ export const genItems = (map: Map): Items => {
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
let tile = getPoint(width, height, data, x, y)
- if (tile != 0) continue
+ if (!canItem(tile)) continue
let item_key = getItemKey(x, y, width)
- items[item_key] = {type: ItemType.DOT, pos: {x, y}}
- let tile_south = getPoint(width, height, data, x, y + 1)
- if (tile_south == 0) {
- item_key = getItemKey(x, y + .5, width)
- items[item_key] = {type: ItemType.DOT, pos: {x, y: y + .5}}
- }
+ let type: ItemType
+
+ if (tile == Tile.FOOD)
+ type = ItemType.FOOD
+ else if (tile == Tile.THICC_DOT)
+ type = ItemType.THICC_DOT
+ else
+ type = ItemType.DOT
+
+ items[item_key] = {type, pos: {x, y}}
- let tile_east = getPoint(width, height, data, x + 1, y)
- if (tile_east == 0) {
- item_key = getItemKey(x + .5, y, width)
- items[item_key] = {type: ItemType.DOT, pos: {x: x + .5, y}}
+ if (type == ItemType.DOT || type == ItemType.THICC_DOT) {
+ type = ItemType.DOT
+
+ let tile_south = getPoint(width, height, data, x, y + 1)
+ if (canItem(tile_south) && tile_south != Tile.FOOD) {
+ item_key = getItemKey(x, y + .5, width)
+ items[item_key] = {type, pos: {x, y: y + .5}}
+ }
+
+ let tile_east = getPoint(width, height, data, x + 1, y)
+ if (canItem(tile_east) && tile_east != Tile.FOOD) {
+ item_key = getItemKey(x + .5, y, width)
+ items[item_key] = {type, pos: {x: x + .5, y}}
+ }
}
}
}
@@ -124,7 +141,6 @@ export const genItems = (map: Map): Items => {
}
let mapData: Maps = {}
-let id: number = 0
export const genMap = (
width: number,
@@ -144,26 +160,22 @@ export const genMap = (
return mapData[mapId]
}
-export const loadMap = (
- width: number,
- height: number,
- data: number[]
-): number => {
-
- let mapId = id++
-
- mapData[mapId] = {
- data: structuredClone(data),
- walls: genWalls(width, height, data),
- width,
- height,
- id: mapId
- }
-
- return mapId
-}
-
export const getMap = (mapId: number): Map | undefined => {
if (mapId == undefined) return undefined
return mapData[mapId]
}
+
+export const compressMap = (map: Map): string => {
+ let encoded = map.width + '|' + map.height + '|' + map.data.map(n => n + ',').join('').slice(0, -1)
+ return LZString.compressToBase64(encoded)
+}
+
+export const decompressMap = (encoded: string): {width: number, height: number, data: number[]} => {
+ let decoded = LZString.decompressFromBase64(encoded)
+ let values = decoded.split('|')
+ let width = parseInt(values[0])
+ let height = parseInt(values[1])
+ let data = values[2].split(',').map(c => parseInt(c))
+
+ return {width, height, data}
+}
diff --git a/client/src/renderer.ts b/client/src/renderer.ts
index 8482ca6..bc6cf83 100644
--- a/client/src/renderer.ts
+++ b/client/src/renderer.ts
@@ -137,9 +137,17 @@ const draw_items = (
let width: number, atlas_index: [number, number]
switch (item.type) {
case ItemType.DOT:
- width = .2,
+ width = .2
atlas_index = [2, 3]
break
+ case ItemType.THICC_DOT:
+ width = .4
+ atlas_index = [2, 3]
+ break
+ case ItemType.FOOD:
+ width = 1
+ atlas_index = [3, 3]
+ break
default:
continue
}
@@ -267,6 +275,7 @@ const draw_debug_sprites = (
let tile_type = map.data[y * map.width + x]
+ let size = 1
let atlas_index: [number, number];
switch (tile_type) {
case Tile.EMPTY:
@@ -275,9 +284,12 @@ const draw_debug_sprites = (
case Tile.GHOST_WALL:
atlas_index = [4, 0]
break
- case Tile.FOOD:
+ case Tile.GHOST_SPAWN:
atlas_index = [3, 0]
break
+ case Tile.FOOD:
+ atlas_index = [3, 3]
+ break
case Tile.PLAYER_SPAWN_1:
atlas_index = [3, 1]
break
@@ -291,10 +303,12 @@ const draw_debug_sprites = (
atlas_index = [4, 2]
break
case Tile.THICC_DOT:
- atlas_index = [4, 3]
+ atlas_index = [2, 3]
+ size = .4
break
case Tile.INITIAL_DOT:
- atlas_index = [3, 3]
+ atlas_index = [2, 3]
+ size = .2
break
}
@@ -302,7 +316,7 @@ const draw_debug_sprites = (
ctx,
x,
y,
- 1,
+ size,
atlas,
atlas_index,
ATLAS_TILE_WIDTH,
diff --git a/client/src/types.ts b/client/src/types.ts
index 02d5adb..c130980 100644
--- a/client/src/types.ts
+++ b/client/src/types.ts
@@ -2,17 +2,17 @@
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
+ EMPTY = 0,
+ WALL = 1,
+ GHOST_WALL = 2,
+ FOOD = 3,
+ PLAYER_SPAWN_1 = 4,
+ PLAYER_SPAWN_2 = 5,
+ PLAYER_SPAWN_3 = 6,
+ PLAYER_SPAWN_4 = 7,
+ GHOST_SPAWN = 8,
+ THICC_DOT = 9,
+ INITIAL_DOT = 10
}
export enum Wall {
@@ -36,7 +36,9 @@ export enum Wall {
}
export enum ItemType {
- DOT
+ DOT,
+ THICC_DOT,
+ FOOD
}
export enum Key {