codepet 1.0.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 +69 -0
- package/adapters/skill/SKILL.md +697 -0
- package/bin/codepet.js +384 -0
- package/bin/pet-render.sh +43 -0
- package/core/index.js +206 -0
- package/package.json +45 -0
- package/scripts/animate.py +207 -0
- package/scripts/auto_exp.js +91 -0
- package/scripts/crop_all.py +46 -0
- package/scripts/crop_expressions.py +73 -0
- package/scripts/gen_expressions.py +95 -0
- package/scripts/gen_variants.py +107 -0
- package/scripts/img2ascii.py +41 -0
- package/scripts/img2emoji.py +61 -0
- package/scripts/img2terminal.py +88 -0
- package/scripts/pet_bubble.js +136 -0
- package/scripts/pet_card.py +472 -0
- package/scripts/polaroid.py +103 -0
- package/scripts/popup_pet.sh +29 -0
- package/scripts/render_sprite.py +558 -0
- package/scripts/render_to_image.py +44 -0
- package/scripts/show_all.py +45 -0
- package/scripts/show_all_expressions.py +41 -0
- package/scripts/sprites.sh +184 -0
- package/sprites/bababoyi.png +0 -0
- package/sprites/bagayalu.png +0 -0
- package/sprites/bibilabu.png +0 -0
- package/sprites/gugugaga.png +0 -0
- package/sprites/waibibabu.png +0 -0
- package/sprites/wodedaodun.png +0 -0
|
@@ -0,0 +1,558 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""CodePet 像素精灵渲染器 v2 — 基于真实形象"""
|
|
3
|
+
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
# ── 调色板(从真实图片取色)──
|
|
7
|
+
C = {
|
|
8
|
+
'.': None,
|
|
9
|
+
# 香蕉/植物
|
|
10
|
+
'Y': (215, 195, 55), # 香蕉黄
|
|
11
|
+
'y': (185, 165, 45), # 香蕉暗黄
|
|
12
|
+
'G': (95, 120, 45), # 蒂绿
|
|
13
|
+
# 灰猫(比比拉布/巴巴博一/咕咕嘎嘎)
|
|
14
|
+
'S': (185, 180, 175), # 银灰猫毛
|
|
15
|
+
's': (155, 150, 145), # 深银灰
|
|
16
|
+
'A': (205, 200, 195), # 亮灰
|
|
17
|
+
'a': (130, 125, 120), # 暗灰
|
|
18
|
+
# 水豚(八嘎呀路/我的刀盾)
|
|
19
|
+
'B': (195, 145, 75), # 金棕
|
|
20
|
+
'b': (165, 120, 60), # 深棕
|
|
21
|
+
'L': (225, 200, 155), # 浅棕/肚
|
|
22
|
+
'l': (240, 220, 180), # 亮浅棕
|
|
23
|
+
'M': (210, 170, 110), # 中棕
|
|
24
|
+
# 巴巴博一(猫球)
|
|
25
|
+
'C': (215, 200, 180), # 奶油色身体
|
|
26
|
+
'c': (195, 175, 155), # 深奶油
|
|
27
|
+
# 歪比巴卜(卡通人)
|
|
28
|
+
'F': (225, 185, 145), # 肤色
|
|
29
|
+
'f': (200, 160, 120), # 深肤色
|
|
30
|
+
'H': (165, 105, 55), # 胡子棕
|
|
31
|
+
'h': (135, 80, 40), # 深胡子
|
|
32
|
+
'K': (165, 170, 175), # 帽灰
|
|
33
|
+
'k': (140, 145, 150), # 帽深灰
|
|
34
|
+
'T': (242, 242, 238), # 白衣
|
|
35
|
+
't': (220, 220, 216), # 衣影
|
|
36
|
+
# 咕咕嘎嘎(黑发)
|
|
37
|
+
'D': (65, 65, 70), # 黑发
|
|
38
|
+
'd': (90, 90, 95), # 深灰发
|
|
39
|
+
# 通用
|
|
40
|
+
'W': (240, 235, 225), # 白
|
|
41
|
+
'w': (250, 248, 242), # 亮白
|
|
42
|
+
'X': (30, 30, 30), # 黑(眼)
|
|
43
|
+
'x': (60, 55, 50), # 深灰(眼)
|
|
44
|
+
'P': (205, 155, 145), # 粉鼻
|
|
45
|
+
'p': (185, 130, 120), # 深粉
|
|
46
|
+
'R': (195, 105, 100), # 红嘴
|
|
47
|
+
'J': (80, 95, 130), # 牛仔蓝
|
|
48
|
+
'j': (60, 75, 105), # 深蓝
|
|
49
|
+
'n': (170, 130, 90), # 鼻棕
|
|
50
|
+
'E': (50, 80, 50), # 深绿
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
SPRITES = {}
|
|
54
|
+
|
|
55
|
+
# ═══════════════════════════════════════
|
|
56
|
+
# 1. 比比拉布(香蕉猫)
|
|
57
|
+
# 灰猫脸从香蕉里探出,绿蒂,灰爪
|
|
58
|
+
# 20w × 26h
|
|
59
|
+
# ═══════════════════════════════════════
|
|
60
|
+
SPRITES['bibilabu'] = {
|
|
61
|
+
'normal': [
|
|
62
|
+
".........EE.........",
|
|
63
|
+
"........EGGE........",
|
|
64
|
+
".......EGGGE........",
|
|
65
|
+
"........YYY.........",
|
|
66
|
+
".......YYYYY........",
|
|
67
|
+
"......YYYYYY........",
|
|
68
|
+
".....YYsSSsYY.......",
|
|
69
|
+
".....YsSSSSsY.......",
|
|
70
|
+
"....YYSXSSXSyY......",
|
|
71
|
+
"....YYSSPSSsyY......",
|
|
72
|
+
"....YYsSSSSYYY......",
|
|
73
|
+
".....YYYYYYYY.......",
|
|
74
|
+
".....YYYYYYYY.......",
|
|
75
|
+
".....yYYYYYYy.......",
|
|
76
|
+
".....yyyYYYYy.......",
|
|
77
|
+
".....yyyYYYy........",
|
|
78
|
+
"......yyYYy.........",
|
|
79
|
+
"......yyyYy.........",
|
|
80
|
+
".......yyyy.........",
|
|
81
|
+
"......yyy...........",
|
|
82
|
+
".......SS.SS........",
|
|
83
|
+
"......SS...SS.......",
|
|
84
|
+
],
|
|
85
|
+
'happy': [
|
|
86
|
+
".........EE.........",
|
|
87
|
+
"........EGGE........",
|
|
88
|
+
".......EGGGE........",
|
|
89
|
+
"........YYY.........",
|
|
90
|
+
".......YYYYY........",
|
|
91
|
+
"......YYYYYY........",
|
|
92
|
+
".....YYsSSsYY.......",
|
|
93
|
+
".....YsSSSSsY.......",
|
|
94
|
+
"....YYSaSSaSyY......",
|
|
95
|
+
"....YYSSPSSsyY......",
|
|
96
|
+
"....YYsSSSSYYY......",
|
|
97
|
+
".....YYYYYYYY.......",
|
|
98
|
+
".....YYYYYYYY.......",
|
|
99
|
+
".....yYYYYYYy.......",
|
|
100
|
+
".....yyyYYYYy.......",
|
|
101
|
+
".....yyyYYYy........",
|
|
102
|
+
"......yyYYy.........",
|
|
103
|
+
"......yyyYy.........",
|
|
104
|
+
".......yyyy.........",
|
|
105
|
+
"......yyy...........",
|
|
106
|
+
".......SS.SS........",
|
|
107
|
+
"......SS...SS.......",
|
|
108
|
+
],
|
|
109
|
+
'sleep': [
|
|
110
|
+
".........EE.........",
|
|
111
|
+
"........EGGE........",
|
|
112
|
+
".......EGGGE........",
|
|
113
|
+
"........YYY.........",
|
|
114
|
+
".......YYYYY........",
|
|
115
|
+
"......YYYYYY........",
|
|
116
|
+
".....YYsSSsYY.......",
|
|
117
|
+
".....YsSSSSsY.......",
|
|
118
|
+
"....YYSsSssSyY......",
|
|
119
|
+
"....YYSSPSSsyY......",
|
|
120
|
+
"....YYsSSSSYYY......",
|
|
121
|
+
".....YYYYYYYY.......",
|
|
122
|
+
".....YYYYYYYY.......",
|
|
123
|
+
".....yYYYYYYy.......",
|
|
124
|
+
".....yyyYYYYy.......",
|
|
125
|
+
".....yyyYYYy........",
|
|
126
|
+
"......yyYYy.........",
|
|
127
|
+
"......yyyYy.........",
|
|
128
|
+
".......yyyy.........",
|
|
129
|
+
"......yyy...........",
|
|
130
|
+
".......SS.SS........",
|
|
131
|
+
"......SS...SS.......",
|
|
132
|
+
],
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
# ═══════════════════════════════════════
|
|
136
|
+
# 2. 八嘎呀路(坐姿水豚)
|
|
137
|
+
# 金棕色,3/4侧面坐,闭眼忧郁,浅肚
|
|
138
|
+
# 20w × 22h
|
|
139
|
+
# ═══════════════════════════════════════
|
|
140
|
+
SPRITES['bagayalu'] = {
|
|
141
|
+
'normal': [
|
|
142
|
+
"..........bb........",
|
|
143
|
+
".........bBBb.......",
|
|
144
|
+
"........bBBBBb......",
|
|
145
|
+
".......bBBBBBBb.....",
|
|
146
|
+
"......bBBBBBBBBb....",
|
|
147
|
+
".....bBbBBbBBBBBb...",
|
|
148
|
+
".....bBBnnBBBBBBb...",
|
|
149
|
+
".....bBBBBBBBBBBb...",
|
|
150
|
+
"....bBBBBBBBBBBBb...",
|
|
151
|
+
"...bBBBBBBBBBBBBb...",
|
|
152
|
+
"..bBBBBBBBBBBBBBb...",
|
|
153
|
+
"..bBBBLLLLLBBBBb....",
|
|
154
|
+
"..bBBLLLLLLLBBBb....",
|
|
155
|
+
"..bBBLLLLLLLBBb.....",
|
|
156
|
+
"...bBBLLLLLBBb......",
|
|
157
|
+
"...bBBBBBBBBBb......",
|
|
158
|
+
"....bbBBBBBbb.......",
|
|
159
|
+
"....bBb..bBBb.......",
|
|
160
|
+
"....bb....bbb.......",
|
|
161
|
+
],
|
|
162
|
+
'happy': [
|
|
163
|
+
"..........bb........",
|
|
164
|
+
".........bBBb.......",
|
|
165
|
+
"........bBBBBb......",
|
|
166
|
+
".......bBBBBBBb.....",
|
|
167
|
+
"......bBBBBBBBBb....",
|
|
168
|
+
".....bBMBBMBBBBBb...",
|
|
169
|
+
".....bBBnnBBBBBBb...",
|
|
170
|
+
".....bBBLLBBBBBBb...",
|
|
171
|
+
"....bBBBBBBBBBBBb...",
|
|
172
|
+
"...bBBBBBBBBBBBBb...",
|
|
173
|
+
"..bBBBBBBBBBBBBBb...",
|
|
174
|
+
"..bBBBLLLLLBBBBb....",
|
|
175
|
+
"..bBBLLLLLLLBBBb....",
|
|
176
|
+
"..bBBLLLLLLLBBb.....",
|
|
177
|
+
"...bBBLLLLLBBb......",
|
|
178
|
+
"...bBBBBBBBBBb......",
|
|
179
|
+
"....bbBBBBBbb.......",
|
|
180
|
+
"....bBb..bBBb.......",
|
|
181
|
+
"....bb....bbb.......",
|
|
182
|
+
],
|
|
183
|
+
'sleep': [
|
|
184
|
+
"..........bb........",
|
|
185
|
+
".........bBBb.......",
|
|
186
|
+
"........bBBBBb......",
|
|
187
|
+
".......bBBBBBBb.....",
|
|
188
|
+
"......bBBBBBBBBb....",
|
|
189
|
+
".....bBbBBbBBBBBb...",
|
|
190
|
+
".....bBBnnBBBBBBb...",
|
|
191
|
+
".....bBBBBBBBBBBb...",
|
|
192
|
+
"....bBBBBBBBBBBBb...",
|
|
193
|
+
"...bBBBBBBBBBBBBb...",
|
|
194
|
+
"..bBBBBBBBBBBBBBb...",
|
|
195
|
+
"..bBBBLLLLLBBBBb....",
|
|
196
|
+
"..bBBLLLLLLLBBBb....",
|
|
197
|
+
"..bBBLLLLLLLBBb.....",
|
|
198
|
+
"...bBBLLLLLBBb......",
|
|
199
|
+
"...bBBBBBBBBBb......",
|
|
200
|
+
"....bbBBBBBbb.......",
|
|
201
|
+
"....bBb..bBBb.......",
|
|
202
|
+
"....bb....bbb.......",
|
|
203
|
+
],
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
# ═══════════════════════════════════════
|
|
207
|
+
# 3. 我的刀盾(趴姿水豚)
|
|
208
|
+
# 完全趴平像面包,侧面,微笑
|
|
209
|
+
# 22w × 12h
|
|
210
|
+
# ═══════════════════════════════════════
|
|
211
|
+
SPRITES['wodedaodun'] = {
|
|
212
|
+
'normal': [
|
|
213
|
+
".......bbbbb........",
|
|
214
|
+
"....bbbBBBBBbbb.....",
|
|
215
|
+
"...bBBBBBBBBBBBbb...",
|
|
216
|
+
"..bBbBbBBBBBBBBBBb..",
|
|
217
|
+
"..bBBnBBBBBBBBBBBBb.",
|
|
218
|
+
"..bBBBLLBBBBBBBBBBb.",
|
|
219
|
+
"...bBBBBBBBBBBBBBb..",
|
|
220
|
+
"...bbLBBBBBBBBLbb...",
|
|
221
|
+
"....bb.........bb...",
|
|
222
|
+
],
|
|
223
|
+
'happy': [
|
|
224
|
+
".......bbbbb........",
|
|
225
|
+
"....bbbBBBBBbbb.....",
|
|
226
|
+
"...bBBBBBBBBBBBbb...",
|
|
227
|
+
"..bBMBMBBBBBBBBBBb..",
|
|
228
|
+
"..bBBnBBBBBBBBBBBBb.",
|
|
229
|
+
"..bBBBLLBBBBBBBBBBb.",
|
|
230
|
+
"...bBBBBBBBBBBBBBb..",
|
|
231
|
+
"...bbLBBBBBBBBLbb...",
|
|
232
|
+
"....bb.........bb...",
|
|
233
|
+
],
|
|
234
|
+
'sleep': [
|
|
235
|
+
".......bbbbb........",
|
|
236
|
+
"....bbbBBBBBbbb.....",
|
|
237
|
+
"...bBBBBBBBBBBBbb...",
|
|
238
|
+
"..bBbBbBBBBBBBBBBb..",
|
|
239
|
+
"..bBBnBBBBBBBBBBBBb.",
|
|
240
|
+
"..bBBBLLBBBBBBBBBBb.",
|
|
241
|
+
"...bBBBBBBBBBBBBBb..",
|
|
242
|
+
"...bbLBBBBBBBBLbb...",
|
|
243
|
+
"....bb.........bb...",
|
|
244
|
+
],
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
# ═══════════════════════════════════════
|
|
248
|
+
# 4. 巴巴博一(圆猫球)
|
|
249
|
+
# 极度圆,巨大黑眼,粉鼻,灰+奶油色
|
|
250
|
+
# 20w × 20h
|
|
251
|
+
# ═══════════════════════════════════════
|
|
252
|
+
SPRITES['bababoyi'] = {
|
|
253
|
+
'normal': [
|
|
254
|
+
".......ssss.........",
|
|
255
|
+
"......sSSSSs........",
|
|
256
|
+
".....sSSSSSSSs......",
|
|
257
|
+
"....sSSSSSSSSSs.....",
|
|
258
|
+
"...sSSSSSSSSSSSs....",
|
|
259
|
+
"..sSxXxSSSSxXxSSs...",
|
|
260
|
+
"..sSXXxSSSSxXXSSs...",
|
|
261
|
+
"..sSSSSSSSSSSSSSSs..",
|
|
262
|
+
"..sSSSSSPPSSSSSSSs..",
|
|
263
|
+
"..sCCCCCCCCCCCCCs...",
|
|
264
|
+
"..CCCCCCCCCCCCCCCC..",
|
|
265
|
+
".CCCCCCCCCCCCCCCCCC.",
|
|
266
|
+
".CCCCCCCCCCCCCCCCCC.",
|
|
267
|
+
".CCCCCCCCCCCCCCCCCC.",
|
|
268
|
+
"..CCCCCCCCCCCCCCCC..",
|
|
269
|
+
"..cCCCCCCCCCCCCCc...",
|
|
270
|
+
"...ccCCCCCCCCcc.....",
|
|
271
|
+
"....cccccccccc......",
|
|
272
|
+
".....ss....ss.......",
|
|
273
|
+
],
|
|
274
|
+
'happy': [
|
|
275
|
+
".......ssss.........",
|
|
276
|
+
"......sSSSSs........",
|
|
277
|
+
".....sSSSSSSSs......",
|
|
278
|
+
"....sSSSSSSSSSs.....",
|
|
279
|
+
"...sSSSSSSSSSSSs....",
|
|
280
|
+
"..sSaxaSSSSaxaSSs...",
|
|
281
|
+
"..sSaaaSSSsaaaSs....",
|
|
282
|
+
"..sSSSSSSSSSSSSSSs..",
|
|
283
|
+
"..sSSSSSPPSSSSSSSs..",
|
|
284
|
+
"..sCCCCCCCCCCCCCs...",
|
|
285
|
+
"..CCCCCCCCCCCCCCCC..",
|
|
286
|
+
".CCCCCCCCCCCCCCCCCC.",
|
|
287
|
+
".CCCCCCCCCCCCCCCCCC.",
|
|
288
|
+
".CCCCCCCCCCCCCCCCCC.",
|
|
289
|
+
"..CCCCCCCCCCCCCCCC..",
|
|
290
|
+
"..cCCCCCCCCCCCCCc...",
|
|
291
|
+
"...ccCCCCCCCCcc.....",
|
|
292
|
+
"....cccccccccc......",
|
|
293
|
+
".....ss....ss.......",
|
|
294
|
+
],
|
|
295
|
+
'sleep': [
|
|
296
|
+
".......ssss.........",
|
|
297
|
+
"......sSSSSs........",
|
|
298
|
+
".....sSSSSSSSs......",
|
|
299
|
+
"....sSSSSSSSSSs.....",
|
|
300
|
+
"...sSSSSSSSSSSSs....",
|
|
301
|
+
"..sSSsSSSSSsSSSSSs..",
|
|
302
|
+
"..sSssSSSSssSSSSSs..",
|
|
303
|
+
"..sSSSSSSSSSSSSSSs..",
|
|
304
|
+
"..sSSSSSPPSSSSSSSs..",
|
|
305
|
+
"..sCCCCCCCCCCCCCs...",
|
|
306
|
+
"..CCCCCCCCCCCCCCCC..",
|
|
307
|
+
".CCCCCCCCCCCCCCCCCC.",
|
|
308
|
+
".CCCCCCCCCCCCCCCCCC.",
|
|
309
|
+
".CCCCCCCCCCCCCCCCCC.",
|
|
310
|
+
"..CCCCCCCCCCCCCCCC..",
|
|
311
|
+
"..cCCCCCCCCCCCCCc...",
|
|
312
|
+
"...ccCCCCCCCCcc.....",
|
|
313
|
+
"....cccccccccc......",
|
|
314
|
+
".....ss....ss.......",
|
|
315
|
+
],
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
# ═══════════════════════════════════════
|
|
319
|
+
# 5. 歪比巴卜(大胡子壮汉)
|
|
320
|
+
# 卡通风,灰帽,肤色脸,棕胡子,白Polo衫
|
|
321
|
+
# 18w × 26h
|
|
322
|
+
# ═══════════════════════════════════════
|
|
323
|
+
SPRITES['waibibabu'] = {
|
|
324
|
+
'normal': [
|
|
325
|
+
".......kkkk.........",
|
|
326
|
+
"......kKKKKk........",
|
|
327
|
+
".....kKKKKKKk.......",
|
|
328
|
+
".....KKKKKKKKK......",
|
|
329
|
+
"....FFFFFFFFFFf.....",
|
|
330
|
+
"....FxFFFFxFFFF.....",
|
|
331
|
+
"....FFFFFFFFFFFf....",
|
|
332
|
+
"....FFFnnFFFFFf.....",
|
|
333
|
+
"....fHHHHHHHHf......",
|
|
334
|
+
".....fHHHHHHf.......",
|
|
335
|
+
"......ffffff........",
|
|
336
|
+
".....TTTTTTTTT......",
|
|
337
|
+
"....TTTTtTTTTTT.....",
|
|
338
|
+
"...FTTTTtTTTTTF.....",
|
|
339
|
+
"...FFTTTtTTTTFF.....",
|
|
340
|
+
"...FFFTTtTTFFF......",
|
|
341
|
+
"....FFTTtTTFF.......",
|
|
342
|
+
".....TTTTTTT........",
|
|
343
|
+
".....TTTTTTT........",
|
|
344
|
+
"......TTTTT.........",
|
|
345
|
+
"......JJ.JJ.........",
|
|
346
|
+
".....JJJ.JJJ........",
|
|
347
|
+
".....JJ...JJ........",
|
|
348
|
+
"....jjj...jjj.......",
|
|
349
|
+
],
|
|
350
|
+
'happy': [
|
|
351
|
+
".......kkkk.........",
|
|
352
|
+
"......kKKKKk........",
|
|
353
|
+
".....kKKKKKKk.......",
|
|
354
|
+
".....KKKKKKKKK......",
|
|
355
|
+
"....FFFFFFFFFFf.....",
|
|
356
|
+
"....FaFFFFaFFFF.....",
|
|
357
|
+
"....FFFFFFFFFFFf....",
|
|
358
|
+
"....FFFnnFFFFFf.....",
|
|
359
|
+
"....fHHHLHHHHf......",
|
|
360
|
+
".....fHHHHHHf.......",
|
|
361
|
+
"......ffffff........",
|
|
362
|
+
".....TTTTTTTTT......",
|
|
363
|
+
"....TTTTtTTTTTT.....",
|
|
364
|
+
"...FTTTTtTTTTTF.....",
|
|
365
|
+
"...FFTTTtTTTTFF.....",
|
|
366
|
+
"...FFFTTtTTFFF......",
|
|
367
|
+
"....FFTTtTTFF.......",
|
|
368
|
+
".....TTTTTTT........",
|
|
369
|
+
".....TTTTTTT........",
|
|
370
|
+
"......TTTTT.........",
|
|
371
|
+
"......JJ.JJ.........",
|
|
372
|
+
".....JJJ.JJJ........",
|
|
373
|
+
".....JJ...JJ........",
|
|
374
|
+
"....jjj...jjj.......",
|
|
375
|
+
],
|
|
376
|
+
'sleep': [
|
|
377
|
+
".......kkkk.........",
|
|
378
|
+
"......kKKKKk........",
|
|
379
|
+
".....kKKKKKKk.......",
|
|
380
|
+
".....KKKKKKKKK......",
|
|
381
|
+
"....FFFFFFFFFFf.....",
|
|
382
|
+
"....FfFFFFfFFFF.....",
|
|
383
|
+
"....FFFFFFFFFFFf....",
|
|
384
|
+
"....FFFnnFFFFFf.....",
|
|
385
|
+
"....fHHHHHHHHf......",
|
|
386
|
+
".....fHHHHHHf.......",
|
|
387
|
+
"......ffffff........",
|
|
388
|
+
".....TTTTTTTTT......",
|
|
389
|
+
"....TTTTtTTTTTT.....",
|
|
390
|
+
"...FTTTTtTTTTTF.....",
|
|
391
|
+
"...FFTTTtTTTTFF.....",
|
|
392
|
+
"...FFFTTtTTFFF......",
|
|
393
|
+
"....FFTTtTTFF.......",
|
|
394
|
+
".....TTTTTTT........",
|
|
395
|
+
".....TTTTTTT........",
|
|
396
|
+
"......TTTTT.........",
|
|
397
|
+
"......JJ.JJ.........",
|
|
398
|
+
".....JJJ.JJJ........",
|
|
399
|
+
".....JJ...JJ........",
|
|
400
|
+
"....jjj...jjj.......",
|
|
401
|
+
],
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
# ═══════════════════════════════════════
|
|
405
|
+
# 6. 咕咕嘎嘎(黑刘海圆脸猫)
|
|
406
|
+
# 厚黑灰色刘海,白/灰圆脸,小嘴
|
|
407
|
+
# 20w × 18h
|
|
408
|
+
# ═══════════════════════════════════════
|
|
409
|
+
SPRITES['gugugaga'] = {
|
|
410
|
+
'normal': [
|
|
411
|
+
"......ddddddd.......",
|
|
412
|
+
".....dDDDDDDDd......",
|
|
413
|
+
"....dDDDDDDDDDd.....",
|
|
414
|
+
"...dDDDDDDDDDDDd....",
|
|
415
|
+
"..dDDDDDDDDDDDDDd...",
|
|
416
|
+
"..dDDDDDDDDDDDDDd...",
|
|
417
|
+
"..dDxDDDDDDxDDDDd...",
|
|
418
|
+
"..SSSSSSSSSSSSSSss..",
|
|
419
|
+
"..SSSSSSSSSSSSSSSs..",
|
|
420
|
+
"..SSSSSSSSSSSSSSss..",
|
|
421
|
+
"..sSSSSSRSSSSSSSs...",
|
|
422
|
+
"...sSSSSSSSSSSSs....",
|
|
423
|
+
"...sSSSSSSSSSSs.....",
|
|
424
|
+
"....sSWWWWWWSs......",
|
|
425
|
+
"....sWWWWWWWWs......",
|
|
426
|
+
".....sWWWWWWs.......",
|
|
427
|
+
"......ssssss........",
|
|
428
|
+
".......ss.ss........",
|
|
429
|
+
],
|
|
430
|
+
'happy': [
|
|
431
|
+
"......ddddddd.......",
|
|
432
|
+
".....dDDDDDDDd......",
|
|
433
|
+
"....dDDDDDDDDDd.....",
|
|
434
|
+
"...dDDDDDDDDDDDd....",
|
|
435
|
+
"..dDDDDDDDDDDDDDd...",
|
|
436
|
+
"..dDDDDDDDDDDDDDd...",
|
|
437
|
+
"..dDaDDDDDDaDDDDd...",
|
|
438
|
+
"..SSSSSSSSSSSSSSss..",
|
|
439
|
+
"..SSSSSSSSSSSSSSSs..",
|
|
440
|
+
"..SSSSSSSSSSSSSSss..",
|
|
441
|
+
"..sSSSSSLSSSSSSSs...",
|
|
442
|
+
"...sSSSSSSSSSSSs....",
|
|
443
|
+
"...sSSSSSSSSSSs.....",
|
|
444
|
+
"....sSWWWWWWSs......",
|
|
445
|
+
"....sWWWWWWWWs......",
|
|
446
|
+
".....sWWWWWWs.......",
|
|
447
|
+
"......ssssss........",
|
|
448
|
+
".......ss.ss........",
|
|
449
|
+
],
|
|
450
|
+
'sleep': [
|
|
451
|
+
"......ddddddd.......",
|
|
452
|
+
".....dDDDDDDDd......",
|
|
453
|
+
"....dDDDDDDDDDd.....",
|
|
454
|
+
"...dDDDDDDDDDDDd....",
|
|
455
|
+
"..dDDDDDDDDDDDDDd...",
|
|
456
|
+
"..dDDDDDDDDDDDDDd...",
|
|
457
|
+
"..dDsDDDDDDsDDDDd...",
|
|
458
|
+
"..SSSSSSSSSSSSSSss..",
|
|
459
|
+
"..SSSSSSSSSSSSSSSs..",
|
|
460
|
+
"..SSSSSSSSSSSSSSss..",
|
|
461
|
+
"..sSSSSSSSSSSSSSs...",
|
|
462
|
+
"...sSSSSSSSSSSSs....",
|
|
463
|
+
"...sSSSSSSSSSSs.....",
|
|
464
|
+
"....sSWWWWWWSs......",
|
|
465
|
+
"....sWWWWWWWWs......",
|
|
466
|
+
".....sWWWWWWs.......",
|
|
467
|
+
"......ssssss........",
|
|
468
|
+
".......ss.ss........",
|
|
469
|
+
],
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
# ── 渲染引擎 ──
|
|
473
|
+
|
|
474
|
+
def fg(r, g, b):
|
|
475
|
+
return f"\033[38;2;{r};{g};{b}m"
|
|
476
|
+
|
|
477
|
+
def bg(r, g, b):
|
|
478
|
+
return f"\033[48;2;{r};{g};{b}m"
|
|
479
|
+
|
|
480
|
+
RESET = "\033[0m"
|
|
481
|
+
BOLD = "\033[1m"
|
|
482
|
+
|
|
483
|
+
def render_pixel_pair(top_char, bot_char):
|
|
484
|
+
top_color = C.get(top_char)
|
|
485
|
+
bot_color = C.get(bot_char)
|
|
486
|
+
if top_color and bot_color:
|
|
487
|
+
if top_color == bot_color:
|
|
488
|
+
return f"{fg(*top_color)}█{RESET}"
|
|
489
|
+
else:
|
|
490
|
+
return f"{fg(*top_color)}{bg(*bot_color)}▀{RESET}"
|
|
491
|
+
elif top_color:
|
|
492
|
+
return f"{fg(*top_color)}▀{RESET}"
|
|
493
|
+
elif bot_color:
|
|
494
|
+
return f"{fg(*bot_color)}▄{RESET}"
|
|
495
|
+
else:
|
|
496
|
+
return " "
|
|
497
|
+
|
|
498
|
+
def render_sprite(name, state='normal', indent=4):
|
|
499
|
+
data = SPRITES.get(name, {}).get(state)
|
|
500
|
+
if not data:
|
|
501
|
+
print(f"未找到: {name}/{state}")
|
|
502
|
+
return
|
|
503
|
+
rows = list(data)
|
|
504
|
+
if len(rows) % 2 == 1:
|
|
505
|
+
max_len = max(len(r) for r in rows)
|
|
506
|
+
rows.append('.' * max_len)
|
|
507
|
+
max_len = max(len(r) for r in rows)
|
|
508
|
+
rows = [r.ljust(max_len, '.') for r in rows]
|
|
509
|
+
for i in range(0, len(rows), 2):
|
|
510
|
+
top_row = rows[i]
|
|
511
|
+
bot_row = rows[i + 1]
|
|
512
|
+
line = ""
|
|
513
|
+
for j in range(max_len):
|
|
514
|
+
tc = top_row[j] if j < len(top_row) else '.'
|
|
515
|
+
bc = bot_row[j] if j < len(bot_row) else '.'
|
|
516
|
+
line += render_pixel_pair(tc, bc)
|
|
517
|
+
print(f"{' ' * indent}{line}")
|
|
518
|
+
|
|
519
|
+
def render_card(name, state='normal'):
|
|
520
|
+
"""渲染单个角色带标题"""
|
|
521
|
+
names_zh = {
|
|
522
|
+
'bibilabu': '比比拉布(香蕉猫)',
|
|
523
|
+
'bagayalu': '八嘎呀路(坐姿水豚)',
|
|
524
|
+
'wodedaodun': '我的刀盾(趴姿水豚)',
|
|
525
|
+
'bababoyi': '巴巴博一(圆猫球)',
|
|
526
|
+
'waibibabu': '歪比巴卜(大胡子壮汉)',
|
|
527
|
+
'gugugaga': '咕咕嘎嘎(黑刘海猫)',
|
|
528
|
+
}
|
|
529
|
+
states_zh = {'normal': '普通', 'happy': '开心', 'sleep': '睡觉'}
|
|
530
|
+
title = names_zh.get(name, name)
|
|
531
|
+
st = states_zh.get(state, state)
|
|
532
|
+
print(f"\n {BOLD}{title}{RESET} · {st}")
|
|
533
|
+
render_sprite(name, state)
|
|
534
|
+
|
|
535
|
+
def render_all():
|
|
536
|
+
print()
|
|
537
|
+
print(" ═══════════════════════════════════")
|
|
538
|
+
print(f" 🐾 {BOLD}CodePet 像素角色画廊{RESET}")
|
|
539
|
+
print(" ═══════════════════════════════════")
|
|
540
|
+
for name in ['bibilabu', 'bagayalu', 'wodedaodun', 'bababoyi', 'waibibabu', 'gugugaga']:
|
|
541
|
+
for state in ['normal', 'happy', 'sleep']:
|
|
542
|
+
render_card(name, state)
|
|
543
|
+
print(" ───────────────────────────────────")
|
|
544
|
+
print()
|
|
545
|
+
|
|
546
|
+
# ── 入口 ──
|
|
547
|
+
if __name__ == '__main__':
|
|
548
|
+
name_map = {
|
|
549
|
+
'比比拉布': 'bibilabu', '八嘎呀路': 'bagayalu',
|
|
550
|
+
'我的刀盾': 'wodedaodun', '巴巴博一': 'bababoyi',
|
|
551
|
+
'歪比巴卜': 'waibibabu', '咕咕嘎嘎': 'gugugaga',
|
|
552
|
+
}
|
|
553
|
+
if len(sys.argv) < 2 or sys.argv[1] == 'all':
|
|
554
|
+
render_all()
|
|
555
|
+
else:
|
|
556
|
+
name = name_map.get(sys.argv[1], sys.argv[1])
|
|
557
|
+
state = sys.argv[2] if len(sys.argv) > 2 else 'normal'
|
|
558
|
+
render_card(name, state)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""将角色渲染为 PNG 图片,供 Claude Code 直接读取显示"""
|
|
3
|
+
|
|
4
|
+
import os, sys
|
|
5
|
+
from PIL import Image
|
|
6
|
+
|
|
7
|
+
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
8
|
+
SPRITE_DIR = os.path.join(SCRIPT_DIR, "..", "sprites")
|
|
9
|
+
PET_DIR = os.path.join(os.path.expanduser("~"), ".codepet")
|
|
10
|
+
|
|
11
|
+
def render_to_png(character, variant='normal', output_path=None):
|
|
12
|
+
"""将角色图片缩放到合适大小并保存为 PNG"""
|
|
13
|
+
# 优先用变体图
|
|
14
|
+
src = os.path.join(SPRITE_DIR, character, f"{variant}.png")
|
|
15
|
+
if not os.path.exists(src):
|
|
16
|
+
src = os.path.join(SPRITE_DIR, f"{character}.png")
|
|
17
|
+
if not os.path.exists(src):
|
|
18
|
+
print(f"图片不存在: {src}")
|
|
19
|
+
return None
|
|
20
|
+
|
|
21
|
+
img = Image.open(src).convert("RGBA")
|
|
22
|
+
|
|
23
|
+
# 缩放到合适展示尺寸(宽度 400px)
|
|
24
|
+
target_w = 400
|
|
25
|
+
ratio = target_w / img.width
|
|
26
|
+
target_h = int(img.height * ratio)
|
|
27
|
+
img = img.resize((target_w, target_h), Image.LANCZOS)
|
|
28
|
+
|
|
29
|
+
# 白色背景替换为透明(如果需要)
|
|
30
|
+
# 保持原样即可
|
|
31
|
+
|
|
32
|
+
if not output_path:
|
|
33
|
+
os.makedirs(PET_DIR, exist_ok=True)
|
|
34
|
+
output_path = os.path.join(PET_DIR, "display.png")
|
|
35
|
+
|
|
36
|
+
img.save(output_path)
|
|
37
|
+
return output_path
|
|
38
|
+
|
|
39
|
+
if __name__ == '__main__':
|
|
40
|
+
character = sys.argv[1] if len(sys.argv) > 1 else 'gugugaga'
|
|
41
|
+
variant = sys.argv[2] if len(sys.argv) > 2 else 'normal'
|
|
42
|
+
path = render_to_png(character, variant)
|
|
43
|
+
if path:
|
|
44
|
+
print(path)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""一键展示所有 CodePet 角色的终端像素画"""
|
|
3
|
+
|
|
4
|
+
import os, sys
|
|
5
|
+
|
|
6
|
+
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
7
|
+
sys.path.insert(0, SCRIPT_DIR)
|
|
8
|
+
|
|
9
|
+
from img2terminal import render_image
|
|
10
|
+
from PIL import Image
|
|
11
|
+
|
|
12
|
+
SPRITE_DIR = os.path.join(SCRIPT_DIR, "..", "sprites")
|
|
13
|
+
RESET = "\033[0m"
|
|
14
|
+
BOLD = "\033[1m"
|
|
15
|
+
|
|
16
|
+
chars = [
|
|
17
|
+
("bibilabu", "比比拉布", ""),
|
|
18
|
+
("bagayalu", "八嘎呀路", ""),
|
|
19
|
+
("wodedaodun", "我的刀盾", ""),
|
|
20
|
+
("bababoyi", "巴巴博一", ""),
|
|
21
|
+
("waibibabu", "歪比巴卜", ""),
|
|
22
|
+
("gugugaga", "咕咕嘎嘎", ""),
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
width = int(sys.argv[1]) if len(sys.argv) > 1 else 45
|
|
26
|
+
|
|
27
|
+
print()
|
|
28
|
+
print(f" ═══════════════════════════════════════")
|
|
29
|
+
print(f" 🐾 {BOLD}CodePet 角色画廊{RESET}(终端像素画)")
|
|
30
|
+
print(f" ═══════════════════════════════════════")
|
|
31
|
+
|
|
32
|
+
for eng, zh, desc in chars:
|
|
33
|
+
img_path = os.path.join(SPRITE_DIR, f"{eng}.png")
|
|
34
|
+
if not os.path.exists(img_path):
|
|
35
|
+
print(f"\n [!] {zh} 图片不存在: {img_path}")
|
|
36
|
+
continue
|
|
37
|
+
img = Image.open(img_path)
|
|
38
|
+
label = f"\n {BOLD}{zh}{RESET}" + (f"({desc})" if desc else "")
|
|
39
|
+
print(label)
|
|
40
|
+
result = render_image(img, width)
|
|
41
|
+
for line in result.splitlines():
|
|
42
|
+
print(f" {line}")
|
|
43
|
+
print(f" {'─' * 40}")
|
|
44
|
+
|
|
45
|
+
print()
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""一次性展示全部 36 张角色表情的终端像素画"""
|
|
3
|
+
|
|
4
|
+
import os, sys
|
|
5
|
+
|
|
6
|
+
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
7
|
+
sys.path.insert(0, SCRIPT_DIR)
|
|
8
|
+
from img2terminal import render_image
|
|
9
|
+
from PIL import Image
|
|
10
|
+
|
|
11
|
+
SPRITE_DIR = os.path.join(SCRIPT_DIR, "..", "sprites")
|
|
12
|
+
RESET = "\033[0m"
|
|
13
|
+
BOLD = "\033[1m"
|
|
14
|
+
|
|
15
|
+
CHARS = ["bibilabu", "bagayalu", "wodedaodun", "bababoyi", "waibibabu", "gugugaga"]
|
|
16
|
+
NAMES = {"bibilabu": "比比拉布", "bagayalu": "八嘎呀路", "wodedaodun": "我的刀盾", "bababoyi": "巴巴博一", "waibibabu": "歪比巴卜", "gugugaga": "咕咕嘎嘎"}
|
|
17
|
+
EXPRS = ["normal", "happy", "sleep", "eat", "pet", "worry"]
|
|
18
|
+
EXPR_ZH = {"normal": "普通", "happy": "开心", "sleep": "睡觉", "eat": "吃东西", "pet": "被撸", "worry": "焦虑"}
|
|
19
|
+
|
|
20
|
+
width = int(sys.argv[1]) if len(sys.argv) > 1 else 25
|
|
21
|
+
|
|
22
|
+
print()
|
|
23
|
+
print(f" ═══════════════════════════════════════════")
|
|
24
|
+
print(f" 🐾 {BOLD}CodePet 全部 36 张角色表情{RESET}")
|
|
25
|
+
print(f" ═══════════════════════════════════════════")
|
|
26
|
+
|
|
27
|
+
for char in CHARS:
|
|
28
|
+
print(f"\n {BOLD}【{NAMES[char]}】{RESET}")
|
|
29
|
+
for expr in EXPRS:
|
|
30
|
+
path = os.path.join(SPRITE_DIR, char, f"{expr}.png")
|
|
31
|
+
if not os.path.exists(path):
|
|
32
|
+
print(f" {EXPR_ZH[expr]}: 缺失")
|
|
33
|
+
continue
|
|
34
|
+
img = Image.open(path)
|
|
35
|
+
print(f"\n {EXPR_ZH[expr]}:")
|
|
36
|
+
result = render_image(img, width)
|
|
37
|
+
for line in result.splitlines():
|
|
38
|
+
print(f" {line}")
|
|
39
|
+
print(f"\n {'─' * 44}")
|
|
40
|
+
|
|
41
|
+
print()
|