mcpField
P
pixelfx

pixelfx

github.com/patch-gg创意与媒体4.1k14 次安装3 天前更新
代码仓库

关于 pixelfx

pixelfx 是用代码绘制像素艺术效果的工具集,适用于 JavaScript 游戏开发者及需要导出动画素材的团队。效果可实时调整颜色、方向和随机种子,也可渲染为精灵图集供其他引擎使用。

主要功能

  1. 01以代码绘制双缓冲像素效果
  2. 02调整调色板、方向、光效和种子
  3. 03渲染精灵图集与动画帧
  4. 04检查循环、画布边界与性能

适用场景

  1. 01在 JavaScript 游戏中实时播放效果
  2. 02为 Godot 或 Unity 导出动画图集
  3. 03制作并检查角色攻击效果

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/patch-gg/pixelfx --skill pixelfx

安装后在 Claude Code 中输入/pixelfx确认已加载。

详细介绍

pixelfx

将像素艺术效果编写为代码。每个效果都是一个文件,src/fx/<category>/<name>.js,绘制到两个缓冲区中: color(像素:不透明、抖动或真正半透明)和 light(加色发光)。无需图像,因此效果可以实时播放、重新着色、镜像、重新设定随机种子,并渲染成适用于任何引擎的精灵图集。

此方法来自 Hugo Duprez(如何用 Claude 制作(出色的)像素艺术效果):代码是黏土,相信你的眼睛,提供参考素材。一次性提示词只能生成平庸的效果。将草稿渲染出来、仔细观察并不断改进,才能做出好效果。

开始之前

  1. 在 pixelfx 检出目录中操作。如果工作目录下没有 tools/render.mjs,就在项目旁克隆一份:git clone https://github.com/patch-gg/pixelfx。无需安装:这些工具只用到 Node。
  2. 检查能否运行:node tools/render.mjs fire/torch 会写入 records/fire/torch/contact.png。用你的图像读取工具打开这个 PNG。从现在起,你可以通过这张联系表查看每个效果。

1. 先查找现有的效果

node tools/list.mjs <words> 会搜索 ID、名称、标签和描述(node tools/list.mjs frost、node tools/list.mjs slash loop)。docs/CATALOG.md 按类别列出了所有效果。先渲染候选效果并查看,再做选择。大多数需求都可以通过调整现有效果的选项来满足:

  • palette:主色阶,从暗到亮,以十六进制字符串表示。可以使用 src/core/color.js 中的任意 PAL 色阶(fire ember lava smoke dust ice water electric volt poison holy heal arcane shadow blood earth stone gold leaf wood metal bone neon cyber matrix candy night),也可以使用自己的色阶。蓝色火焰可以这样指定:{"palette": PAL.ice}。
  • seed 用于生成不同但等效的效果;flip 用于朝左;angle 用于旋转;light(0..1+)用于调整辉光强度;还可以设置每个效果在其 meta.options 中的专属参数(大小、数量、半径、文本、高度……)。
  • 无需编辑代码即可试用选项:node tools/render.mjs fire/torch --opts '{"palette":["#102","#215","#43a","#8cf","#fff"]}'。

2. 放进游戏

使用 JS 或 TS 的 Canvas 或 WebGL 游戏(原生 canvas、Phaser、PixiJS、Kaplay、three.js):直接使用代码即可。它 没有依赖;复制 src/core 和所需的效果文件,或依赖此仓库。

import { createFrame, clearFrame, createFx, composite } from "pixelfx";   // src/core/index.js
import * as frostNova from "pixelfx/fx/ice/frost-nova";                   // src/fx/ice/frost-nova.js

const frame = createFrame(320, 180);            // the game's pixel resolution; ox, oy scroll it with the camera
const img = new ImageData(320, 180);
const fx = createFx(frostNova, { x: hero.x, y: hero.y, flip: hero.facing < 0 });

// every tick
fx.update(dt);
clearFrame(frame);
fx.draw(frame, "back");    // what goes behind characters
drawCharacters();          // your own sprites, or draw them into frame.color yourself
fx.draw(frame, "front");
composite(frame, img.data, background);   // color over the background plus light; or null for transparent
ctx.putImageData(img, 0, 0);              // then scale the canvas up with image-rendering: pixelated
if (fx.done()) removeIt();               // one-shots end on their own; fx.stop() fades a loop out

多个效果可以共用一帧。在 WebGL 引擎中,每帧将合成后的 RGBA 上传到纹理,或者将效果一次性渲染到精灵图(见下文),然后像播放其他动画一样播放。

任何引擎(Godot、Unity、GameMaker、Defold、LÖVE、Bevy、Construct):导出精灵图。 node tools/render.mjs ice/frost-nova --sheet 会生成 records/ice/frost-nova/frost-nova.png(网格排列的透明帧)和 frost-nova.json(Aseprite 风格的帧数据,因此 Phaser 的图集加载器、Godot 和 Unity 的 Aseprite 导入器以及大多数工具都能读取;meta.pixelfx 包含 fps、循环、帧尺寸、列数和轴心点)。将 轴心点设为 meta.pixelfx.pivot(效果的原点,例如脚部),以最近邻过滤且不压缩的方式导入,并按 meta.pixelfx.fps 播放。辉光会以带 alpha 的颜色烘焙到精灵图中,在暗色场景上会呈现叠加效果;对于明亮场景,可渲染重新着色的版本,或将效果放在暗色图层上。

如需完整素材库:node tools/render.mjs <category> --sheet 会处理整个分类。

命中效果需要有角色作为衬托。 单独的效果看起来像贴纸。带有角色的效果附带一个 act:角色何时蓄力、何时定格,以及目标如何反应。根据游戏的构建方式选择使用:

  • 使用内置角色:用 createAct(slash, { x, y }) 代替 createFx。调用 act.update(dt)、act.draw(frame),并通过 act.shake 抖动画面。冻结期间它会自动保持静止。node tools/act.mjs <id> --sheet 会将所有内容烘焙到精灵图中。
  • 使用游戏自带角色:读取时序信息,即 slash.act,或精灵图 JSON 中的 meta.pixelfx.act(包含 windup、recovery,以及带有 t 和 freeze 的 hits)。在效果出现前 windup 秒播放角色的攻击动画,并在每次命中时停止更新所有内容,包括效果和角色,持续 freeze 秒。宿主端的命中定格适用于任何效果,无论是否带有 act。

src/fx/moves/ 包含由效果串联而成的完整攻击,从蓄力到收招:有人需要招式时,从这里开始找,而不是从效果开始。

3. 制作新效果

先阅读 docs/AUTHORING.md:其中定义了约定(meta、纯效果使用 draw(p, t, o),模拟效果使用 create(o)、局部坐标、无缝循环、结束时画面为空)、工具包、绘制器 API 和质量标准。 然后:

  1. 用一句话描述艺术方向:它是什么、如何运动、采用什么配色、时长如何。“冰霜新星: 晶体从脚下向外呈环状迸发,中心闪出一道白光,碎片旋转飞散,地面留下冰霜并逐渐消退。”
  2. 查找参考:在素材库中运行 node tools/list.mjs <words>,然后阅读最接近的两三个特效文件,并借鉴其中的技巧(用于火花、烟雾和碎屑的 src/core/sim.js 中的 Particles 和 Bits、用于半透明体积的 p.disc、用于无缝粒子的 cycle、用于火焰和水流的 tileFbm 滚动)。也看看 Hugo Duprez 的特效 中最接近的作品:它们是品质标杆。如果他的作品在屏幕上尺寸相同时有更多细节、光效或生命力,你的作品就还没完成。
  3. **起草。**运行 node tools/new.mjs <category>/<name>(循环动画请添加 --loop)即可生成可用文件。如果方向尚未确定,就写 3 到 5 个真正不同的草稿(<name>-a.js .. -e.js),全部渲染(node tools/render.mjs "<category>/<name>-"),并查看每张联系表后再做选择。如果用户在场,向其展示最出色的两三个版本(--gif 可生成便于分享的动画)。
  4. **观察、评判、修改。**渲染后打开 records/<id>/contact.png,像挑剔的像素画师一样进行评判。修复最糟糕的问题,然后再次渲染。至少迭代三轮;精品特效需要更多轮。--all 可显示每一帧,--mp4 可全速展示动画。
  5. 如果涉及角色,就演出来:添加 export const act(参见 docs/AUTHORING.md 中的“Acts”),包含 t = 0 之前的蓄力、释放帧上的姿势变化、接触时的定格以及恢复动作。node tools/act.mjs <id> 会以 12 fps 显示连续步骤:根据这些步骤和 --mp4 判断动作,不要只看联系表中的采样帧。
  6. 检查。node tools/check.mjs <id> 会检测画布外绘制、结束时画面不为空的一次性动画、循环衔接、未设种子的随机性和慢帧;对于动作,还会检测顺序错误的按键、未知姿势字段以及瞬移的手部。持续修复,直到检查完全通过。删除未保留的草稿。

需要关注的方面及常见修复方法:

你看到的情况修复方法
以 1x 查看时显得模糊一团减少颜色,轮廓清晰,突出一个焦点,形状更大
出现斑点:形状内部有孤立的噪点像素降低阈值噪声,用 at() 量化,小形状上不加噪声
飘忽无力,缺乏冲击感快速进入、缓慢退出(ease.outQuart/outExpo),加入 1 到 2 帧的白色主帧,缩短总时长
僵硬或机械让每个粒子各不相同(大小、速度、延迟、寿命),添加次要动态效果(火花、烟雾、碎屑)
颜色发白减少辉光(k 取 0.2 到 0.5),边缘色阶更暗,只让最亮的核心部分保持白色
画面平淡让光线从一侧照来:左上角更亮,右下角色阶更暗;底部增加更暗的色阶
渐变平滑,显得像矢量图使用明确的色阶;只在光线和半透明烟雾中使用柔化效果
烟雾位置出现棋盘格使用 SMOKE、VAPOUR 或 DUST 粒子,或使用 p.disc:真正实现半透明,并在顶部受光
循环衔接处出现接缝使用 cycle、loopNoise(phase)、滚动整格的 tileNoise、sin(phase * TAU * n)
单次效果突然消失在 t = duration 之前让效果缩小、通过抖色淡出或飘落消失
效果很棒,但角色毫无反应为角色设计一套动作:蓄力、释放姿势、接触时定格、目标做出反应、恢复动作
动作显得没有重量朝打击的反方向蓄力,延长定格时间(最长 0.2 s),让轮廓变化更明显,并加入震动
打击时机不同步将打击关键帧移到效果自身的常量处,而不是凭感觉估计一个时间点
角色握武器的姿势不对肘部保持弯曲,武器杆在胸前;挥动时刀刃滞后于手部;手臂伸展距离约为 15 px,且不会拉长,因此要让身体向前迈步
手臂交叉,或姿势显得平板角色以四分之三角度面向我们:张开手臂时,近侧的手向左(fx < 0),远侧的手向右,并设置 turn: 1;yaw 才会真正转动角色

方向性效果朝右,地面效果位于 y = 0,角色效果使用 o.actor(24 x 38 标准角色的蒙版和像素),且不使用 Math.random。通用主题可以使用;切勿复刻特定游戏的精灵图、角色或徽标。

4. 使用原生代码而非 JS

如果游戏无法运行 JS,而精灵图表又不够用(例如效果需要跟随移动目标,或在运行时按实例设置颜色),就移植该效果。纯效果是时间的函数;模拟效果则在 src/core/sim.js 中逐步更新粒子。保留双缓冲思路、用于抖色 alpha 的 4x4 Bayer 阈值,以及调色板色阶查找。并排渲染 JS 原版和移植版本,检查两者是否匹配。

评论

支持 Markdown