pixel-perfect rendering, all sprites have same 1:1 scale
This commit is contained in:
+18
-4
@@ -3,6 +3,15 @@ import { Graphics } from 'pixi.js';
|
||||
/** Matches `.health-bar`/`.health-bar__fill` in App.css. */
|
||||
const WIDTH = 28;
|
||||
const HEIGHT = 5;
|
||||
const BORDER_WIDTH = 1;
|
||||
// The fill sits inside the border's own inner edge, not flush with the bar's outer bounds — Pixi
|
||||
// centers a stroke on its path by default (half the stroke width paints inward), so a fill drawn
|
||||
// flush to (0,0)-(WIDTH,HEIGHT) would paint over that inward half on the top/bottom/left edges,
|
||||
// visibly overlapping the border. The original CSS version didn't have this problem: `.health-
|
||||
// bar__fill` was a child div sized to the *parent's content box*, which excludes its border by
|
||||
// definition.
|
||||
const INNER_WIDTH = WIDTH - BORDER_WIDTH * 2;
|
||||
const INNER_HEIGHT = HEIGHT - BORDER_WIDTH * 2;
|
||||
|
||||
export function createHealthBar(): Graphics {
|
||||
return new Graphics();
|
||||
@@ -16,13 +25,18 @@ export function updateHealthBar(g: Graphics, ratio: number): void {
|
||||
g.clear();
|
||||
g.rect(0, 0, WIDTH, HEIGHT)
|
||||
.fill({ color: 0x000000, alpha: 0.5 })
|
||||
.stroke({ width: 1, color: 0x1b1611 });
|
||||
.stroke({ width: BORDER_WIDTH, color: 0x1b1611 });
|
||||
if (clamped > 0)
|
||||
g.rect(0, 0, WIDTH * clamped, HEIGHT).fill(0x4caf50);
|
||||
g.rect(BORDER_WIDTH, BORDER_WIDTH, INNER_WIDTH * clamped, INNER_HEIGHT).fill(0x4caf50);
|
||||
}
|
||||
|
||||
/** Positions a health bar so (x, yAboveSprite) is its bottom-center, same anchor as the original
|
||||
* CSS transform. */
|
||||
* CSS transform. Rounded to the nearest whole world-pixel: a vector shape rasterized (without
|
||||
* antialiasing — see PixelPerfectWorld) at a fractional position can flip a full pixel row in or
|
||||
* out depending on exactly where the fraction falls, and `yAboveSprite` tracks a jumping rabbit's
|
||||
* continuously-changing height — left unrounded, the bar's fill visibly "jumps" a pixel in height
|
||||
* frame to frame for as long as the jump lasts (most noticeable there specifically, since the
|
||||
* position — and so the sub-pixel fraction — is otherwise constant while idle). */
|
||||
export function setHealthBarPosition(g: Graphics, x: number, yAboveSprite: number): void {
|
||||
g.position.set(x - WIDTH / 2, yAboveSprite - HEIGHT);
|
||||
g.position.set(Math.round(x - WIDTH / 2), Math.round(yAboveSprite - HEIGHT));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user