<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Open World Test</title>

<link href="https://unpkg.com/maplibre-gl@3.6.2/dist/maplibre-gl.css" rel="stylesheet">

<style>
  html, body {
    margin: 0;
    padding: 0;
    overflow: hidden;
    height: 100%;
  }
  #map {
    position: absolute;
    inset: 0;
  }
  #game {
    position: absolute;
    inset: 0;
    pointer-events: none;
  }
</style>
</head>
<body>

<div id="map"></div>
<canvas id="game"></canvas>

<script src="https://unpkg.com/maplibre-gl@3.6.2/dist/maplibre-gl.js"></script>

<script>
let map, player, canvas, ctx;
let lastTime = performance.now();

/* ---------------- INPUT ---------------- */
const keys = { up:false, down:false, left:false, right:false };

window.addEventListener("keydown", e => {
  if (e.key === "w") keys.up = true;
  if (e.key === "s") keys.down = true;
  if (e.key === "a") keys.left = true;
  if (e.key === "d") keys.right = true;
});

window.addEventListener("keyup", e => {
  if (e.key === "w") keys.up = false;
  if (e.key === "s") keys.down = false;
  if (e.key === "a") keys.left = false;
  if (e.key === "d") keys.right = false;
});

/* ---------------- PLAYER ---------------- */
class Player {
  constructor(lng, lat) {
    this.lng = lng;
    this.lat = lat;
    this.speed = 20; // metres per second (simple movement)
    this.img = new Image();
    this.img.src = "player.png"; // must be in same folder
  }

  move(dt) {
    let dx = 0;
    let dy = 0;

    if (keys.up) dy -= this.speed * dt;
    if (keys.down) dy += this.speed * dt;
    if (keys.left) dx -= this.speed * dt;
    if (keys.right) dx += this.speed * dt;

    if (dx !== 0 || dy !== 0) {
      const p = map.project([this.lng, this.lat]);
      const newPoint = { x: p.x + dx, y: p.y + dy };
      const ll = map.unproject(newPoint);
      this.lng = ll.lng;
      this.lat = ll.lat;
    }
  }

  draw(ctx) {
    const pos = map.project([this.lng, this.lat]);
    const size = 40;

    ctx.save();
    ctx.translate(pos.x, pos.y);
    ctx.drawImage(this.img, -size/2, -size/2, size, size);
    ctx.restore();
  }
}

/* ---------------- INIT ---------------- */
window.onload = () => {
  map = new maplibregl.Map({
    container: 'map',
    style: 'https://api.maptiler.com/maps/019d3452-4395-7ecd-bbf0-c64a3d5060cd/style.json?key=uHmPABwBFcVhiPJcdCzb',
    center: [173.284, -41.270], // Nelson
    zoom: 17.5, // ~200m radius
    pitch: 0,
    bearing: 0
  });

  // Disable keyboard so WASD doesn't move the map
  map.keyboard.disable();

  // Allow right-click rotation
  map.dragRotate.enable();
  map.touchZoomRotate.disableRotation();

  canvas = document.getElementById("game");
  ctx = canvas.getContext("2d");

  resizeCanvas();
  window.addEventListener("resize", resizeCanvas);

  player = new Player(173.284, -41.270);

  map.on("render", gameLoop);
};

/* ---------------- HELPERS ---------------- */
function resizeCanvas() {
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
}

/* ---------------- MAIN LOOP ---------------- */
function gameLoop() {
  const now = performance.now();
  const dt = (now - lastTime) / 1000;
  lastTime = now;

  player.move(dt);

  // Camera follows player
  map.setCenter([player.lng, player.lat]);

  ctx.clearRect(0, 0, canvas.width, canvas.height);
  player.draw(ctx);
}
</script>

</body>
</html>