mirror of
https://github.com/Such-Software/wownerogue.git
synced 2026-10-17 14:21:25 +02:00
fix(fx): drop per-step red monster flash; big banner on descend/treasure
Red pulse: _fxOnPlayerMoved fired a full-screen red FX.flash whenever a monster was within 3
tiles (throttled 550ms) — the monster usually IS within 3 tiles, so it pulsed on nearly every
step. Removed it; the monster is already on-screen, so proximity needs no flash. FX.flash is now
reserved for genuine one-shots (win/lose).
Descend feedback: taking the stairs only logged a tiny chat line. Add showEventBanner() — a big
centered pop-in/hold/fade banner over the game view (pointer-events:none, auto-removed) fired on
descend ("LEVEL n / N") and treasure ("TREASURE SECURED"), with a soft one-shot colored flash.
Chat lines kept as the log trail.
This commit is contained in:
+4
-13
@@ -450,19 +450,10 @@ var Game = {
|
||||
window.FX.sparkle(pp.x, pp.y, '#fbbf24');
|
||||
}
|
||||
|
||||
// Monster proximity: throttled red edge pulse, stronger the closer it is.
|
||||
var m = GameState._monster;
|
||||
if (m && typeof m.x === 'number' && typeof m.y === 'number' && window.FX.flash) {
|
||||
var md = this._fxDist(player.x, player.y, m.x, m.y);
|
||||
if (md <= 3) {
|
||||
var now = Date.now();
|
||||
if (!this._fxLastMonsterFlash || (now - this._fxLastMonsterFlash) > 550) {
|
||||
this._fxLastMonsterFlash = now;
|
||||
var alpha = (md <= 1) ? 0.22 : (md <= 2 ? 0.14 : 0.09);
|
||||
window.FX.flash('rgba(255,60,60,1)', alpha, 260);
|
||||
}
|
||||
}
|
||||
}
|
||||
// NOTE: removed the monster-proximity red screen flash — it fired on nearly every step
|
||||
// (monster usually within 3 tiles) and read as a constant annoying pulse. The monster is
|
||||
// already visible on-screen, so proximity needs no full-screen flash. Reserve FX.flash for
|
||||
// genuine one-shot events (win/lose in handleGameOver).
|
||||
},
|
||||
|
||||
// Attach + start the FX loop for a fresh game.
|
||||
|
||||
@@ -139,8 +139,11 @@ const SocketHandlers = {
|
||||
var lvl = (data.depth && data.maxDepth) ? ('Level ' + data.depth + ' of ' + data.maxDepth + ' — ') : '';
|
||||
$m.append($('<li class="status" style="color:#ffcc00; font-weight:bold;">')
|
||||
.text('⬇️ Stairs down! ' + lvl + 'keep going — escape before the block!'));
|
||||
var lvlTitle = (data.depth && data.maxDepth) ? ('⬇ LEVEL ' + data.depth + ' / ' + data.maxDepth) : '⬇ DESCEND';
|
||||
SocketHandlers.showEventBanner(lvlTitle, 'Deeper in — escape before the block!', '#ffcc00');
|
||||
} else if (data.event === 'treasure_found') {
|
||||
$m.append($('<li class="status" style="color:#fbbf24; font-weight:bold;">').text('💰 Treasure secured!'));
|
||||
SocketHandlers.showEventBanner('💰 TREASURE SECURED', 'Now get to the stairs and escape!', '#fbbf24');
|
||||
} else return;
|
||||
if (typeof UI !== 'undefined' && UI.scrollChat) UI.scrollChat();
|
||||
});
|
||||
@@ -333,6 +336,42 @@ const SocketHandlers = {
|
||||
UI.scrollChat();
|
||||
},
|
||||
|
||||
// A big, one-shot on-screen banner over the game view for headline in-run events (descend /
|
||||
// treasure). Pops in, holds, fades — pointer-events:none so it never eats input, and auto-removes.
|
||||
showEventBanner: function(title, sub, color) {
|
||||
color = color || '#ffcc00';
|
||||
var host = document.getElementById('game-display') || document.body;
|
||||
if (!document.getElementById('evt-banner-style')) {
|
||||
var st = document.createElement('style');
|
||||
st.id = 'evt-banner-style';
|
||||
st.textContent =
|
||||
'@keyframes evtBannerIn{0%{opacity:0;transform:translate(-50%,-50%) scale(.6)}' +
|
||||
'12%{opacity:1;transform:translate(-50%,-50%) scale(1.12)}' +
|
||||
'22%{transform:translate(-50%,-50%) scale(1)}' +
|
||||
'76%{opacity:1;transform:translate(-50%,-50%) scale(1)}' +
|
||||
'100%{opacity:0;transform:translate(-50%,-50%) scale(1.05)}}';
|
||||
document.head.appendChild(st);
|
||||
}
|
||||
// Drop any banner still on screen so they never stack.
|
||||
var prev = document.getElementById('evt-banner');
|
||||
if (prev && prev.parentNode) prev.parentNode.removeChild(prev);
|
||||
|
||||
var b = document.createElement('div');
|
||||
b.id = 'evt-banner';
|
||||
var positioned = host.id === 'game-display'; // #game-display is position:relative
|
||||
b.style.cssText = (positioned ? 'position:absolute;' : 'position:fixed;') +
|
||||
'left:50%;top:34%;z-index:30;pointer-events:none;text-align:center;' +
|
||||
'font-family:ui-monospace,monospace;animation:evtBannerIn 2600ms ease-out forwards;';
|
||||
b.innerHTML =
|
||||
'<div style="font-size:38px;font-weight:900;letter-spacing:2px;color:' + color + ';' +
|
||||
'text-shadow:0 3px 0 #000,0 0 20px ' + color + '99;">' + title + '</div>' +
|
||||
(sub ? '<div style="font-size:15px;color:#e6ead0;margin-top:8px;text-shadow:0 2px 6px #000;">' + sub + '</div>' : '');
|
||||
host.appendChild(b);
|
||||
setTimeout(function () { if (b.parentNode) b.parentNode.removeChild(b); }, 2650);
|
||||
// A little extra pop: a soft colored flash if the FX overlay is up.
|
||||
try { if (window.FX && window.FX.flash) window.FX.flash(color, 0.16, 320); } catch (e) {}
|
||||
},
|
||||
|
||||
onStatusUpdate: function(data) {
|
||||
const statusClass = data.type === 'error' ? 'error' : 'status';
|
||||
const statusColor = data.type === 'error' ? '#f00' :
|
||||
|
||||
Reference in New Issue
Block a user