create-pixifact 0.15.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -0
- package/dist/createPixifactProject.js +19 -0
- package/dist/index.js +14 -1
- package/dist/skills/pixifact/SKILL.md +106 -0
- package/dist/skills/pixifact/agents/openai.yaml +4 -0
- package/dist/skills/pixifact/references/runtime-observation.md +89 -0
- package/dist/skills/pixifact/references/scene-authoring-decisions.md +118 -0
- package/dist/skills/pixifact/references/scene-hierarchy-patterns.md +292 -0
- package/dist/skills/pixifact/references/scene-objects.md +585 -0
- package/dist/skills/pixifact/references/scene-script-patterns.md +312 -0
- package/package.json +2 -2
- package/templates/minimal/package.json +4 -2
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
# Pixifact Scene Hierarchy Patterns
|
|
2
|
+
|
|
3
|
+
本文件随 Pixifact skill 安装,用于下游项目设计或修复 `.scene` 层级结构。新建 Scene、大改 UI、插入复杂列表、拆子 Scene、或发现 agent 把节点堆错层级时先读本文件。
|
|
4
|
+
|
|
5
|
+
## 先画树,再写 XML
|
|
6
|
+
|
|
7
|
+
写 `.scene` 前先给出短树形草图:
|
|
8
|
+
|
|
9
|
+
```txt
|
|
10
|
+
Scene Hud
|
|
11
|
+
Image#background
|
|
12
|
+
Container#topLayer
|
|
13
|
+
HBoxContainer#resourceRow
|
|
14
|
+
Image#coinIcon
|
|
15
|
+
Text#coinText
|
|
16
|
+
BottomMenu#bottomMenu scene="./BottomMenu.scene"
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
原则:
|
|
20
|
+
|
|
21
|
+
- 先识别屏幕区块,再决定容器。
|
|
22
|
+
- 每个容器必须有职责。
|
|
23
|
+
- 叶子节点只显示,不承载 children。
|
|
24
|
+
- 子 Scene 是黑盒,父子交互只走 props、events、slots。
|
|
25
|
+
- 改完用 `pixifact scene inspect --scene <path>` 对比实际树和计划。
|
|
26
|
+
|
|
27
|
+
## Root 只放大区块
|
|
28
|
+
|
|
29
|
+
根 `<Scene>` 下优先放少量大区块:
|
|
30
|
+
|
|
31
|
+
```txt
|
|
32
|
+
Scene Main
|
|
33
|
+
Image#background
|
|
34
|
+
Container#worldLayer
|
|
35
|
+
Hud#hud scene="./Hud.scene"
|
|
36
|
+
Container#overlayLayer
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
常见 root child:
|
|
40
|
+
|
|
41
|
+
- `Image#background` 或 `TileImage#backgroundPattern`
|
|
42
|
+
- `Container#contentLayer`
|
|
43
|
+
- `Container#overlayLayer`
|
|
44
|
+
- 主要子 Scene instance,例如 `Hud`、`BottomMenu`、`InventoryPanel`
|
|
45
|
+
- 少量全局遮罩或调试节点
|
|
46
|
+
|
|
47
|
+
不要在大型 Scene 的 root 下直接堆几十个 `Text`、`Image`、`Rect`。先按区域分组。
|
|
48
|
+
|
|
49
|
+
## 容器必须有理由
|
|
50
|
+
|
|
51
|
+
合理容器理由:
|
|
52
|
+
|
|
53
|
+
- 分组移动、缩放、显隐或排序。
|
|
54
|
+
- 需要稳定的盒子宽高或 frame layout 时使用 `Group`。
|
|
55
|
+
- 隔离层级,例如 content / overlay / modal。
|
|
56
|
+
- 使用 layout container 排列子节点。
|
|
57
|
+
- `ScrollContainer` 裁剪和滚动内容。
|
|
58
|
+
- 子 Scene 的 slot outlet host。
|
|
59
|
+
- 复用组件边界。
|
|
60
|
+
|
|
61
|
+
没有职责的空壳 `Container` 或 `Group` 不要加。容器名字应该说明职责,例如 `resourceRow`、`contentLayer`、`questList`,不要只叫 `group1`。
|
|
62
|
+
|
|
63
|
+
## 叶子节点不是容器
|
|
64
|
+
|
|
65
|
+
这些节点通常是叶子:
|
|
66
|
+
|
|
67
|
+
```txt
|
|
68
|
+
Text
|
|
69
|
+
BitmapText
|
|
70
|
+
HTMLText
|
|
71
|
+
Rect
|
|
72
|
+
Image
|
|
73
|
+
NineImage
|
|
74
|
+
TileImage
|
|
75
|
+
Sprite
|
|
76
|
+
NineSliceSprite
|
|
77
|
+
TilingSprite
|
|
78
|
+
Graphics
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
错误:
|
|
82
|
+
|
|
83
|
+
```xml
|
|
84
|
+
<Rect id="buttonBack" width="180" height="64">
|
|
85
|
+
<Text id="label" text="Start" />
|
|
86
|
+
</Rect>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
正确:
|
|
90
|
+
|
|
91
|
+
```xml
|
|
92
|
+
<Group id="buttonGroup" width="180" height="64">
|
|
93
|
+
<Rect id="buttonBack" left="0" right="0" top="0" bottom="0" radius="12" fillColor="#2563eb" />
|
|
94
|
+
<Text id="label" text="Start" x="48" y="18" fontSize="24" fill="#ffffff" />
|
|
95
|
+
</Group>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
更可复用时,拆成 `PrimaryButton.scene`。
|
|
99
|
+
|
|
100
|
+
## 重复结构用 layout container
|
|
101
|
+
|
|
102
|
+
横向资源条:
|
|
103
|
+
|
|
104
|
+
```xml
|
|
105
|
+
<HBoxContainer id="resourceRow" right="24" top="24" width="260" height="56" gap="12" alignY="center" justify="end">
|
|
106
|
+
<Image id="coinIcon" texture="assets/icons/coin.png" width="40" height="40" />
|
|
107
|
+
<Text id="coinText" text="12,800" fontSize="24" fill="#ffffff" />
|
|
108
|
+
</HBoxContainer>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
纵向菜单:
|
|
112
|
+
|
|
113
|
+
```xml
|
|
114
|
+
<VBoxContainer id="mainMenu" horizontal="0" vertical="0" width="420" gap="18" alignX="center">
|
|
115
|
+
<Text id="title" text="PIXIFACT" fontSize="48" fill="#ffffff" />
|
|
116
|
+
<PrimaryButton id="startButton" scene="./PrimaryButton.scene" width="360" height="80" label="开始" />
|
|
117
|
+
<PrimaryButton id="settingsButton" scene="./PrimaryButton.scene" width="360" height="80" label="设置" />
|
|
118
|
+
</VBoxContainer>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
背包网格:
|
|
122
|
+
|
|
123
|
+
```xml
|
|
124
|
+
<GridContainer id="inventoryGrid" left="32" right="32" top="160" height="520" columns="4" gapX="14" gapY="14">
|
|
125
|
+
<ItemSlot id="slot1" scene="./ItemSlot.scene" width="128" height="128" />
|
|
126
|
+
<ItemSlot id="slot2" scene="./ItemSlot.scene" width="128" height="128" />
|
|
127
|
+
</GridContainer>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
不要手写大量 `x/y` 去模拟横排、竖排或网格,除非每个元素确实需要独立位置。
|
|
131
|
+
|
|
132
|
+
## ScrollContainer 标准结构
|
|
133
|
+
|
|
134
|
+
滚动容器通常只直接承载一个内容 layout container:
|
|
135
|
+
|
|
136
|
+
```xml
|
|
137
|
+
<ScrollContainer id="questScroll" left="32" right="32" top="180" bottom="120" direction="vertical">
|
|
138
|
+
<VBoxContainer id="questList" width="686" gap="16">
|
|
139
|
+
<QuestRow id="quest1" scene="./QuestRow.scene" width="686" height="96" title="采集草药" />
|
|
140
|
+
<QuestRow id="quest2" scene="./QuestRow.scene" width="686" height="96" title="修理木桥" />
|
|
141
|
+
</VBoxContainer>
|
|
142
|
+
</ScrollContainer>
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
背包可用内部 `GridContainer`:
|
|
146
|
+
|
|
147
|
+
```xml
|
|
148
|
+
<ScrollContainer id="slotScroll" left="32" right="32" top="160" bottom="120" direction="vertical">
|
|
149
|
+
<GridContainer id="slotGrid" columns="4" gapX="14" gapY="14">
|
|
150
|
+
<ItemSlot id="slot1" scene="./ItemSlot.scene" width="128" height="128" />
|
|
151
|
+
</GridContainer>
|
|
152
|
+
</ScrollContainer>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
不要把几十个 item 直接平铺在 `ScrollContainer` 下,除非它们确实不需要统一排列。
|
|
156
|
+
|
|
157
|
+
## 子 Scene 是黑盒
|
|
158
|
+
|
|
159
|
+
父 Scene 可以:
|
|
160
|
+
|
|
161
|
+
- 设置子 Scene public props。
|
|
162
|
+
- 绑定子 Scene public events。
|
|
163
|
+
- 向子 Scene public slots 填内容。
|
|
164
|
+
- 设置通用 transform、frame layout 和 display props。
|
|
165
|
+
|
|
166
|
+
父 Scene 不应该:
|
|
167
|
+
|
|
168
|
+
- 假设子 Scene 内部节点 id。
|
|
169
|
+
- 直接操作子 Scene 内部 `@part()`。
|
|
170
|
+
- 把 children 塞进没有声明 slot 的子 Scene。
|
|
171
|
+
|
|
172
|
+
正确:
|
|
173
|
+
|
|
174
|
+
```xml
|
|
175
|
+
<PrimaryButton id="startButton" scene="./PrimaryButton.scene" label="开始" @click="startGame">
|
|
176
|
+
<Image slot="icon" id="startIcon" texture="assets/icons/play.png" width="32" height="32" fit="contain" />
|
|
177
|
+
</PrimaryButton>
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
要求:
|
|
181
|
+
|
|
182
|
+
- `PrimaryButton.ts` 暴露 `@prop() label`。
|
|
183
|
+
- `PrimaryButton.ts` 暴露 `@event() click`。
|
|
184
|
+
- `PrimaryButton.ts` 暴露 `@slot({ name: 'icon' })`。
|
|
185
|
+
- `PrimaryButton.scene` 中有 `<slot name="icon" />`。
|
|
186
|
+
|
|
187
|
+
## z 顺序
|
|
188
|
+
|
|
189
|
+
默认用树顺序表达层级:
|
|
190
|
+
|
|
191
|
+
```xml
|
|
192
|
+
<Scene name="Main">
|
|
193
|
+
<Image id="background" ... />
|
|
194
|
+
<Container id="contentLayer">...</Container>
|
|
195
|
+
<Container id="overlayLayer">...</Container>
|
|
196
|
+
</Scene>
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
后写的 sibling 通常在视觉上更靠上。只有确实需要同层显式排序或动态排序时才用 `zIndex`。
|
|
200
|
+
|
|
201
|
+
不要靠大量 `zIndex` 修补混乱树。先重组层级。
|
|
202
|
+
|
|
203
|
+
## 常见反模式
|
|
204
|
+
|
|
205
|
+
反模式:root 下堆叶子。
|
|
206
|
+
|
|
207
|
+
```xml
|
|
208
|
+
<Scene name="Hud">
|
|
209
|
+
<Image id="coinIcon" texture="assets/icons/coin.png" />
|
|
210
|
+
<Text id="coinText" text="1200" />
|
|
211
|
+
<Image id="gemIcon" texture="assets/icons/gem.png" />
|
|
212
|
+
<Text id="gemText" text="35" />
|
|
213
|
+
</Scene>
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
改成:
|
|
217
|
+
|
|
218
|
+
```xml
|
|
219
|
+
<Scene name="Hud">
|
|
220
|
+
<HBoxContainer id="resourceRow" right="24" top="24" height="48" gap="10" alignY="center">
|
|
221
|
+
<Image id="coinIcon" texture="assets/icons/coin.png" width="36" height="36" />
|
|
222
|
+
<Text id="coinText" text="1200" fontSize="24" fill="#ffffff" />
|
|
223
|
+
<Image id="gemIcon" texture="assets/icons/gem.png" width="36" height="36" />
|
|
224
|
+
<Text id="gemText" text="35" fontSize="24" fill="#ffffff" />
|
|
225
|
+
</HBoxContainer>
|
|
226
|
+
</Scene>
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
反模式:用普通 `Container` 手写列表位置。
|
|
230
|
+
|
|
231
|
+
```xml
|
|
232
|
+
<Container id="questList">
|
|
233
|
+
<QuestRow id="quest1" scene="./QuestRow.scene" y="0" />
|
|
234
|
+
<QuestRow id="quest2" scene="./QuestRow.scene" y="112" />
|
|
235
|
+
<QuestRow id="quest3" scene="./QuestRow.scene" y="224" />
|
|
236
|
+
</Container>
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
改成:
|
|
240
|
+
|
|
241
|
+
```xml
|
|
242
|
+
<VBoxContainer id="questList" gap="16">
|
|
243
|
+
<QuestRow id="quest1" scene="./QuestRow.scene" width="686" height="96" />
|
|
244
|
+
<QuestRow id="quest2" scene="./QuestRow.scene" width="686" height="96" />
|
|
245
|
+
<QuestRow id="quest3" scene="./QuestRow.scene" width="686" height="96" />
|
|
246
|
+
</VBoxContainer>
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
反模式:把 modal、遮罩和背景混在 content 中。
|
|
250
|
+
|
|
251
|
+
```xml
|
|
252
|
+
<Scene name="Main">
|
|
253
|
+
<Image id="background" ... />
|
|
254
|
+
<InventoryPanel id="inventory" scene="./InventoryPanel.scene" ... />
|
|
255
|
+
<PlayerCard id="player" scene="./PlayerCard.scene" ... />
|
|
256
|
+
<Rect id="modalMask" ... />
|
|
257
|
+
</Scene>
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
改成:
|
|
261
|
+
|
|
262
|
+
```xml
|
|
263
|
+
<Scene name="Main">
|
|
264
|
+
<Image id="background" ... />
|
|
265
|
+
<Container id="contentLayer">
|
|
266
|
+
<PlayerCard id="player" scene="./PlayerCard.scene" ... />
|
|
267
|
+
<InventoryPanel id="inventory" scene="./InventoryPanel.scene" ... />
|
|
268
|
+
</Container>
|
|
269
|
+
<Container id="overlayLayer">
|
|
270
|
+
<Rect id="modalMask" ... />
|
|
271
|
+
</Container>
|
|
272
|
+
</Scene>
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## Inspect 复核
|
|
276
|
+
|
|
277
|
+
层级大改后先 inspect:
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
pixifact scene inspect --scene src/scenes/Hud.scene
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
检查:
|
|
284
|
+
|
|
285
|
+
- root 下是否只有少量大区块。
|
|
286
|
+
- 背景、内容、overlay 顺序是否正确。
|
|
287
|
+
- layout container 是否承载重复结构。
|
|
288
|
+
- 叶子节点下是否没有 children。
|
|
289
|
+
- 子 Scene children 是否都通过已声明 slot。
|
|
290
|
+
- 需要脚本访问的节点是否有稳定 `id`。
|
|
291
|
+
|
|
292
|
+
inspect 树和预先草图不一致时,先修层级,再运行 validate 和 compile。
|