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.
@@ -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()