Init
Initialer Load vom alten Projekt.
BIN
hexgrid.png
Normal file
|
After Width: | Height: | Size: 2.0 MiB |
108
index.html
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>MapViewer – Spielleiter</title>
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
|
||||
<style>
|
||||
body.paused {
|
||||
outline: 8px solid rgba(0, 150, 255, 0.75);
|
||||
outline-offset: -8px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<!-- Weltkarte Button unten links -->
|
||||
<button id="mapToggleButton" title="Weltkarte anzeigen"
|
||||
style="
|
||||
position: fixed;
|
||||
bottom: 15px;
|
||||
left: 15px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
font-size: 60px;
|
||||
background-color: #444;
|
||||
color: green;
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
z-index: 9999;">
|
||||
🗺
|
||||
</button>
|
||||
|
||||
<body>
|
||||
<div id="controls">
|
||||
<label><input type="checkbox" id="toggleFog"></label>
|
||||
<button id="fogMode">Modus: Radierer</button><br>
|
||||
<button id="fogClear">Alles aufdecken</button>
|
||||
<button id="fogFull">Alles vernebeln</button><br>
|
||||
<label>Pinselgröße: <input type="range" id="brushSize" min="1" max="5" value="1" /></label>
|
||||
|
||||
|
||||
<div style="background:#ccc; padding:10px; margin-top:10px;">
|
||||
<label><input type="checkbox" id="toggleHexgrid" checked> Hexgrid anzeigen</label><br>
|
||||
<label>Grid-Skalierung: <input type="range" id="gridScaleSlider" min="0.1" max="4.0" step="0.1" value="1"></label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Battlemap-Auswahl Buttons -->
|
||||
<div id="battlemap-buttons" style="position: absolute; top: 175px; left: 10px; background: rgba(255,255,255,0.8); padding: 10px; border-radius: 10px; z-index: 9999;">
|
||||
<strong>Battle Maps:</strong>
|
||||
</div>
|
||||
|
||||
<canvas id="mapCanvas"></canvas>
|
||||
|
||||
<iframe id="worldmap-iframe"
|
||||
src="https://map.arenos.danielnagel.at"
|
||||
style="display: none; position: absolute; top: 0; left: 0; width: 100%; height: calc(100% - 130px); z-index: 8000; border: none;">
|
||||
</iframe>
|
||||
|
||||
|
||||
<script src="master.js">
|
||||
|
||||
</script>
|
||||
|
||||
<script>
|
||||
let paused = false;
|
||||
document.addEventListener("keydown", (e) => {
|
||||
if (e.code === "Space") {
|
||||
paused = !paused;
|
||||
document.body.classList.toggle("paused", paused);
|
||||
localStorage.setItem("pauseActive", paused);
|
||||
}
|
||||
});
|
||||
|
||||
// === Dynamische Standardmaps laden ===
|
||||
fetch('/list-maps')
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
const controlDiv = document.getElementById('battlemap-buttons');
|
||||
const container = document.createElement('div');
|
||||
container.style.marginTop = '5px';
|
||||
container.style.background = '#ccc';
|
||||
container.style.padding = '5px';
|
||||
|
||||
data.forEach(file => {
|
||||
const button = document.createElement('button');
|
||||
button.textContent = file;
|
||||
button.style.display = 'block';
|
||||
button.style.marginBottom = '5px';
|
||||
|
||||
button.addEventListener('click', () => {
|
||||
LoadImageMap(`standard_maps/${file}`);
|
||||
});
|
||||
|
||||
container.appendChild(button);
|
||||
});
|
||||
|
||||
controlDiv.appendChild(container);
|
||||
})
|
||||
.catch(err => console.error('Fehler beim Laden der Battlemap-Liste:', err));
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
287
master.js
Normal file
|
|
@ -0,0 +1,287 @@
|
|||
const canvas = document.getElementById("mapCanvas");
|
||||
const fogCanvas = document.createElement("canvas");
|
||||
const ctx = canvas.getContext("2d");
|
||||
const fogCtx = fogCanvas.getContext("2d");
|
||||
const iframe = document.getElementById("worldmap-iframe");
|
||||
|
||||
let image = null;
|
||||
let offsetX = 0, offsetY = 0;
|
||||
let scale = 1;
|
||||
let isDragging = false;
|
||||
let startX, startY;
|
||||
let fogEnabled = false;
|
||||
let fogMode = "erase";
|
||||
let brushSize = 50;
|
||||
let mouseX = 0, mouseY = 0;
|
||||
|
||||
const channel = new BroadcastChannel("mapsync");
|
||||
let MapX = 0;
|
||||
let MapY = 0;
|
||||
let MapZoom = 2;
|
||||
|
||||
function resizeCanvas() {
|
||||
canvas.width = window.innerWidth;
|
||||
canvas.height = window.innerHeight;
|
||||
draw();
|
||||
if (fogEnabled) drawBrushPreview(mouseX, mouseY);
|
||||
}
|
||||
window.addEventListener("resize", resizeCanvas);
|
||||
resizeCanvas();
|
||||
|
||||
// === Fog Controls ===
|
||||
document.getElementById("toggleFog").addEventListener("change", (e) => {
|
||||
fogEnabled = e.target.checked;
|
||||
channel.postMessage({ type: "fogEnabled", enabled: fogEnabled });
|
||||
draw();
|
||||
if (fogEnabled) drawBrushPreview(mouseX, mouseY);
|
||||
});
|
||||
|
||||
document.getElementById("fogMode").addEventListener("click", () => {
|
||||
fogMode = fogMode === "erase" ? "paint" : "erase";
|
||||
document.getElementById("fogMode").innerText = fogMode === "erase" ? "Modus: Radierer" : "Modus: Nebel";
|
||||
});
|
||||
|
||||
document.getElementById("fogClear").addEventListener("click", () => {
|
||||
const btn = document.getElementById("fogClear");
|
||||
btn.disabled = true;
|
||||
setTimeout(() => btn.disabled = false, 1000);
|
||||
fogCtx.clearRect(0, 0, fogCanvas.width, fogCanvas.height);
|
||||
syncFog(); draw();
|
||||
if (fogEnabled) drawBrushPreview(mouseX, mouseY);
|
||||
});
|
||||
|
||||
document.getElementById("fogFull").addEventListener("click", () => {
|
||||
const btn = document.getElementById("fogFull");
|
||||
btn.disabled = true;
|
||||
setTimeout(() => btn.disabled = false, 1000);
|
||||
fogCtx.fillStyle = "rgba(50, 50, 50, 1)";
|
||||
fogCtx.fillRect(0, 0, fogCanvas.width, fogCanvas.height);
|
||||
syncFog(); draw();
|
||||
if (fogEnabled) drawBrushPreview(mouseX, mouseY);
|
||||
});
|
||||
|
||||
document.getElementById("brushSize").addEventListener("input", (e) => {
|
||||
brushSize = 50 * parseInt(e.target.value);
|
||||
});
|
||||
|
||||
// === Mouse Interaktion ===
|
||||
canvas.addEventListener("dragover", e => e.preventDefault());
|
||||
canvas.addEventListener("drop", e => {
|
||||
e.preventDefault();
|
||||
const file = e.dataTransfer.files[0];
|
||||
const reader = new FileReader();
|
||||
reader.onload = evt => {
|
||||
const img = new Image();
|
||||
img.onload = () => {
|
||||
image = img;
|
||||
//Fog auf Größe des Geladenen Bildes anpassen.
|
||||
fogCanvas.width = img.width;
|
||||
fogCanvas.height = img.height;
|
||||
fogCtx.clearRect(0, 0, fogCanvas.width, fogCanvas.height);
|
||||
draw();
|
||||
if (fogEnabled) drawBrushPreview(mouseX, mouseY);
|
||||
channel.postMessage({ type: "mapData", data: evt.target.result });
|
||||
channel.postMessage({ type: "fogEnabled", enabled: fogEnabled });
|
||||
syncFog();
|
||||
};
|
||||
img.src = evt.target.result;
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
});
|
||||
|
||||
function LoadImageMap(i) {
|
||||
const img = new Image();
|
||||
img.onload = () => {
|
||||
image = img;
|
||||
fogCanvas.width = img.width;
|
||||
fogCanvas.height = img.height;
|
||||
fogCtx.clearRect(0, 0, fogCanvas.width, fogCanvas.height);
|
||||
draw();
|
||||
if (fogEnabled) drawBrushPreview(mouseX, mouseY);
|
||||
channel.postMessage({ type: "mapData", data: i });
|
||||
channel.postMessage({ type: "fogEnabled", enabled: fogEnabled });
|
||||
syncFog();
|
||||
};
|
||||
img.src = i;
|
||||
}
|
||||
|
||||
window.LoadImageMap = LoadImageMap;
|
||||
|
||||
canvas.addEventListener("mousedown", e => {
|
||||
if (e.button === 1) {
|
||||
isDragging = true;
|
||||
startX = e.clientX - offsetX;
|
||||
startY = e.clientY - offsetY;
|
||||
}
|
||||
});
|
||||
canvas.addEventListener("mouseup", () => { isDragging = false; });
|
||||
canvas.addEventListener("mouseout", () => { isDragging = false; });
|
||||
canvas.addEventListener("mousemove", e => {
|
||||
mouseX = e.clientX;
|
||||
mouseY = e.clientY;
|
||||
if (fogEnabled) draw();
|
||||
if (isDragging) {
|
||||
offsetX = e.clientX - startX;
|
||||
offsetY = e.clientY - startY;
|
||||
syncView();
|
||||
draw();
|
||||
if (fogEnabled) drawBrushPreview(mouseX, mouseY);
|
||||
} else if (fogEnabled && e.buttons === 1) {
|
||||
const x = (mouseX - offsetX) / scale;
|
||||
const y = (mouseY - offsetY) / scale;
|
||||
fogCtx.globalCompositeOperation = fogMode === "erase" ? "destination-out" : "source-over";
|
||||
fogCtx.fillStyle = "rgba(50, 50, 50, 0.9)";
|
||||
fogCtx.beginPath();
|
||||
fogCtx.arc(x, y, brushSize, 0, 2 * Math.PI);
|
||||
fogCtx.fill();
|
||||
syncFog(); draw();
|
||||
drawBrushPreview(mouseX, mouseY);
|
||||
}
|
||||
});
|
||||
|
||||
canvas.addEventListener("wheel", e => {
|
||||
e.preventDefault();
|
||||
const worldX = (e.clientX - offsetX) / scale;
|
||||
const worldY = (e.clientY - offsetY) / scale;
|
||||
const zoomFactor = e.deltaY < 0 ? 1.1 : 0.9;
|
||||
scale *= zoomFactor;
|
||||
offsetX = e.clientX - worldX * scale;
|
||||
offsetY = e.clientY - worldY * scale;
|
||||
syncView(); draw();
|
||||
if (fogEnabled) drawBrushPreview(mouseX, mouseY);
|
||||
});
|
||||
|
||||
function syncView() {
|
||||
channel.postMessage({ type: "viewData", offsetX, offsetY, scale });
|
||||
}
|
||||
|
||||
function syncFog() {
|
||||
const fogURL = fogCanvas.toDataURL("image/png");
|
||||
channel.postMessage({ type: "fogData", data: fogURL });
|
||||
}
|
||||
|
||||
function draw() {
|
||||
ctx.setTransform(scale, 0, 0, scale, offsetX, offsetY);
|
||||
ctx.clearRect(-offsetX / scale, -offsetY / scale, canvas.width / scale, canvas.height / scale);
|
||||
if (image) ctx.drawImage(image, 0, 0);
|
||||
if (fogEnabled && fogCanvas.width && fogCanvas.height) {
|
||||
ctx.globalAlpha = 0.4;
|
||||
ctx.drawImage(fogCanvas, 0, 0);
|
||||
ctx.globalAlpha = 1;
|
||||
}
|
||||
if (fogEnabled) drawBrushPreview(mouseX, mouseY);
|
||||
}
|
||||
|
||||
function drawBrushPreview(mouseX, mouseY) {
|
||||
const worldX = (mouseX - offsetX) / scale;
|
||||
const worldY = (mouseY - offsetY) / scale;
|
||||
ctx.save();
|
||||
ctx.setTransform(scale, 0, 0, scale, offsetX, offsetY);
|
||||
ctx.strokeStyle = "rgba(255,255,255,0.8)";
|
||||
ctx.lineWidth = 2 / scale;
|
||||
ctx.beginPath();
|
||||
ctx.arc(worldX, worldY, brushSize, 0, 2 * Math.PI);
|
||||
ctx.stroke();
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
window.addEventListener("keydown", (e) => {
|
||||
if (e.key.toLowerCase() === "f") {
|
||||
fogEnabled = !fogEnabled;
|
||||
document.getElementById("toggleFog").checked = fogEnabled;
|
||||
channel.postMessage({ type: "fogEnabled", enabled: fogEnabled });
|
||||
draw();
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById("toggleHexgrid").addEventListener("change", (e) => {
|
||||
channel.postMessage({ type: "hexgrid", enabled: e.target.checked });
|
||||
});
|
||||
|
||||
document.getElementById("gridScaleSlider").addEventListener("input", (e) => {
|
||||
const scale = parseFloat(e.target.value);
|
||||
channel.postMessage({ type: "hexgridScale", scale });
|
||||
});
|
||||
|
||||
|
||||
|
||||
// === Weltkarte Funktionen ===
|
||||
let worldMapMode = false;
|
||||
let previousImageSrc = null;
|
||||
|
||||
// === Leaflet View Update Intervall ===
|
||||
setInterval(() => {
|
||||
const iframe = document.getElementById("worldmap-iframe");
|
||||
if (iframe?.contentWindow && worldMapMode) {
|
||||
iframe.contentWindow.postMessage("getView", "*");
|
||||
}
|
||||
}, 500);
|
||||
|
||||
window.addEventListener("message", (event) => {
|
||||
const data = event.data;
|
||||
if (data?.type === "viewData") {
|
||||
MapX = data.center.lng;
|
||||
MapY = data.center.lat;
|
||||
MapZoom = data.zoom;
|
||||
channel.postMessage({ type: "MapCoord", MapX, MapY, MapZoom}); //Dem Slave die Karten Werte schicken.
|
||||
}
|
||||
});
|
||||
|
||||
const mapButton = document.getElementById("mapToggleButton");
|
||||
if (mapButton) {
|
||||
mapButton.addEventListener("click", () => {
|
||||
if (!worldMapMode) {
|
||||
previousImageSrc = image?.src || "pause.png";
|
||||
loadMap();
|
||||
channel.postMessage({ type: "mapMode", enabled: true });
|
||||
mapButton.textContent = "↩️";
|
||||
worldMapMode = true;
|
||||
syncWorldMapView();
|
||||
} else {
|
||||
restoreImage(previousImageSrc);
|
||||
channel.postMessage({ type: "mapMode", enabled: false });
|
||||
mapButton.textContent = "🗺";
|
||||
worldMapMode = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//Laden der iframe WorldMap
|
||||
function loadMap() {
|
||||
const iframe = document.getElementById("worldmap-iframe");
|
||||
if (!iframe) return;
|
||||
iframe.style.display = "block";
|
||||
if (iframe.contentWindow) {
|
||||
iframe.contentWindow.postMessage({ action: "syncRequest" }, "*");
|
||||
} else {
|
||||
iframe.onload = () => {
|
||||
iframe.contentWindow.postMessage({ action: "syncRequest" }, "*");
|
||||
};
|
||||
}
|
||||
}
|
||||
//Nach dem schließen der iframe WorldMap, wieder die letzte Map herstellen.
|
||||
function restoreImage(src) {
|
||||
const iframe = document.getElementById("worldmap-iframe");
|
||||
const canvas = document.getElementById("mapCanvas");
|
||||
|
||||
if (iframe) iframe.style.display = "none";
|
||||
if (canvas) canvas.style.display = "block";
|
||||
if (!src) return;
|
||||
|
||||
const img = new Image();
|
||||
img.onload = () => {
|
||||
image = img;
|
||||
fogCanvas.width = img.width;
|
||||
fogCanvas.height = img.height;
|
||||
fogCtx.clearRect(0, 0, fogCanvas.width, fogCanvas.height);
|
||||
draw();
|
||||
};
|
||||
img.src = src;
|
||||
}
|
||||
|
||||
function syncWorldMapView() {
|
||||
const iframe = document.getElementById("worldmap-iframe");
|
||||
if (worldMapMode && iframe?.contentWindow) {
|
||||
iframe.contentWindow.postMessage("getView", "*");
|
||||
}
|
||||
}
|
||||
26
server_launcher.py
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import http.server
|
||||
import socketserver
|
||||
import os
|
||||
import json
|
||||
|
||||
PORT = 8000
|
||||
os.chdir(os.path.dirname(__file__))
|
||||
|
||||
class CustomHandler(http.server.SimpleHTTPRequestHandler):
|
||||
def do_GET(self):
|
||||
if self.path == '/list-maps':
|
||||
try:
|
||||
files = os.listdir('standard_maps')
|
||||
image_files = [f for f in files if f.lower().endswith(('.png', '.jpg', '.jpeg'))]
|
||||
self.send_response(200)
|
||||
self.send_header('Content-Type', 'application/json')
|
||||
self.end_headers()
|
||||
self.wfile.write(json.dumps(image_files).encode('utf-8'))
|
||||
except Exception as e:
|
||||
self.send_error(500, f"Fehler: {str(e)}")
|
||||
else:
|
||||
super().do_GET()
|
||||
|
||||
with socketserver.TCPServer(("", PORT), CustomHandler) as httpd:
|
||||
print(f"Starte Server auf Port {PORT}...")
|
||||
httpd.serve_forever()
|
||||
126
slave.js
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
// slave.js – synchronisiert Ansicht mit master.js (mit direkter URL-Übergabe an Leaflet)
|
||||
|
||||
const canvas = document.getElementById("mapCanvas");
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
||||
let image = null;
|
||||
let fogImage = null;
|
||||
let hexGrid = new Image();
|
||||
hexGrid.src = "hexgrid.png";
|
||||
|
||||
let offsetX = 0, offsetY = 0;
|
||||
let scale = 1;
|
||||
let fogEnabled = false;
|
||||
let hexgridEnabled = false;
|
||||
let hexgridScale = 1;
|
||||
|
||||
let MapX = 0;
|
||||
let MapY = 0;
|
||||
let MapZoom = 2;
|
||||
|
||||
const channel = new BroadcastChannel("mapsync");
|
||||
|
||||
channel.onmessage = (event) => {
|
||||
const msg = event.data;
|
||||
|
||||
if (msg.type === "mapData") {
|
||||
const img = new Image();
|
||||
img.onload = () => {
|
||||
image = img;
|
||||
draw();
|
||||
};
|
||||
img.src = msg.data;
|
||||
|
||||
} else if (msg.type === "hexgrid") {
|
||||
hexgridEnabled = msg.enabled;
|
||||
draw();
|
||||
|
||||
} else if (msg.type === "hexgridScale") {
|
||||
hexgridScale = msg.scale;
|
||||
draw();
|
||||
|
||||
} else if (msg.type === "viewData") {
|
||||
offsetX = msg.offsetX;
|
||||
offsetY = msg.offsetY;
|
||||
scale = msg.scale;
|
||||
draw();
|
||||
|
||||
} else if (msg.type === "fogData") {
|
||||
const fog = new Image();
|
||||
fog.onload = () => {
|
||||
fogImage = fog;
|
||||
draw();
|
||||
};
|
||||
fog.src = msg.data;
|
||||
|
||||
} else if (msg.type === "fogEnabled") {
|
||||
fogEnabled = msg.enabled;
|
||||
draw();
|
||||
|
||||
} else if (msg.type === "mapMode") {
|
||||
const iframe = document.getElementById("worldmap-iframe");
|
||||
const canvas = document.getElementById("mapCanvas");
|
||||
|
||||
if (msg.enabled) {
|
||||
iframe.style.display = "block";
|
||||
canvas.style.display = "none";
|
||||
} else {
|
||||
iframe.style.display = "none";
|
||||
canvas.style.display = "block";
|
||||
}
|
||||
|
||||
} else if (msg.type === "MapCoord") {
|
||||
MapX = msg.MapX;
|
||||
MapY = msg.MapY;
|
||||
MapZoom = msg.MapZoom;
|
||||
|
||||
const iframe = document.getElementById("worldmap-iframe");
|
||||
if (iframe && iframe.contentWindow) {
|
||||
iframe.contentWindow.postMessage({
|
||||
type: "setView",
|
||||
center: [MapY, MapX],
|
||||
zoom: MapZoom
|
||||
}, "*");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function resizeCanvas() {
|
||||
canvas.width = window.innerWidth;
|
||||
canvas.height = window.innerHeight;
|
||||
draw();
|
||||
}
|
||||
window.addEventListener("resize", resizeCanvas);
|
||||
resizeCanvas();
|
||||
|
||||
function draw() {
|
||||
if (!image) return;
|
||||
ctx.setTransform(scale, 0, 0, scale, offsetX, offsetY);
|
||||
ctx.clearRect(-offsetX / scale, -offsetY / scale, canvas.width / scale, canvas.height / scale);
|
||||
ctx.drawImage(image, 0, 0);
|
||||
|
||||
if (hexgridEnabled && hexGrid.complete) {
|
||||
ctx.save();
|
||||
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
||||
ctx.globalAlpha = 0.5;
|
||||
|
||||
const scaleMod = 0.2;
|
||||
const gridWidth = hexGrid.width * (hexgridScale * scaleMod);
|
||||
const gridHeight = hexGrid.height * (hexgridScale * scaleMod);
|
||||
|
||||
const dx = (canvas.width - gridWidth) / 2;
|
||||
const dy = (canvas.height - gridHeight) / 2;
|
||||
|
||||
ctx.drawImage(hexGrid, dx, dy, gridWidth, gridHeight);
|
||||
ctx.restore();
|
||||
|
||||
ctx.setTransform(scale, 0, 0, scale, offsetX, offsetY);
|
||||
}
|
||||
|
||||
if (fogEnabled && fogImage) {
|
||||
ctx.globalAlpha = 1.0;
|
||||
ctx.drawImage(fogImage, 0, 0);
|
||||
ctx.globalAlpha = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
44
spieler.html
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>MapViewer - Spieler</title>
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
|
||||
<style>
|
||||
#pauseScreen {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: #000;
|
||||
z-index: 9999;
|
||||
display: none;
|
||||
}
|
||||
#pauseScreen img {
|
||||
object-fit: cover;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body><div id="pauseScreen"><img src="pause.png" alt="Pause"></div>
|
||||
<canvas id="mapCanvas"></canvas>
|
||||
<script src="slave.js"></script>
|
||||
|
||||
<iframe id="worldmap-iframe"
|
||||
src="https://map.arenos.danielnagel.at"
|
||||
style="display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 9000; border: none;">
|
||||
</iframe>
|
||||
|
||||
|
||||
<script>
|
||||
const pauseScreen = document.getElementById("pauseScreen");
|
||||
function checkPauseState() {
|
||||
const paused = localStorage.getItem("pauseActive") === "true";
|
||||
pauseScreen.style.display = paused ? "block" : "none";
|
||||
requestAnimationFrame(checkPauseState);
|
||||
}
|
||||
requestAnimationFrame(checkPauseState);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
BIN
standard_maps/cave.png
Normal file
|
After Width: | Height: | Size: 2.3 MiB |
BIN
standard_maps/city streets.png
Normal file
|
After Width: | Height: | Size: 2.4 MiB |
BIN
standard_maps/farm field.jpg
Normal file
|
After Width: | Height: | Size: 8.5 MiB |
BIN
standard_maps/harbor.png
Normal file
|
After Width: | Height: | Size: 2.0 MiB |
BIN
standard_maps/mansion garden.jpg
Normal file
|
After Width: | Height: | Size: 166 KiB |
BIN
standard_maps/roadside camp.jpg
Normal file
|
After Width: | Height: | Size: 6.5 MiB |
BIN
standard_maps/street.png
Normal file
|
After Width: | Height: | Size: 3.1 MiB |
BIN
standard_maps/tavern.jpg
Normal file
|
After Width: | Height: | Size: 4.9 MiB |
5
starte_viewer.bat
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
@echo off
|
||||
start /min python server_launcher.py
|
||||
timeout /t 2 >nul
|
||||
start http://localhost:8000/index.html
|
||||
start http://localhost:8000/spieler.html
|
||||
22
style.css
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
body {
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
background: #000;
|
||||
}
|
||||
#mapCanvas {
|
||||
display: block;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: #111;
|
||||
cursor: grab;
|
||||
}
|
||||
#controls {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
z-index: 10;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
padding: 10px;
|
||||
border-radius: 8px;
|
||||
font-family: sans-serif;
|
||||
}
|
||||