fix: 优化跳跃和下落手感
This commit is contained in:
1 parent
ada64fe4be
commit
afe2f64b9b
25 files changed
+1197
-188
No files matched your search
+24
-17
@@ -1,18 +1,20 @@
|
||||
// 跳刺(Needle)10 关 —— IWBT 经典密集针刺风格
|
||||
// 设计语法(已经 tools/solve.mjs 验证):
|
||||
// 刺毯缺口每 4 格一个(单跳节奏);钻石中心 = 地板上方 2~3 格;
|
||||
// 刺毯缺口每 3 格一个(跳 2 连刺 = 64px 单跳节奏);钻石中心 = 地板上方 2~3 格;
|
||||
// 垂刺离最低落脚点 5 格(单跳安全、二段跳必死);2 格高矮洞可用撞头跳;
|
||||
// 竖井台阶每级升 2~3 格横移 3 格内;钢丝柱间距 ≤4(单跳)/ ≤6(二段)。
|
||||
import { Grid } from './kit.js';
|
||||
import { vgap, hgap, diamond, spikeRun, block, corner, ceil, wall, well } from './needle.js';
|
||||
|
||||
// 刺毯:从 x0 起 n 格留落脚缺口。
|
||||
// 缺口间距在 4/3 格之间交替(跳 3 格 / 跳 4 格轮换),避免整关都是"每 4 格一跳"的单一套路;
|
||||
// 最远仍是 3 连刺(单跳极限),配合压顶垂刺时二段跳必死。
|
||||
// 缺口间距统一 3 格(跳 2 连刺 = 64px)。
|
||||
// 2026-10-23:JUMP 7.5 + GRAV_FALL 0.55 下单跳水平实测 118.8px(tools/jumpdist.mjs),
|
||||
// 但落地前一帧竖直速度已达 8.9px/帧,3 连刺(96px)的起拍窗被压到 0~1 帧(不可玩);
|
||||
// 2 连刺留 55px 射程余量,落地窗恢复充裕。井口/左端右行出口处的 3 连刺须显式拆断(见各关 gaps 注释)
|
||||
const carpet = (m, x0, y, n, gaps = []) => {
|
||||
const g = [];
|
||||
let i = 3, k = 0;
|
||||
while (i < n) { g.push(i); i += (k++ % 2 === 0 ? 4 : 3); }
|
||||
let i = 3;
|
||||
while (i < n) { g.push(i); i += 3; }
|
||||
return spikeRun(m, x0, y, n, '^', g.concat(gaps));
|
||||
};
|
||||
|
||||
@@ -58,7 +60,7 @@ export const JUMP_LEVELS = [
|
||||
wall(m, 79, R - 5, R - 5, '<'); wall(m, 74, R - 7, R - 7, '>');
|
||||
// --- 上层回廊(地板 row 12)x80-97 ---
|
||||
m.rect(80, R - 10, 18, 1, '#');
|
||||
carpet(m, 81, R - 11, 15, [0]);
|
||||
carpet(m, 81, R - 11, 15, [0, 8]); // 8=x89:给对刺门留左侧起拍位(新物理下跳台落点偏右,须能走进 x90)
|
||||
ceil(m, 81, 95, R - 16); // row 6 垂刺
|
||||
hgap(m, 92, R - 11); // 对刺门
|
||||
m.set(82, R - 11, 'G'); m.set(94, R - 11, 'G');
|
||||
@@ -82,7 +84,7 @@ export const JUMP_LEVELS = [
|
||||
// ---- L0 地板 row 48(向右:刺毯 + 三道上下夹缝)----
|
||||
m.rect(1, 48, 66, 1, '#');
|
||||
m.set(3, 47, 'S');
|
||||
carpet(m, 5, 47, 50);
|
||||
carpet(m, 5, 47, 50, [1, 18]); // 1=x6 出生旁缺口;18=x23 放宽落点窗(3 连刺落点贴右腰会被 6px 状态桶卡死)
|
||||
ceil(m, 5, 54, 43);
|
||||
vgap(m, 16, 46); vgap(m, 30, 46); vgap(m, 46, 46);
|
||||
m.set(11, 47, 'G'); m.set(39, 47, 'G');
|
||||
@@ -100,7 +102,7 @@ export const JUMP_LEVELS = [
|
||||
m.set(2, 37, '^'); m.set(8, 35, '^');
|
||||
// ---- L2 地板 row 32(向右,井底延伸到右井下方)----
|
||||
m.rect(9, 32, 57, 1, '#');
|
||||
carpet(m, 11, 31, 46);
|
||||
carpet(m, 11, 31, 46, [1, 11, 31]); // 1=x12 拆井口 3 连刺;11=x22/31=x42 是 hgap 夹缝通道列(必须为空,否则整门变 3 连刺、4 格跳超射程)
|
||||
ceil(m, 11, 54, 27);
|
||||
hgap(m, 22, 31); hgap(m, 42, 31);
|
||||
vgap(m, 32, 30); vgap(m, 50, 30);
|
||||
@@ -110,7 +112,7 @@ export const JUMP_LEVELS = [
|
||||
m.set(65, 29, '^'); m.set(58, 27, '^');
|
||||
// ---- L3 地板 row 24(向左,掉落刺;垂刺避开左井 x2..9)----
|
||||
m.rect(2, 24, 56, 1, '#');
|
||||
carpet(m, 10, 23, 44);
|
||||
carpet(m, 10, 23, 44, [0]); // 0=x10:拆掉左端 3 连刺(左行跳落点差 0.8px 蹭 x10 左坡;L1 同位置能过是因 vgap(12) 清空了 x10-14,L3 没有)
|
||||
ceil(m, 10, 54, 19);
|
||||
[14, 24, 34, 44].forEach(x => m.set(x, 18, 'D'));
|
||||
vgap(m, 40, 22); vgap(m, 22, 22);
|
||||
@@ -120,7 +122,7 @@ export const JUMP_LEVELS = [
|
||||
m.set(2, 21, '^'); m.set(8, 19, '^');
|
||||
// ---- L4 地板 row 16(向右到终点)----
|
||||
m.rect(9, 16, 57, 1, '#');
|
||||
carpet(m, 11, 15, 52);
|
||||
carpet(m, 11, 15, 52, [1, 41]); // 1=x12 拆井口 3 连刺;41=x52 是 hgap 夹缝通道列(必须为空)
|
||||
ceil(m, 11, 60, 11);
|
||||
hgap(m, 26, 15); vgap(m, 40, 14); hgap(m, 52, 15);
|
||||
[18, 34, 56].forEach(x => m.set(x, 10, 'D'));
|
||||
@@ -175,8 +177,8 @@ export const JUMP_LEVELS = [
|
||||
m.border('#');
|
||||
m.rect(1, R, W - 2, 1, '%'); // 冰地板
|
||||
m.set(3, R - 1, 'S');
|
||||
// --- x6-30 冰面刺坑 ---
|
||||
for (const [a, b] of [[7, 10], [13, 16], [19, 22], [25, 29]])
|
||||
// --- x6-30 冰面刺坑(3 格宽:新物理单跳 108.8px > 96px;旧 4~5 格坑跳不过)---
|
||||
for (const [a, b] of [[7, 9], [13, 15], [19, 21], [25, 27]])
|
||||
for (let x = a; x <= b; x++) { m.set(x, R, '.'); m.set(x, R + 1, '^'); }
|
||||
ceil(m, 6, 24, R - 5); // 压顶垂刺:冰面上禁二段跳
|
||||
m.set(12, R - 1, 'G');
|
||||
@@ -284,10 +286,11 @@ export const JUMP_LEVELS = [
|
||||
wall(m, 129, 26, 26, '<'); wall(m, 122, 23, 23, '>'); wall(m, 129, 20, 20, '<');
|
||||
// ============ L1 中层(地板 row 16,向左折返,延伸到两侧井底)============
|
||||
m.rect(1, 16, 122, 1, '#');
|
||||
carpet(m, 9, 15, 112);
|
||||
carpet(m, 9, 15, 112, [86]); // 86=x95:补 hgap(95) 通道列(否则门芯留一根 '^',GRAV_FALL 0.40 下回跳轨迹下降慢正好嵌进去)
|
||||
ceil(m, 9, 118, 10);
|
||||
vgap(m, 108, 14); vgap(m, 82, 14); vgap(m, 56, 14); vgap(m, 30, 14);
|
||||
hgap(m, 95, 15); hgap(m, 43, 15);
|
||||
m.set(44, 15, '.'); // 拆掉对刺门左刺'<':GRAV 0.33 下从 x45 起跳第 3 帧必被刺尖别住(起拍窗窄到 2px),清掉后留 ^+> 双刺门,整格起拍都能过
|
||||
block(m, 69, 15, 2); block(m, 17, 15, 2);
|
||||
m.set(113, 15, 'G'); m.set(63, 15, 'G'); m.set(21, 15, 'G');
|
||||
// ============ 左井 x2-7 → L2(右墙底部留 3 格入口,桥接块接 L2 地板边)============
|
||||
@@ -377,10 +380,13 @@ export const JUMP_LEVELS = [
|
||||
for (let x = 76; x <= 99; x++) { m.set(x, R, '.'); m.set(x, R + 1, '^'); }
|
||||
m.set(78, R - 2, '-'); m.set(79, R - 2, '-');
|
||||
m.set(83, R - 4, '-'); m.set(84, R - 4, '-');
|
||||
m.set(88, R - 6, '-'); m.set(89, R - 6, '-');
|
||||
m.set(87, R - 6, '-'); m.set(88, R - 6, '-'); m.set(89, R - 6, '-');
|
||||
m.set(93, R - 4, '-'); m.set(94, R - 4, '-');
|
||||
m.set(97, R - 2, '-'); m.set(98, R - 2, '-');
|
||||
vgap(m, 86, R - 8); vgap(m, 93, R - 6);
|
||||
// x86 只留压顶刺:JUMP 8.0 下 apex 盒底 479 与 '^' 顶点 480 只差 1px,
|
||||
// 上升航线有 4 帧顶点落在盒内必死(8.5 时 apex 466 可从容擦过),故去掉地刺
|
||||
m.set(86, R - 9, 'v');
|
||||
vgap(m, 93, R - 6);
|
||||
m.set(101, R - 1, 'G');
|
||||
// --- x102-126 钻石收尾 ---
|
||||
carpet(m, 102, R - 1, 24, [0, 1, 20, 21]);
|
||||
@@ -405,7 +411,7 @@ export const JUMP_LEVELS = [
|
||||
// ============ L0 下层(地板 row 28)============
|
||||
m.rect(1, 28, W - 2, 1, '#');
|
||||
m.set(3, 27, 'S');
|
||||
carpet(m, 5, 27, 116);
|
||||
carpet(m, 5, 27, 116, [54]); // 54=x59:拆开矮洞入口的四格跳(洞顶 row24 会挡跳的横向漂移)
|
||||
ceil(m, 5, 120, 22);
|
||||
vgap(m, 14, 26); vgap(m, 38, 26);
|
||||
vgap(m, 86, 26); vgap(m, 110, 26);
|
||||
@@ -427,7 +433,7 @@ export const JUMP_LEVELS = [
|
||||
wall(m, 126, 24, 24, '<'); wall(m, 119, 21, 21, '>'); wall(m, 126, 18, 18, '<');
|
||||
// ============ L1 上层(地板 row 14,向左折返,延伸到井底)============
|
||||
m.rect(2, 14, 118, 1, '#');
|
||||
carpet(m, 9, 13, 108);
|
||||
carpet(m, 9, 13, 108, [27, 59]); // 27=x36 / 59=x68:补对刺门通道列(否则整门是一面 3 连刺,往回跳必被 < 刺别住)
|
||||
ceil(m, 9, 116, 8);
|
||||
hgap(m, 100, 13); hgap(m, 68, 13); hgap(m, 36, 13);
|
||||
vgap(m, 84, 12); vgap(m, 52, 12); vgap(m, 20, 12);
|
||||
@@ -498,6 +504,7 @@ export const JUMP_LEVELS = [
|
||||
wires.push(wx);
|
||||
for (const s of steps) { wx -= s; if (wx < 14) break; wires.push(wx); }
|
||||
wires.forEach((x, i) => m.vline(x, [6, 5, 7, 6, 7, 5][i % 6], 7, '#'));
|
||||
m.vline(55, 5, 7, '#'); // 过渡柱:x58→x52 原为 6 格跳,HSPD 2.6 下"晚二段"落点整体左移 8px 掉过柱顶摔死;x55 拆成 3+3 格两跳(dj=12 轨迹实测两跳都能精确接住)
|
||||
// 存档放在两根钢丝顶上
|
||||
const g1 = wires[6], g2 = wires[Math.floor(wires.length / 2) + 4];
|
||||
const topOf = i => [6, 5, 7, 6, 7, 5][i % 6];
|
||||
|
||||
Reference in new issue
Block a user