Редизайн под новую Matrix-стилистику + RU/EN переключатель языка
Новая шапка (sticky, blur, мигающий курсор), нумерованные секции резюме с полным опытом работы и новым разделом «Образование», карточки проектов в стиле drwxr-xr-x, более яркий дождь на фоне. Добавлен i18n-модуль (frontend/js/i18n.js) с переключателем EN/RU: резюме и проекты полностью переведены, в игре переведены статичные подписи интерфейса лобби и боя (данные от сервера остаются на русском).
This commit is contained in:
+54
-15
@@ -1,6 +1,38 @@
|
||||
import { ClientMessage, ServerMessage } from './protocol.js';
|
||||
import { returnToLobbyContainer, leaveRoomAndReturn } from './lobby.js';
|
||||
import { playShot, playWallHit, playExplosion, playWin, playLose } from './audio.js';
|
||||
import { getLang } from '../i18n.js';
|
||||
|
||||
const STR = {
|
||||
ru: {
|
||||
controlsHint: 'WASD / стрелки + пробел тоже работают',
|
||||
fire: 'огонь',
|
||||
titles: { win: 'ПОБЕДА', lose: 'ПОРАЖЕНИЕ', draw: 'НИЧЬЯ' },
|
||||
rematch: 'играть ещё',
|
||||
toLobby: 'в лобби',
|
||||
},
|
||||
en: {
|
||||
controlsHint: 'WASD / arrow keys + space also work',
|
||||
fire: 'fire',
|
||||
titles: { win: 'VICTORY', lose: 'DEFEAT', draw: 'DRAW' },
|
||||
rematch: 'play again',
|
||||
toLobby: 'to lobby',
|
||||
},
|
||||
};
|
||||
|
||||
function t() {
|
||||
return STR[getLang()];
|
||||
}
|
||||
|
||||
// Регистрируем один раз на модуль: обновляем статичные подписи в уже
|
||||
// отрисованной панели управления и оверлей победы/поражения, если он открыт.
|
||||
window.addEventListener('cacto:langchange', () => {
|
||||
const hint = document.querySelector('.battle-controls__hint');
|
||||
if (hint) hint.textContent = t().controlsHint;
|
||||
const fireBtn = document.querySelector('.fire-btn');
|
||||
if (fireBtn) fireBtn.textContent = t().fire;
|
||||
if (lastOverPayload) renderOverlay(lastOverPayload);
|
||||
});
|
||||
|
||||
const TILE_PX = 32;
|
||||
// Quintus транслирует и вращает контекст сам (Sprite.render -> matrix.setContextTransform)
|
||||
@@ -282,6 +314,23 @@ function onState(payload) {
|
||||
}
|
||||
}
|
||||
|
||||
let lastOverPayload = null;
|
||||
|
||||
function renderOverlay(payload) {
|
||||
const title = t().titles[payload.result] || payload.result.toUpperCase();
|
||||
const overlay = document.getElementById('battle-result-overlay');
|
||||
overlay.innerHTML = `
|
||||
<div class="battle-result battle-result--${payload.result}">
|
||||
<h2 class="glitch" data-text="${title}">${title}</h2>
|
||||
<p>${payload.reason}</p>
|
||||
<div class="battle-result__actions">
|
||||
<button data-action="rematch">${t().rematch}</button>
|
||||
<button data-action="to-lobby">${t().toLobby}</button>
|
||||
</div>
|
||||
</div>`;
|
||||
overlay.style.display = 'flex';
|
||||
}
|
||||
|
||||
function onOver(payload) {
|
||||
polling = false;
|
||||
if (payload.result === 'win') {
|
||||
@@ -289,19 +338,8 @@ function onOver(payload) {
|
||||
} else {
|
||||
playLose();
|
||||
}
|
||||
const titles = { win: 'ПОБЕДА', lose: 'ПОРАЖЕНИЕ', draw: 'НИЧЬЯ' };
|
||||
const title = titles[payload.result] || payload.result.toUpperCase();
|
||||
const overlay = document.getElementById('battle-result-overlay');
|
||||
overlay.innerHTML = `
|
||||
<div class="battle-result battle-result--${payload.result}">
|
||||
<h2 class="glitch" data-text="${title}">${title}</h2>
|
||||
<p>${payload.reason}</p>
|
||||
<div class="battle-result__actions">
|
||||
<button data-action="rematch">играть ещё</button>
|
||||
<button data-action="to-lobby">в лобби</button>
|
||||
</div>
|
||||
</div>`;
|
||||
overlay.style.display = 'flex';
|
||||
lastOverPayload = payload;
|
||||
renderOverlay(payload);
|
||||
}
|
||||
|
||||
function onOverlayClick(e) {
|
||||
@@ -310,6 +348,7 @@ function onOverlayClick(e) {
|
||||
const overlay = document.getElementById('battle-result-overlay');
|
||||
overlay.style.display = 'none';
|
||||
overlay.innerHTML = '';
|
||||
lastOverPayload = null;
|
||||
if (btn.dataset.action === 'rematch') {
|
||||
returnToLobbyContainer();
|
||||
} else {
|
||||
@@ -331,14 +370,14 @@ export function startBattle(networkInstance, payload, ownPlayerId) {
|
||||
<div class="battle-layout">
|
||||
<div id="battle-canvas-slot"></div>
|
||||
<div class="battle-controls">
|
||||
<p class="battle-controls__hint">WASD / стрелки + пробел тоже работают</p>
|
||||
<p class="battle-controls__hint">${t().controlsHint}</p>
|
||||
<div class="dpad">
|
||||
<button class="dpad__up" data-input="up">↑</button>
|
||||
<button class="dpad__left" data-input="left">←</button>
|
||||
<button class="dpad__right" data-input="right">→</button>
|
||||
<button class="dpad__down" data-input="down">↓</button>
|
||||
</div>
|
||||
<button class="fire-btn" data-input="fire">огонь</button>
|
||||
<button class="fire-btn" data-input="fire">${t().fire}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="battle-result-overlay"></div>`;
|
||||
|
||||
Reference in New Issue
Block a user