Fix player position by removing wrapper div, position bubble independently
This commit is contained in:
@@ -385,13 +385,15 @@ class Game {
|
|||||||
|
|
||||||
/* Player sprite stays horizontally centred; only Y shifts */
|
/* Player sprite stays horizontally centred; only Y shifts */
|
||||||
const p = document.getElementById('map-player');
|
const p = document.getElementById('map-player');
|
||||||
const pw = document.getElementById('map-player-wrap');
|
const bub = document.getElementById('player-bubble');
|
||||||
if (p && pw) {
|
if (p) {
|
||||||
const centreX = viewW / 2 - 16;
|
const centreX = viewW / 2 - 16;
|
||||||
const centreY = viewH * 0.65 + this.state.worldY;
|
const centreY = viewH * 0.65 + this.state.worldY;
|
||||||
pw.style.left = centreX + 'px';
|
const bottomPx = viewH - centreY - 40;
|
||||||
pw.style.bottom = (viewH - centreY - 40) + 'px';
|
p.style.left = centreX + 'px';
|
||||||
|
p.style.bottom = bottomPx + 'px';
|
||||||
p.className = `map-player walk-${dir}`;
|
p.className = `map-player walk-${dir}`;
|
||||||
|
if (bub) { bub.style.left = (centreX - 4) + 'px'; bub.style.bottom = (bottomPx + 64) + 'px'; }
|
||||||
}
|
}
|
||||||
|
|
||||||
this._checkNPCProximity();
|
this._checkNPCProximity();
|
||||||
@@ -416,12 +418,12 @@ class Game {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_checkNPCProximity() {
|
_checkNPCProximity() {
|
||||||
const world = document.getElementById('map-inner');
|
const world = document.getElementById('map-world');
|
||||||
const viewW = world ? world.parentElement.offsetWidth : 420;
|
const viewW = (world && world.offsetWidth) ? world.offsetWidth : 420;
|
||||||
const viewH = world ? world.parentElement.offsetHeight : 300;
|
const viewH = (world && world.offsetHeight) ? world.offsetHeight : 300;
|
||||||
const playerWorldX = this.state.worldX + viewW / 2;
|
const playerWorldX = this.state.worldX + viewW / 2;
|
||||||
const dx = Math.abs(playerWorldX - this.state.npcWorldX);
|
const dx = Math.abs(playerWorldX - this.state.npcWorldX);
|
||||||
const near = dx < 60;
|
const near = this.state.npcWorldX > 0 && dx < 60;
|
||||||
|
|
||||||
const hint = document.getElementById('map-talk-hint');
|
const hint = document.getElementById('map-talk-hint');
|
||||||
const bub = document.getElementById('npc-bubble');
|
const bub = document.getElementById('npc-bubble');
|
||||||
@@ -447,8 +449,9 @@ class Game {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_nearNPC() {
|
_nearNPC() {
|
||||||
const world = document.getElementById('map-inner');
|
if (!this.state.npcWorldX) return false;
|
||||||
const viewW = world ? world.parentElement.offsetWidth : 420;
|
const world = document.getElementById('map-world');
|
||||||
|
const viewW = (world && world.offsetWidth) ? world.offsetWidth : 420;
|
||||||
const playerWorldX = this.state.worldX + viewW / 2;
|
const playerWorldX = this.state.worldX + viewW / 2;
|
||||||
return Math.abs(playerWorldX - this.state.npcWorldX) < 60;
|
return Math.abs(playerWorldX - this.state.npcWorldX) < 60;
|
||||||
}
|
}
|
||||||
@@ -480,11 +483,14 @@ class Game {
|
|||||||
const viewH = world ? world.parentElement.offsetHeight : 300;
|
const viewH = world ? world.parentElement.offsetHeight : 300;
|
||||||
|
|
||||||
const p = document.getElementById('map-player');
|
const p = document.getElementById('map-player');
|
||||||
const pw = document.getElementById('map-player-wrap');
|
const bub = document.getElementById('player-bubble');
|
||||||
if (p && pw) {
|
if (p) {
|
||||||
pw.style.left = (viewW / 2 - 16) + 'px';
|
const left = viewW / 2 - 16;
|
||||||
pw.style.bottom = (viewH * 0.28) + 'px';
|
const bottom = viewH * 0.28;
|
||||||
|
p.style.left = left + 'px';
|
||||||
|
p.style.bottom = bottom + 'px';
|
||||||
p.className = 'map-player idle';
|
p.className = 'map-player idle';
|
||||||
|
if (bub) { bub.style.left = (left - 4) + 'px'; bub.style.bottom = (bottom + 64) + 'px'; }
|
||||||
}
|
}
|
||||||
this._applyCamera();
|
this._applyCamera();
|
||||||
const hint = document.getElementById('map-talk-hint');
|
const hint = document.getElementById('map-talk-hint');
|
||||||
|
|||||||
+1
-4
@@ -93,7 +93,6 @@
|
|||||||
<div class="map-right">
|
<div class="map-right">
|
||||||
<div class="prog-bar-outer"><div class="prog-bar-inner" id="map-prog-bar"></div></div>
|
<div class="prog-bar-outer"><div class="prog-bar-inner" id="map-prog-bar"></div></div>
|
||||||
<span class="prog-text" id="map-prog-text">0/100</span>
|
<span class="prog-text" id="map-prog-text">0/100</span>
|
||||||
<span class="save-dot" id="save-dot" title="Auto-saved">💾</span>
|
|
||||||
<span class="music-toggle" id="music-toggle" title="Mute/Unmute Music">🎵</span>
|
<span class="music-toggle" id="music-toggle" title="Mute/Unmute Music">🎵</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -108,11 +107,9 @@
|
|||||||
<div class="npc-bubble" id="npc-bubble">!</div>
|
<div class="npc-bubble" id="npc-bubble">!</div>
|
||||||
<div class="map-npc" id="map-npc"></div>
|
<div class="map-npc" id="map-npc"></div>
|
||||||
</div>
|
</div>
|
||||||
<!-- Player stays fixed to viewport, only Y moves -->
|
<!-- Player stays fixed to viewport, only Y moves -->\
|
||||||
<div class="map-player-wrap" id="map-player-wrap">
|
|
||||||
<div class="player-bubble" id="player-bubble">...</div>
|
<div class="player-bubble" id="player-bubble">...</div>
|
||||||
<div class="map-player" id="map-player"></div>
|
<div class="map-player" id="map-player"></div>
|
||||||
</div>
|
|
||||||
<!-- Hints overlay the viewport, not the world -->
|
<!-- Hints overlay the viewport, not the world -->
|
||||||
<div class="map-talk-hint" id="map-talk-hint" style="display:none"><span class="hint-pc">Press E</span><span class="hint-touch">Press A</span></div>
|
<div class="map-talk-hint" id="map-talk-hint" style="display:none"><span class="hint-pc">Press E</span><span class="hint-touch">Press A</span></div>
|
||||||
<div class="map-dir-arrow" id="map-dir-arrow" style="display:none">▶</div>
|
<div class="map-dir-arrow" id="map-dir-arrow" style="display:none">▶</div>
|
||||||
|
|||||||
@@ -483,8 +483,7 @@ html, body {
|
|||||||
.npc-bubble { font-size:14px; font-family:var(--font); color:var(--black); background:var(--yellow); border:2px solid var(--black); width:20px; height:20px; display:flex; align-items:center; justify-content:center; margin:0 auto 2px; animation:bounce .7s ease-in-out infinite; }
|
.npc-bubble { font-size:14px; font-family:var(--font); color:var(--black); background:var(--yellow); border:2px solid var(--black); width:20px; height:20px; display:flex; align-items:center; justify-content:center; margin:0 auto 2px; animation:bounce .7s ease-in-out infinite; }
|
||||||
.map-npc { font-size:clamp(36px,10vw,52px); filter:drop-shadow(2px 3px 0 rgba(0,0,0,.35)); cursor:pointer; }
|
.map-npc { font-size:clamp(36px,10vw,52px); filter:drop-shadow(2px 3px 0 rgba(0,0,0,.35)); cursor:pointer; }
|
||||||
/* Player is fixed to the viewport centre horizontally; only Y moves */
|
/* Player is fixed to the viewport centre horizontally; only Y moves */
|
||||||
.map-player-wrap { position:absolute; text-align:center; z-index:99; width:32px; height:64px; }
|
.player-bubble { font-size:11px; font-family:var(--font); color:var(--black); background:#fff; border:2px solid var(--black); padding:0 4px; height:20px; display:none; align-items:center; justify-content:center; border-radius:2px; white-space:nowrap; position:absolute; z-index:100; }
|
||||||
.player-bubble { font-size:11px; font-family:var(--font); color:var(--black); background:#fff; border:2px solid var(--black); padding:0 4px; height:20px; display:none; align-items:center; justify-content:center; border-radius:2px; white-space:nowrap; position:absolute; bottom:100%; left:50%; transform:translateX(-50%); margin-bottom:4px; }
|
|
||||||
.player-bubble.visible { display:flex; animation:bounce .5s ease-in-out 3; }
|
.player-bubble.visible { display:flex; animation:bounce .5s ease-in-out 3; }
|
||||||
.map-player {
|
.map-player {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|||||||
Reference in New Issue
Block a user