revert(胎动): 去掉踢屏幕褶皱与快连踢,胎动恢复到 v26100406 (v26100412)
用户要求撤掉踢屏幕的效果、回到上一版;头图柔光/水波保留。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
/* 页面版本号(YYMMDD+序号):显示在「关于兜爸心选」页底部;bump 时同步 head 注释与 ?v= */
|
||||
var VER = '26100411';
|
||||
var VER = '26100412';
|
||||
const $ = (s, c) => (c || document).querySelector(s);
|
||||
const $$ = (s, c) => Array.from((c || document).querySelectorAll(s));
|
||||
|
||||
|
||||
60
js/bump.js
60
js/bump.js
@@ -81,13 +81,11 @@
|
||||
const STAGES = {
|
||||
// drum:原地带节奏连踢的概率;chain:踢完不歇、旁边紧接着再踢的概率,最多连 chainMax 下(2026-10-04 用户:「有时会带点节奏、可以连续踢」)
|
||||
flutter: { order: ['flick', 'flick', 'tap', 'flick'], gap: [10, 18], kick: false, again: 0, double: .45, follow: false, drum: 0, chain: 0 },
|
||||
active: { order: ORDER, gap: [4, 8], kick: true, again: .34, double: 0, follow: true, drum: .6, chain: .3, chainMax: 3 },
|
||||
late: { order: ['roll', 'butt', 'foot', 'roll', 'knee'], gap: [7, 12], kick: false, again: .15, double: 0, follow: true, slow: true, drum: .35, chain: .15, chainMax: 2 }
|
||||
active: { order: ORDER, gap: [4, 8], kick: true, again: .34, double: 0, follow: true, drum: .4, chain: .3, chainMax: 3 },
|
||||
late: { order: ['roll', 'butt', 'foot', 'roll', 'knee'], gap: [7, 12], kick: false, again: .15, double: 0, follow: true, slow: true, drum: .22, chain: .15, chainMax: 2 }
|
||||
};
|
||||
// 原地连踢的节奏型(每拍间隔,秒):匀速「哒哒哒」、「哒哒—哒」、「哒—哒哒」、两下一组
|
||||
// 2026-10-04 加了「噔噔噔」快连踢(.22~.26 秒一下),出现机会最大
|
||||
// 「噔噔噔噔」4 下快连踢放了 3 份,最常出现
|
||||
const RHYTHMS = [[.24, .24, .24, .24], [.22, .22, .22, .22], [.26, .26, .26, .26], [.24, .24, .24], [.42, .42, .42], [.3, .3, .75, .3], [.38, .38, .38, .38]];
|
||||
const RHYTHMS = [[.42, .42, .42], [.3, .3, .75, .3], [.6, .28, .28], [.32, .9, .32], [.38, .38, .38, .38]];
|
||||
const dbgWeek = (location.href.match(/bumpweek=(\d+)/) || [])[1];
|
||||
let week = dbgWeek ? +dbgWeek : (window.__mbPreg ? window.__mbPreg.week : null);
|
||||
const stageOf = w => w == null || w < 20 ? null : w < 26 ? STAGES.flutter : w < 34 ? STAGES.active : STAGES.late;
|
||||
@@ -226,7 +224,7 @@
|
||||
const inChain = ft.chained || ft.chainLeft > 0;
|
||||
if (inChain && !P.roll) ft.dur = (1.1 + Math.random() * .6) * (stage && stage.slow ? 1.3 : 1);
|
||||
// 原地连踢:脚丫 / 拳头 / 膝盖才有;晚期节奏放慢 1.4 倍。拍子排在第一下顶起来之后,整段时长跟着拉长
|
||||
ft.beats = null; ft.beat = 0; ft.pop = 0; ft.wp = 0; ft.wrot = 0; ft.wseed = Math.random() * 1000;
|
||||
ft.beats = null; ft.beat = 0; ft.pop = 0;
|
||||
if (!inChain && stage && stage.drum && !P.roll && !P.soft && P !== PARTS.kick && Math.random() < stage.drum) {
|
||||
const r = RHYTHMS[Math.random() * RHYTHMS.length | 0], m = stage.slow ? 1.4 : 1;
|
||||
let t = .7; ft.beats = r.map(d => (t += d * m));
|
||||
@@ -331,8 +329,6 @@
|
||||
|
||||
/* ---------- 物理 ---------- */
|
||||
function step(dt) {
|
||||
// 连踢时褶皱回落得快(0.24 秒基本退平),每一拍才是清楚的一下「噔」;单踢慢慢退
|
||||
if (ft.wp > 0) ft.wp = Math.max(0, ft.wp - dt * (ft.beats ? 4.2 : 1.4));
|
||||
if (mode === 'wait') {
|
||||
if (active() && idle()) { wait -= dt; if (wait <= 0) appear(); }
|
||||
} else if (mode === 'show') {
|
||||
@@ -342,15 +338,14 @@
|
||||
const k = Math.min(u / ft.dur, 1);
|
||||
ft.ox = ft.rollDir * (P.slide || 30) * k; ft.oy = -6 * Math.sin(k * Math.PI); ft.wob = Math.sin(u * 1.2) * .08;
|
||||
} else {
|
||||
if (u < .5 && ft.wp < .9) ft.wp = Math.max(ft.wp, u * 2); // 第一下顶起来时褶皱一起出
|
||||
ft.wob = Math.sin(u * 2.1) * .12;
|
||||
if (u > ft.dur * .4 && !ft.kicked && P !== PARTS.kick && !P.soft && stage && stage.kick) { ft.kicked = true; ft.h.vel += 70; ft.wp = 1; } // 中途再顶一下
|
||||
if (u > ft.dur * .4 && !ft.kicked && P !== PARTS.kick && !P.soft && stage && stage.kick) { ft.kicked = true; ft.h.vel += 70; } // 中途再顶一下
|
||||
// 一拍:先往回缩一下(鼓包塌一点),0.12 秒后再顶上来,位置跟着微微挪(脚尖 / 脚跟轮流使劲)
|
||||
if (ft.beats && ft.beat < ft.beats.length && u >= ft.beats[ft.beat]) {
|
||||
ft.beat++; ft.h.vel -= 85; ft.pop = .12;
|
||||
ft.ox += (Math.random() - .5) * 10; ft.oy += (Math.random() - .5) * 10;
|
||||
}
|
||||
if (ft.pop > 0 && (ft.pop -= dt) <= 0) { ft.h.vel += stage && stage.slow ? 110 : 180; ft.wp = 1; ft.wrot = (ft.wrot || 0) + (Math.random() - .5) * .35; } // 每一拍褶皱重新被踢出来,落点略偏一点
|
||||
if (ft.pop > 0 && (ft.pop -= dt) <= 0) ft.h.vel += stage && stage.slow ? 95 : 150;
|
||||
}
|
||||
if (u > ft.dur) {
|
||||
// 连续踢:这一下收得快一点,旁边紧接着再来,不等下一个间隔
|
||||
@@ -458,47 +453,6 @@
|
||||
}
|
||||
blob(x, y, rx, ry, ang, dark.concat(lite));
|
||||
}
|
||||
// 褶皱:像从背面顶一层绷紧的膜 —— 从鼓包边缘向外放射出几道弯弯的褶,每道 = 一条暗线 + 旁边错开一点的亮线,
|
||||
// 越往外越细越淡。k = 鼓得多高,pulse = 刚被踢那一下(连踢时每一拍都重新踢出来、更深一点)
|
||||
function rnd(n) { const x = Math.sin(n * 127.1 + 311.7) * 43758.5453; return x - Math.floor(x); }
|
||||
function wrinkles(x, y, rx, ry, ang, k, pulse, seed) {
|
||||
if (k < .08) return;
|
||||
const n = 8, R0 = Math.max(rx, ry);
|
||||
cx.save(); cx.translate(x, y); cx.rotate(ang); cx.lineCap = 'round';
|
||||
for (let i = 0; i < n; i++) {
|
||||
const a = (i + rnd(seed + i) * .6) / n * Math.PI * 2;
|
||||
const len = (.5 + rnd(seed + i * 3.1) * .6) * (1 + pulse * .35);
|
||||
const bend = (rnd(seed + i * 5.7) - .5) * .5;
|
||||
const ca = Math.cos(a), sa = Math.sin(a);
|
||||
// 起点贴着鼓包椭圆边,往外走
|
||||
const sx0 = ca * rx * .7, sy0 = sa * ry * .7;
|
||||
const ex = ca * (rx * .7 + R0 * len), ey = sa * (ry * .7 + R0 * len);
|
||||
const mx = (sx0 + ex) / 2 - sa * R0 * bend * len, my = (sy0 + ey) / 2 + ca * R0 * bend * len;
|
||||
const al = Math.min(1, k) * (.55 + .45 * pulse) * (.7 + .3 * rnd(seed + i * 9.2));
|
||||
// 垂直于褶的方向;统一让「朝左上」的那一侧亮(光从左上来,和鼓包的高光一致),褶棱才立得起来
|
||||
let nx = -sa, ny = ca;
|
||||
{ const wa = ang, wx = nx * Math.cos(wa) - ny * Math.sin(wa), wy = nx * Math.sin(wa) + ny * Math.cos(wa); if (wx + wy > 0) { nx = -nx; ny = -ny; } }
|
||||
// 每道褶 = 暗面 + 亮面两条宽软带,各用三层由宽到窄叠出虚边(canvas 的 filter:blur 在老 iOS 上不支持)
|
||||
for (const [col, a1, off] of [['60,48,42', .16, -2.4], ['255,255,255', .36, 2.4]]) {
|
||||
for (const [wm, am] of [[9, .45], [5.5, .7], [2.6, 1]]) {
|
||||
const g = cx.createLinearGradient(sx0, sy0, ex, ey);
|
||||
g.addColorStop(0, 'rgba(' + col + ',0)');
|
||||
g.addColorStop(.15, 'rgba(' + col + ',' + (a1 * am * al).toFixed(3) + ')');
|
||||
g.addColorStop(.6, 'rgba(' + col + ',' + (a1 * am * al * .5).toFixed(3) + ')');
|
||||
g.addColorStop(1, 'rgba(' + col + ',0)');
|
||||
cx.strokeStyle = g; cx.lineWidth = wm * (1 + pulse * .3);
|
||||
const ox = nx * off, oy = ny * off;
|
||||
cx.beginPath(); cx.moveTo(sx0 + ox, sy0 + oy); cx.quadraticCurveTo(mx + ox, my + oy, ex + ox, ey + oy); cx.stroke();
|
||||
}
|
||||
}
|
||||
}
|
||||
// 鼓包一圈绷紧的边:一道很淡的暗环,让「膜被撑开」更明显
|
||||
cx.scale(rx, ry);
|
||||
const g = cx.createRadialGradient(0, 0, .7, 0, 0, 1.15);
|
||||
g.addColorStop(0, 'rgba(70,58,52,0)'); g.addColorStop(.5, 'rgba(70,58,52,' + (.12 * Math.min(1, k)).toFixed(3) + ')'); g.addColorStop(1, 'rgba(70,58,52,0)');
|
||||
cx.fillStyle = g; cx.beginPath(); cx.arc(0, 0, 1.15, 0, 7); cx.fill();
|
||||
cx.restore();
|
||||
}
|
||||
function paint() {
|
||||
cx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
||||
cx.clearRect(0, 0, cv.width, cv.height);
|
||||
@@ -506,8 +460,6 @@
|
||||
const H = ft.h.v;
|
||||
if (H > .1) {
|
||||
const P = ft.part, sp = ft.spread.v, k = Math.min(H / 9, 1.3) / sp;
|
||||
// 2026-10-04 用户:「踢屏幕时前面要有比较明显的褶皱;连续踢就连续被踢出褶」—— 小鱼泡泡(早期)不出褶
|
||||
if (!P.soft) wrinkles(ft.x + ft.ox + ox, ft.y + ft.oy + oy, P.rx * sp, P.ry * sp, ft.ang + (ft.wrot || 0) + (mode === 'show' ? ft.wob : 0), Math.min(H / P.amp, 1.2), ft.wp || 0, ft.wseed || 0);
|
||||
blob(ft.x + ft.ox + ox, ft.y + ft.oy + oy, P.rx * sp, P.ry * sp, ft.ang + (mode === 'show' ? ft.wob : 0), [
|
||||
// 2026-10-04 用户:「凸起就行,不要变颜色(之前踢完泛浅红)」—— 只留中性灰的背光阴影 + 白高光,不带任何暖色
|
||||
[.16, .22, 1.02, 'rgba(70,62,58,' + (.1 * k).toFixed(3) + ')'],
|
||||
|
||||
Reference in New Issue
Block a user