Pneumatic nozzle: air streaks while sucking and blowing (t25)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -121,6 +121,42 @@ function drawDrillAim(ax, ay) {
|
||||
if (GAME.drillTune) { const sz = Math.max(6, zp * 1.4); ctx.fillStyle = rgbOf(GAME.drillTune); ctx.fillRect(p.x + k * 1.8, p.y - k * 1.8 - sz, sz, sz); ctx.strokeStyle = 'rgba(0,0,0,0.5)'; ctx.lineWidth = 1; ctx.strokeRect(p.x + k * 1.8 + 0.5, p.y - k * 1.8 - sz + 0.5, sz - 1, sz - 1); }
|
||||
ctx.restore();
|
||||
}
|
||||
// Air swirls into the pickup ring or spreads from the nozzle toward the cursor.
|
||||
function drawAirStreaks(ax, ay, p, r, blowing) {
|
||||
if (!SET.particles || (SET.fog && fogSeen(ax, ay) < 64)) return;
|
||||
const ctx = R.ctx, zp = R.zp, now = performance.now();
|
||||
const cx = p.x + zp / 2, cy = p.y + zp / 2, ring = (r + 0.5) * zp;
|
||||
ctx.save(); ctx.lineWidth = Math.max(1, zp * 0.2); ctx.lineCap = 'round';
|
||||
if (blowing) {
|
||||
const bx = bot.x + bot.w / 2, by = bot.y + bot.h / 2;
|
||||
const dx = ax + 0.5 - bx, dy = ay + 0.5 - by, d = Math.hypot(dx, dy) || 1;
|
||||
const o = worldToScreenPx(bx + dx / d * 3, by + dy / d * 3);
|
||||
const px = cx - o.x, py = cy - o.y, len = Math.hypot(px, py) || 1;
|
||||
const ux = px / len, uy = py / len;
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const phase = (now * 0.0016 + i * 0.618) % 1;
|
||||
const side = ((i * 0.37) % 1 - 0.5) * 2 * ring * phase;
|
||||
const x = o.x + px * phase - uy * side, y = o.y + py * phase + ux * side;
|
||||
ctx.strokeStyle = `rgba(255,210,122,${Math.sin(phase * Math.PI) * 0.55})`;
|
||||
ctx.beginPath(); ctx.moveTo(x, y); ctx.lineTo(x + ux * 1.6 * zp, y + uy * 1.6 * zp); ctx.stroke();
|
||||
}
|
||||
} else {
|
||||
const travel = ring * 0.65 + 3 * zp;
|
||||
for (let i = 0; i < 12; i++) {
|
||||
const phase = (now * 0.0012 + i * 0.618) % 1;
|
||||
const dist = ring + 3 * zp - travel * phase;
|
||||
const angle = i * Math.PI * 2 / 12 + now * 0.0004 + phase * 1.2;
|
||||
const co = Math.cos(angle), si = Math.sin(angle);
|
||||
const x = cx + co * dist, y = cy + si * dist;
|
||||
const vx = -travel * co - dist * (1.2 + 1 / 3) * si;
|
||||
const vy = -travel * si + dist * (1.2 + 1 / 3) * co;
|
||||
const scale = 1.2 * zp / Math.hypot(vx, vy);
|
||||
ctx.strokeStyle = `rgba(92,186,166,${Math.sin(phase * Math.PI) * 0.5})`;
|
||||
ctx.beginPath(); ctx.moveTo(x, y); ctx.lineTo(x + vx * scale, y + vy * scale); ctx.stroke();
|
||||
}
|
||||
}
|
||||
ctx.restore();
|
||||
}
|
||||
function drawPreviews() {
|
||||
const ctx = R.ctx, zp = R.zp;
|
||||
const t = toolId(), ax = Math.floor(GAME.aim.x), ay = Math.floor(GAME.aim.y);
|
||||
@@ -161,6 +197,7 @@ function drawPreviews() {
|
||||
ctx.strokeStyle = blowing ? 'rgba(255,210,122,0.22)' : 'rgba(92,186,166,0.22)'; ctx.lineWidth = Math.max(1, zp * (r + 0.5) * 0.6);
|
||||
ctx.beginPath(); ctx.moveTo(c.x, c.y); ctx.lineTo(p.x + zp / 2, p.y + zp / 2); ctx.stroke();
|
||||
}
|
||||
if (reachOk && (blowing || GAME.lmb)) drawAirStreaks(ax, ay, p, r, blowing);
|
||||
}
|
||||
} else if (t === 'build') {
|
||||
const P = piece(), b = aimBlock();
|
||||
|
||||
Reference in New Issue
Block a user