Simple Sprite Editor in J

Lobsters Hottest 工具

摘要

本文介绍了如何在 J 语言中构建一个简单的精灵编辑器,涵盖窗口管理、网格绘制、键盘快捷键、鼠标绘图及调色板自定义等功能,展示交互式图形程序的核心技术。

<p><a href="https://lobste.rs/s/eitko7/simple_sprite_editor_j">Comments</a></p>
查看原文
查看缓存全文

缓存时间: 2026/05/31 02:15

TL;DR: 本文介绍了如何在 J 语言中构建一个简单的精灵编辑器,涵盖窗口管理、网格绘制、键盘快捷键、鼠标绘图及调色板自定义等功能。 ## 准备工作:窗口与关闭处理器 每个 J GUI 程序的第一步是编写窗口关闭处理器。将窗口命名为 `gpw`(grid pad window 的缩写),当点击关闭按钮时,J 自动查找 `gpw_close` 函数。处理器不会自动关闭窗口,允许执行确认、保存等操作。这里只需用窗口驱动命令选中窗口并关闭: ```j wd 'parent select gpw parent close' wd 'timer 0' ``` 下方调用 `power` 连词控制运行次数,`wd 'parent'` 返回 0 或 1 表示窗口是否存在。若存在则关闭旧窗口。 ## 窗口布局与渲染 通过窗口驱动调用 `wd` 设置界面。使用 `bin` 命令水平或垂直分组控件,创建左侧调色板、右侧画布和底部状态栏(不可见)。布局完成后需定义渲染函数 `render`: ```j render =: 3 : 0 bm img;image [ wd 'psel ', gpw ) ``` 这里导入 `viewmat`,调用 `bm` 将图像矩阵绘制到子控件中,并传入父控件名称 `gpw` 以确保绘图目标正确。之后每 100 毫秒调用一次 `render`(通过定时器);在调色板中则只在更改后显式重绘。 ## 绘制网格 在 `render` 中添加网格绘制逻辑。由图像形状得到高、宽,查询画布控件的视口宽高,计算单元格大小,然后按行列生成线条位置: ```j grid =: 3 : 0 shape =. $image 'w h' =. >3{ wd 'qchildxywhx ', img cellsize =. (w,h) % |. shape ... ) ``` 水平线和垂直线的绘制均使用 `glqchild` 获取视口尺寸,`+0.5 <.` 取整得到精确坐标。将窗口高度作为列表最后一项时,用波浪号 `~` 交换参数顺序使其成为动词。网格显示受键盘快捷键控制(见下节)。 ## 键盘快捷键 每个控件独立拥有键盘事件处理器。命名规则:`gpw_pal_char` 和 `gpw_image_char` 均绑定同一动词,使键盘在任何控件获得焦点时都能响应。事件数据 `sysdata` 包含按键 ASCII 字符。定义快捷键: - **G**:切换网格显示(`grid =: -. grid`) - **R**:生成随机 32×32 24 位颜色网格(每个颜色 8 位红、绿、蓝) - **N**:将所有像素重置为 0(黑色,新图像) 由于每秒重绘 10 次,按住 R 时展示动画效果。 ## 鼠标交互:坐标映射与绘制 ### 获取鼠标坐标 定义 `mmove` 事件处理器(画布专用)。`sysdata` 字符串包含鼠标事件信息,解析后前两个数字为相对于控件左上角的 x、y 坐标。 ### 映射到数组索引 定义 `cellsize` 查询画布宽高并除以图像形状(注意数组 shape 为“高后宽”,需反转),得到每个单元格的像素大小。`whichbox` 函数从 `sysdata` 取前两个坐标,除以 `cellsize` 并向下取整,再反转坐标顺序(屏幕坐标 → 数组索引)。 ```j whichbox =: (|.@:<.@:(%~ |.))~ ``` 效果:鼠标上下移动时,第一个坐标(数组行索引)变化,第二个为列。 ### 点击绘制 鼠标左键弹起事件 `mblup` 中调用 `mousedraw` 动词。`mousedraw` 使用 `amend` 副词(花括号 `{`)修改图像:将当前画笔颜色(十六进制值)插入到指定坐标位置。 重点:单一坐标需装箱(`<`),否则 J 会将二维数组索引视为一维索引(按行处理)。例如 `4 2 8` 会修改第 4 行和第 28 行的整个行。正确做法: ```j mousedraw =: 3 : 0 image =: pen (< y) } image ) ``` ## 连续绘制与边界检查 为支持鼠标按下时连续绘制,在 `mousemove` 处理器中检测左按钮是否按下(`sysdata` 的第四个元素)。若按下,则传递给 `mousedraw`。 拖拽至画布外时,鼠标事件仍会报告超出范围的坐标,导致数组索引越界。加上边界检查: ```j inbounds =: 4 : ' *./ (0<:x) *. (x < y)' ``` 用 `inbounds image` 包裹 `mousedraw` 调用,确保坐标在每个维度上 ≥0 且 < 对应大小。 ## 调色板与颜色选择 调色板是一维颜色数组,默认使用 90 年代 ZZT 艺术的 16 色标准。垂直渲染时,使用 `,.` 将每个元素变成单独的行(二维数组)。定义调色板绘制事件处理器,但未接入定时器,仅在窗口重绘时生效。 画笔颜色通过变量 `pen`(调色板索引)存储。更新 `mousedraw` 使用 `pen` 而非固定值,实现不同颜色绘制。 ## 总结 本文完整演示了在 J 语言中构建一个具备基本功能的精灵编辑器。从窗口管理、渲染绘图、鼠标键盘事件处理到自定义调色板,涵盖了构建交互式图形程序的核心技术。代码可在 J 环境中直接运行,作为进一步开发的基础。 Source: [YouTube 视频链接](https://www.youtube.com/watch?v=CzK2SazvCxM)

相似文章

@0xQiYan: 还在手动画架构图?拖来拖去改半天? 收藏!今天必须安利这个skill——我最近装了个 `drawio-skill`,一句话就能生成专业图表,再也不用自己画了。 它的逻辑特别简单:你只用说人话(比如“画一个交易系统架构图”),它直接给你生成…

X AI KOLs Timeline

介绍 drawio-skill 工具,通过自然语言描述即可生成架构图、流程图、ER图等专业图表,支持多轮迭代和导出多种格式,大幅提升画图效率。

@VincentLogic: 发现个前端圈公认的动画神器,68K stars 真的不是吹的! anime.js —— 一个轻量级但功能极其强大的 JavaScript 动画引擎。 前端兄弟们又来享福了,这玩意儿简直是“动画师的瑞士军刀”: 全能型选手 不管是 CSS …

X AI KOLs Timeline

Anime.js 是一个轻量级但功能强大的 JavaScript 动画引擎,支持 CSS、SVG、DOM 属性及 JavaScript 对象动画,具有直观的 API、时间线系统、滚动观察器、拖拽和响应式动画等特性,在 GitHub 上拥有 68K stars,是前端开发者和交互设计师的常用工具。