Sprites respect the window they are seen through
DUKK's floor-to-ceiling white sliver, decoded: the sprite gate only asked "did this column's ray warp?" — so a REAL body standing in front of a warp mouth was clipped out of the mouth's columns (leaving a baffling sliver of a huge close sprite), and a body virtualized through warp A could paint columns bent by warp B. Every column now remembers WHICH warp bent its ray and how far away that mouth stood; a real body paints a column only nearer than its mouth (in front of the window), and a virtual one only through its own warp's columns, beyond the mouth. Projectile legs carry the same identity. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
045e868190
commit
cd9ce9fddf
@@ -13,8 +13,8 @@ import type { GameEvent, GameView } from "@wizwar/engine";
|
||||
export type FpFx =
|
||||
| { id: number; kind: "projectile"; art: string; from: { x: number; y: number }; to: { x: number; y: number }; t0: number; dur: number;
|
||||
/** This leg flies in a warp mouth's virtual space: visible only
|
||||
* through the opening, on columns whose rays bent. */
|
||||
warped?: boolean }
|
||||
* through THAT warp's opening, beyond its mouth. */
|
||||
warped?: boolean; warpId?: number }
|
||||
| { id: number; kind: "impact"; art: string; at: { x: number; y: number }; t0: number; dur: number;
|
||||
/** Lifted off the floor (fireworks burst overhead); default 0.3. */
|
||||
rise?: number }
|
||||
@@ -62,19 +62,20 @@ const IMPACT_ART: Record<string, string> = {
|
||||
* clipped by the depth buffer to the side the camera stands on. */
|
||||
function projectileLegs(
|
||||
view: GameView, a: { x: number; y: number }, b: { x: number; y: number },
|
||||
): { from: { x: number; y: number }; to: { x: number; y: number }; warped?: boolean }[] {
|
||||
): { from: { x: number; y: number }; to: { x: number; y: number }; warped?: boolean; warpId?: number }[] {
|
||||
const len = Math.hypot(b.x - a.x, b.y - a.y);
|
||||
if (len < 0.05) return [{ from: a, to: b }];
|
||||
const direct = castRay(view, a.x, a.y, Math.atan2(b.y - a.y, b.x - a.x));
|
||||
if (!direct.warped && direct.dist >= len - 0.4) return [{ from: a, to: b }];
|
||||
for (const w of view.board.warps) {
|
||||
for (let wi = 0; wi < view.board.warps.length; wi++) {
|
||||
const w = view.board.warps[wi]!;
|
||||
const motion = warpMotion(w);
|
||||
const vt = motion.toVirtual(b);
|
||||
const vlen = Math.hypot(vt.x - a.x, vt.y - a.y);
|
||||
const hit = castRay(view, a.x, a.y, Math.atan2(vt.y - a.y, vt.x - a.x));
|
||||
if (hit.warped && hit.dist >= vlen - 0.4) {
|
||||
return [
|
||||
{ from: a, to: vt, warped: true },
|
||||
{ from: a, to: vt, warped: true, warpId: wi },
|
||||
{ from: motion.toReal(a), to: b },
|
||||
];
|
||||
}
|
||||
@@ -96,7 +97,7 @@ export function fpFxForEvents(
|
||||
out.push({
|
||||
fx: {
|
||||
id: nextId++, kind: "projectile", art,
|
||||
from: leg.from, to: leg.to, warped: leg.warped,
|
||||
from: leg.from, to: leg.to, warped: leg.warped, warpId: leg.warpId,
|
||||
t0: 0, dur: PROJECTILE_DUR[art]!,
|
||||
},
|
||||
delay,
|
||||
|
||||
Reference in New Issue
Block a user