diff -ruN a/index.html b/index.html --- a/index.html +++ b/index.html @@ -8,6 +8,7 @@ name="description" content="NEON RUMBLE is a dependency-free 2D fighting game built with HTML5 Canvas. Jab, kick, block, anti-air and land supers in a neon city." /> + moves S+light low · S+heavy launcher · forward+kick overhead · J+K throw (tech J+K) · motion + attack special · double motion + heavy super · tap direction twice to dash

-

- open source · MIT · - github.com/hao035414-cmyk/neon-rumble -

diff -ruN a/src/characters.js b/src/characters.js --- a/src/characters.js +++ b/src/characters.js @@ -4,12 +4,12 @@ */ export const CHARACTER_MOVES = { - kai: { id: 'kai', role: '均衡', weapon: 'fist', stats: { speed: 3, power: 3, range: 3, difficulty: 2 }, u: 'plasma', s: 'dp', super: 'super' }, - rin: { id: 'rin', role: '突进', weapon: 'blades', stats: { speed: 5, power: 3, range: 2, difficulty: 3 }, u: 'kunai', s: 'rush', super: 'rinSuper' }, - volt: { id: 'volt', role: '投技', weapon: 'gauntlet', stats: { speed: 2, power: 5, range: 2, difficulty: 2 }, u: 'quake', s: 'grab', super: 'superThrow' }, - nova: { id: 'nova', role: '弓手', weapon: 'bow', stats: { speed: 3, power: 2, range: 5, difficulty: 4 }, u: 'arrow', s: 'bowSweep', super: 'superArrow' }, - saber: { id: 'saber', role: '连击', weapon: 'claws', stats: { speed: 4, power: 4, range: 2, difficulty: 4 }, u: 'sonic', s: 'triple', super: 'superRush' }, - echo: { id: 'echo', role: '设置', weapon: 'device', stats: { speed: 2, power: 3, range: 4, difficulty: 3 }, u: 'resonance', s: 'orb', super: 'superOrb' }, + kai: { id: 'kai', role: 'BALANCED', weapon: 'fist', stats: { speed: 3, power: 3, range: 3, difficulty: 2 }, u: 'plasma', s: 'dp', super: 'super' }, + rin: { id: 'rin', role: 'RUSHDOWN', weapon: 'blades', stats: { speed: 5, power: 3, range: 2, difficulty: 3 }, u: 'kunai', s: 'rush', super: 'rinSuper' }, + volt: { id: 'volt', role: 'GRAPPLER', weapon: 'gauntlet', stats: { speed: 2, power: 5, range: 2, difficulty: 2 }, u: 'quake', s: 'grab', super: 'superThrow' }, + nova: { id: 'nova', role: 'ARCHER', weapon: 'bow', stats: { speed: 3, power: 2, range: 5, difficulty: 4 }, u: 'arrow', s: 'bowSweep', super: 'superArrow' }, + saber: { id: 'saber', role: 'COMBO', weapon: 'claws', stats: { speed: 4, power: 4, range: 2, difficulty: 4 }, u: 'sonic', s: 'triple', super: 'superRush' }, + echo: { id: 'echo', role: 'SETPLAY', weapon: 'device', stats: { speed: 2, power: 3, range: 4, difficulty: 3 }, u: 'resonance', s: 'orb', super: 'superOrb' }, }; export function validateCharacterMoves(moves, allMoves) { diff -ruN a/src/render-select.js b/src/render-select.js --- a/src/render-select.js +++ b/src/render-select.js @@ -124,7 +124,7 @@ if (!pick) { ctx.fillStyle = 'rgba(255,255,255,0.5)'; ctx.font = '13px "Segoe UI", "Microsoft YaHei", sans-serif'; - ctx.fillText(state.locked[id] ? 'LOCKED' : '选择中…', x + 14, y + 52); + ctx.fillText(state.locked[id] ? 'LOCKED' : 'CHOOSING...', x + 14, y + 52); return; } const char = CHARACTERS[pick]; @@ -140,14 +140,14 @@ ctx.fillText(moves.role + ' · ' + moves.weapon, x + 14, y + 98); const stats = moves.stats; - statBar(ctx, x + 14, y + 132, w - 28, '速度', stats.speed, color); - statBar(ctx, x + 14, y + 156, w - 28, '力量', stats.power, color); - statBar(ctx, x + 14, y + 180, w - 28, '距离', stats.range, color); - statBar(ctx, x + 14, y + 204, w - 28, '难度', stats.difficulty, color); + statBar(ctx, x + 14, y + 132, w - 28, 'SPEED', stats.speed, color); + statBar(ctx, x + 14, y + 156, w - 28, 'POWER', stats.power, color); + statBar(ctx, x + 14, y + 180, w - 28, 'RANGE', stats.range, color); + statBar(ctx, x + 14, y + 204, w - 28, 'SKILL', stats.difficulty, color); ctx.fillStyle = 'rgba(255,255,255,0.55)'; ctx.font = '11px "Segoe UI", "Microsoft YaHei", sans-serif'; - ctx.fillText('U 远程 · S 必杀 · 超杀', x + 14, y + h - 14); + ctx.fillText('U ranged · S special · Super', x + 14, y + h - 14); } export function drawCharacterSelect(ctx, state, t) { @@ -163,7 +163,7 @@ ctx.fillText('SELECT YOUR FIGHTER', VW / 2, 56); ctx.fillStyle = 'rgba(255,255,255,0.5)'; ctx.font = '13px "Segoe UI", "Microsoft YaHei", sans-serif'; - ctx.fillText(state.mode === 'cpu' ? '1P vs CPU · 难度 ' + state.difficulty.toFixed(1) : 'LOCAL 2P', VW / 2, 80); + ctx.fillText(state.mode === 'cpu' ? '1P vs CPU · difficulty ' + state.difficulty.toFixed(1) : 'LOCAL 2P', VW / 2, 80); drawGrid(ctx, state, t); drawPlayerPanel(ctx, state, 'p1', 16, 140, 176, 300); @@ -175,8 +175,8 @@ ctx.fillText(Math.max(0, Math.ceil(state.timer / 60)), VW / 2, 470); ctx.fillStyle = 'rgba(255,255,255,0.5)'; ctx.font = '12px "Segoe UI", "Microsoft YaHei", sans-serif'; - ctx.fillText('P1: A/D 选择 · J 确认 · K 返回', VW / 2, 496); - ctx.fillText('P2: 方向键选择 · 小键盘1 确认 · 小键盘2 返回', VW / 2, 516); + ctx.fillText('P1: A/D choose · J confirm · K back', VW / 2, 496); + ctx.fillText('P2: arrows choose · numpad 1 confirm · numpad 2 back', VW / 2, 516); } export function drawStageSelect(ctx, state, t) { @@ -194,7 +194,7 @@ const chooser = state.stageChooser; ctx.fillStyle = chooser === 'p1' ? P1 : P2; ctx.font = '13px "Segoe UI", "Microsoft YaHei", sans-serif'; - ctx.fillText((chooser === 'p1' ? 'P1' : 'P2') + ' 选择地图' + (state.lastLoser ? ' · 上局败者' : ''), VW / 2, 76); + ctx.fillText((chooser === 'p1' ? 'P1' : 'P2') + ' picks the stage' + (state.lastLoser ? ' · lost the last match' : ''), VW / 2, 76); const ids = state.stages.concat(['random']); const cols = 3; @@ -234,7 +234,7 @@ ctx.fillText(stage ? stage.name : 'RANDOM', x + 16, y + h - 28); ctx.fillStyle = 'rgba(255,255,255,0.65)'; ctx.font = '12px "Segoe UI", sans-serif'; - ctx.fillText(stage ? stage.subtitle + ' · BGM ' + stage.music : '随机地图', x + 16, y + h - 10); + ctx.fillText(stage ? stage.subtitle + ' · BGM ' + stage.music : 'RANDOM STAGE', x + 16, y + h - 10); if (state.stageCursor === i) { ctx.strokeStyle = chooser === 'p1' ? P1 : P2; @@ -252,7 +252,7 @@ ctx.fillText(Math.max(0, Math.ceil(state.timer / 60)), VW / 2, 500); ctx.fillStyle = 'rgba(255,255,255,0.5)'; ctx.font = '12px "Segoe UI", "Microsoft YaHei", sans-serif'; - ctx.fillText('J / 小键盘1 确认 · K / 小键盘2 返回', VW / 2, 522); + ctx.fillText('J / numpad 1 confirm · K / numpad 2 back', VW / 2, 522); } export function drawVS(ctx, state, frame) { diff -ruN a/src/stages.js b/src/stages.js --- a/src/stages.js +++ b/src/stages.js @@ -5,7 +5,7 @@ export const STAGES = [ { id: 'neon_city', - name: '霓虹街道', + name: 'NEON STREET', subtitle: 'NEON CITY', kind: 'city', music: 'neon_city', @@ -22,7 +22,7 @@ }, { id: 'desert_dusk', - name: '荒漠落日', + name: 'DESERT SUNSET', subtitle: 'DESERT DUSK', kind: 'desert', music: 'desert_dusk', @@ -39,7 +39,7 @@ }, { id: 'snow_peak', - name: '雪山之巅', + name: 'SNOW SUMMIT', subtitle: 'SNOW PEAK', kind: 'snow', music: 'snow_peak', @@ -56,7 +56,7 @@ }, { id: 'grassland_wind', - name: '草原长风', + name: 'WINDY PLAINS', subtitle: 'GRASSLAND WIND', kind: 'grass', music: 'grassland_wind', @@ -73,7 +73,7 @@ }, { id: 'rainy_night', - name: '雨夜街头', + name: 'RAINY NIGHT STREETS', subtitle: 'RAINY NIGHT', kind: 'rain', music: 'rainy_night',