Update server/static/map.js
This commit is contained in:
@@ -1,12 +1,19 @@
|
||||
// server/static/map.js
|
||||
|
||||
export class MapView {
|
||||
constructor(scene) {
|
||||
this.scene = scene;
|
||||
|
||||
// Tile config: adjust tileSize here if you want bigger/smaller tiles.
|
||||
this.tileSize = 32;
|
||||
|
||||
this.config = {
|
||||
width: 4000,
|
||||
height: 3000,
|
||||
width: 16000, // will be overridden by world.width from server
|
||||
height: 12000, // "
|
||||
zoom: 1.2,
|
||||
moveSpeed: 200
|
||||
};
|
||||
|
||||
this.target = null;
|
||||
this.nodes = [];
|
||||
this.nodeSprites = new Map();
|
||||
@@ -19,29 +26,73 @@ export class MapView {
|
||||
this.config.width = W;
|
||||
this.config.height = H;
|
||||
|
||||
// background
|
||||
this.scene.add.rectangle(W / 2, H / 2, W, H, 0x020617).setDepth(-100);
|
||||
// Draw tiled background/grid using a Graphics object
|
||||
const g = this.scene.add.graphics();
|
||||
const bgColor = 0x020617; // dark background
|
||||
const gridColor = 0x111827; // grid line color
|
||||
const gridAlpha = 0.4;
|
||||
|
||||
// player sprite
|
||||
this.player = this.scene.add.image(me.x, me.y, 'player').setDepth(10);
|
||||
// Fill background
|
||||
g.fillStyle(bgColor, 1);
|
||||
g.fillRect(0, 0, W, H);
|
||||
|
||||
// Grid lines
|
||||
g.lineStyle(1, gridColor, gridAlpha);
|
||||
for (let x = 0; x <= W; x += this.tileSize) {
|
||||
g.beginPath();
|
||||
g.moveTo(x, 0);
|
||||
g.lineTo(x, H);
|
||||
g.strokePath();
|
||||
}
|
||||
for (let y = 0; y <= H; y += this.tileSize) {
|
||||
g.beginPath();
|
||||
g.moveTo(0, y);
|
||||
g.lineTo(W, y);
|
||||
g.strokePath();
|
||||
}
|
||||
g.setDepth(-100); // stay behind everything
|
||||
|
||||
// Player sprite
|
||||
const startPos = this.snapToTile(me.x, me.y);
|
||||
this.player = this.scene.add.image(startPos.x, startPos.y, 'player').setDepth(10);
|
||||
this.nameText = this.scene
|
||||
.add.text(me.x, me.y - 22, me.username || me.name || 'You', {
|
||||
.add.text(startPos.x, startPos.y - 22, me.username || me.name || 'You', {
|
||||
fontSize: '12px',
|
||||
color: '#e5e7eb'
|
||||
})
|
||||
.setOrigin(0.5);
|
||||
|
||||
// camera follow
|
||||
// Camera follow & bounds
|
||||
const cam = this.scene.cameras.main;
|
||||
cam.setBounds(0, 0, W, H);
|
||||
cam.startFollow(this.player, true, 0.15, 0.15);
|
||||
cam.setZoom(this.config.zoom);
|
||||
|
||||
// Initialize nodes
|
||||
this.replaceNodes(nodes || []);
|
||||
}
|
||||
|
||||
// Snap any x,y world coordinate to the center of the containing tile
|
||||
snapToTile(x, y) {
|
||||
const size = this.tileSize;
|
||||
let tx = Math.floor(x / size);
|
||||
let ty = Math.floor(y / size);
|
||||
|
||||
// clamp to world bounds in tiles
|
||||
const maxTx = Math.floor((this.config.width - 1) / size);
|
||||
const maxTy = Math.floor((this.config.height - 1) / size);
|
||||
tx = Math.max(0, Math.min(maxTx, tx));
|
||||
ty = Math.max(0, Math.min(maxTy, ty));
|
||||
|
||||
return {
|
||||
x: tx * size + size / 2,
|
||||
y: ty * size + size / 2
|
||||
};
|
||||
}
|
||||
|
||||
setTarget(x, y) {
|
||||
this.target = { x, y };
|
||||
// When clicking, snap the target to a tile center
|
||||
this.target = this.snapToTile(x, y);
|
||||
}
|
||||
|
||||
setZoom(z) {
|
||||
@@ -50,17 +101,24 @@ export class MapView {
|
||||
}
|
||||
|
||||
replaceNodes(list) {
|
||||
// Clear old sprites
|
||||
for (const sprite of this.nodeSprites.values()) {
|
||||
sprite.destroy();
|
||||
}
|
||||
this.nodeSprites.clear();
|
||||
this.nodes = list.slice();
|
||||
|
||||
// Recreate sprites, snapping them to tiles visually (without changing server state)
|
||||
for (const n of this.nodes) {
|
||||
const snapped = this.snapToTile(n.x, n.y);
|
||||
const key = this.getTextureKeyForNode(n.type);
|
||||
const spr = this.scene.add.image(n.x, n.y, key).setDepth(1);
|
||||
const spr = this.scene.add.image(snapped.x, snapped.y, key).setDepth(1);
|
||||
spr.setAlpha(n.alive ? 1 : 0.2);
|
||||
this.nodeSprites.set(n.id, spr);
|
||||
|
||||
// Also update stored coords so distance checks use snapped positions
|
||||
n.x = snapped.x;
|
||||
n.y = snapped.y;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,10 +130,10 @@ export class MapView {
|
||||
}
|
||||
|
||||
getTextureKeyForNode(type) {
|
||||
if (type === 'wood') return 'wood';
|
||||
if (type === 'stone') return 'stone';
|
||||
if (type === 'ore') return 'ore';
|
||||
if (type === 'fiber') return 'fiber';
|
||||
if (type === 'wood') return 'wood';
|
||||
if (type === 'stone') return 'stone';
|
||||
if (type === 'ore') return 'ore';
|
||||
if (type === 'fiber') return 'fiber';
|
||||
return 'wood';
|
||||
}
|
||||
|
||||
@@ -103,10 +161,11 @@ export class MapView {
|
||||
const seen = new Set();
|
||||
for (const p of players) {
|
||||
seen.add(p.id);
|
||||
const snapped = this.snapToTile(p.x, p.y);
|
||||
if (!this.otherSprites.has(p.id)) {
|
||||
const img = this.scene.add.image(p.x, p.y, 'other').setDepth(5);
|
||||
const img = this.scene.add.image(snapped.x, snapped.y, 'other').setDepth(5);
|
||||
const label = this.scene
|
||||
.add.text(p.x, p.y - 22, p.name || 'Player', {
|
||||
.add.text(snapped.x, snapped.y - 22, p.name || 'Player', {
|
||||
fontSize: '12px',
|
||||
color: '#9ca3af'
|
||||
})
|
||||
@@ -114,10 +173,11 @@ export class MapView {
|
||||
this.otherSprites.set(p.id, { img, label });
|
||||
} else {
|
||||
const rec = this.otherSprites.get(p.id);
|
||||
rec.img.setPosition(p.x, p.y);
|
||||
rec.label.setPosition(p.x, p.y - 22);
|
||||
rec.img.setPosition(snapped.x, snapped.y);
|
||||
rec.label.setPosition(snapped.x, snapped.y - 22);
|
||||
}
|
||||
}
|
||||
// Remove any that disappeared
|
||||
for (const [id, rec] of this.otherSprites) {
|
||||
if (!seen.has(id)) {
|
||||
rec.img.destroy();
|
||||
|
||||
Reference in New Issue
Block a user