@flare-engine/形状
程序 2D 形状原始 反应-内生-斯基a. 12个被命名的原子形状 + 一个 SVG 路径逃生舱口——设计用于快速2D游戏原型,由原始人组成实体,而不用导入斯匹克艺术.
为什么
Mobile和Indie游戏原型不需要sprite被单开始. 将船,敌人,皮克和UI从原始人造出形状,将可玩的建筑船出,并只在机械锁后以艺术来取而代之——正是工作流程Unity shapes2D和Defold原生线文件. 形状-第一原型保持了迭代循环的紧凑:一个项目可以立即达到可玩状态并只在机械锁后再以斯匹克艺术相换.
安装
bun add @flare-engine/shapes @shopify/react-native-skia
@shopify/react-native-skia 是一个 可选的,只类型端点 —— 说 src/draw.ts 通过 import type 仅(用于注射) Skia 编号 : canvas 编号 : paint 因此它不会进入运行时间捆绑。 在网络/ CanvasKit 上完全跳过; 仅在本地 Skia 上实际渲染的地方添加它 .
使用量
import type { Skia as SkiaModule, SkCanvas, SkPaint } from '@shopify/react-native-skia';
import { drawShape, type ShapeSpec } from '@flare-engine/shapes';
// `Skia` from react-native-skia is a value; the handle type is `typeof Skia`
// (mirrors `type Skia = typeof SkiaModule` inside src/draw.ts).
type Skia = typeof SkiaModule;
function demo(skia: Skia, canvas: SkCanvas, paint: SkPaint): void {
// Compose any entity from primitives.
const shape: ShapeSpec = { kind: 'circle', r: 24, fill: 0xff8844cc };
drawShape(skia, canvas, paint, shape, /* x */ 100, /* y */ 200, /* rot */ 0);
// Need a custom shape? Use the SVG escape hatch:
const star: ShapeSpec = {
kind: 'path',
d: 'M 128 0 L 168 80 L 256 93 L 192 155 L 207 244 L 128 202 L 49 244 L 64 155 L 0 93 L 88 80 Z',
boundsR: 256,
fill: 0xffc9a24a,
};
drawShape(skia, canvas, paint, star, 0, 0, 0);
}
初级
13个光谱类型覆盖了每个常见的2D形状. 全部接受可选 fill (阿根廷英寸), stroke, (中文(简体) ), strokeWidth, (中文(简体) ), ox编号 :oy (单位:千美元), rot (弧度),和 glow: 'friendly' | 'hazard' | { color, width }。 。 。 .
| 仁爱 | 字段 | 使用大小写 |
|---|---|---|
circle | r | 子弹、皮卡、眼睛 |
rect | w, (中文(简体) ), h | 武器、HUD条、相框 |
triangle | size | 船体、箭头、象数 |
ngon | n, (中文(简体) ), r | 螺旋/戊角/章鱼壳 |
star | points, (中文(简体) ), rOuter, (中文(简体) ), rInner | 相机、火花、皮卡 |
ring | r | 奥拉斯,目标标记 |
polyline | points: number[] | 博尔特斯,自由手中风 |
gradient-rect | w, (中文(简体) ), h, (中文(简体) ), colorA, (中文(简体) ), colorB, (中文(简体) ), axis: 0|1 | HP 条,天条 |
arc | r, (中文(简体) ), startAngle, (中文(简体) ), endAngle, (中文(简体) ), sector? | 半圆形 1/4-月 1/8-月 |
annulus | rOuter, (中文(简体) ), rInner, (中文(简体) ), startAngle?, (中文(简体) ), endAngle? | 甜甜圈,半核桃,部分花环 |
trapezoid | topW, (中文(简体) ), botW, (中文(简体) ), h | 船舶驾驶舱,踏板 |
path | d, (中文(简体) ), boundsR | 逃逸舱门 任意 SVG 路径字符串 |
ship | hull, (中文(简体) ), weapons[], (中文(简体) ), engine | 综合(3-要素规则) |
组成实体
import type { ShapeSpec } from '@flare-engine/shapes';
// A ship: hull + 2 weapons + engine, painted back-to-front.
const playerShip: ShapeSpec = {
kind: 'ship',
hull: { kind: 'triangle', size: 28, fill: 0xffc9a24a },
weapons: [
{ kind: 'rect', w: 6, h: 12, fill: 0xffc9a24a, ox: -14, oy: 8 },
{ kind: 'rect', w: 6, h: 12, fill: 0xffc9a24a, ox: 14, oy: 8 },
],
engine: { kind: 'square', size: 20, fill: 0xff806020 },
};
// A pickup: ring + inner glow circle.
const amulet: readonly ShapeSpec[] = [
{ kind: 'ring', r: 9, stroke: 0xffc9a24a, strokeWidth: 2, glow: 'friendly' },
{ kind: 'circle', r: 3, fill: 0xffff2b2b },
];
边界
import {
shapeBoundsBox,
shapeBoundsRadius,
singleShapeRadius,
type ShapeSpec,
} from '@flare-engine/shapes';
declare const playerShip: ShapeSpec;
// For atlas tile sizing — max half-extent across a composition. Includes each
// shape's ox/oy offset, a stroke-width margin where a stroke is actually
// painted, and the full extent of a glow ring (+5.5 friendly, +2.25 hazard,
// +2.5 + width for a themed ring), so a tile sized from this fully contains
// what `drawShape` paints.
const tileRadius = shapeBoundsRadius([playerShip]);
// For hitboxes — per-axis extents with the same margins, so an asymmetric
// ship gets no dead space where a radius would. `shapeBoundsBoxInto(specs, out)`
// is the zero-alloc form for a caller-owned box.
const hit = shapeBoundsBox([playerShip]);
const hitWidth = hit.maxX - hit.minX;
const hitHeight = hit.maxY - hit.minY;
// For glow halo sizing — radius of one primitive.
const glowR = singleShapeRadius({ kind: 'circle', r: 14 });
添加一个新的原始
三种方式,按摩擦顺序排列:
-
使用
path逃出舱门. 特别工作组d="..."字符串本地解析通过Skia.Path.MakeFromSVGString。与 Figma / Inkscape / 相同的语法<path>零引擎变换. -
撰写一个组成. 将多个原始物包入一个
ShapeSpec[]阵列。 没有新的代码. -
添加一个命名为原始的. 当(1)/(2)不够人机组学,或者你需要一个被优化的分支时:
- 扩展
ShapeSpec工会src/types.ts - 添加一个
case 'kind':分支在drawShape(单位:千美元)src/draw.ts(中文(简体) ) - 在
singleShapeRadius(单位:千美元)src/bounds.ts(中文(简体) ) - 在其中添加测试
tests/draw.test.ts财务报告和审定财务报表tests/bounds.test.ts
Tsc 抓住了缺少的一步 3:
singleShapeRadius返回时number,所以没有处理的种类失败 编译. 没错 没有 抓住一个缺失步骤2 -drawShape返回时void它的开关没有default,所以没有绘图分支的新类型编译而无声无息地作画. - 扩展
发光
设定 glow 任何原始和 drawShape 画一环后身. 两个叫光环的免费来,一个 GlowSpec 对象在您的调色板上画出一个环:
| 发光 | 颜色 | 使用 |
|---|---|---|
'friendly' | 安全绿色 #6FA66B 零点25分,单相3分 r+4 | 玩家船、皮卡、安全标记 |
'hazard' | 危险-橙色 #E84B2A 0.6时双倍0.5平方圆 r+1 财务报告和审定财务报表 r+2 | 敌人子弹 危险提示 |
{ color, width } | 一个 width px 环入 color (ARGB),体内外的内缘 2.5 px | 任何主题 |
{ color: friendlyGlowArgb(), width: 3 } 画什么 'friendly' 颜料 帮助者范围由 2.5 + width 对于对象的形态,所以一个地图册的瓷砖或打箱会随环而生长. 非无限或负数 width 画出无指环并添加出无指向. applyGlow(canvas, paint, cx, cy, r, color, width) 直接为自定义堆肥绘制主题环.
import type { GlowSpec, ShapeSpec } from '@flare-engine/shapes';
const brandGlow: GlowSpec = { color: 0x40c9a24a, width: 4 };
const relic: ShapeSpec = { kind: 'star', points: 5, rOuter: 12, rInner: 5, fill: 0xffc9a24a, glow: brandGlow };
许可证
阿帕奇 - 2.0