clawmate 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/electron-builder.yml +23 -0
- package/index.js +341 -0
- package/main/ai-bridge.js +261 -0
- package/main/ai-connector.js +169 -0
- package/main/autostart.js +42 -0
- package/main/desktop-path.js +33 -0
- package/main/file-ops.js +146 -0
- package/main/index.js +128 -0
- package/main/ipc-handlers.js +104 -0
- package/main/manifest.js +70 -0
- package/main/platform.js +33 -0
- package/main/store.js +45 -0
- package/main/tray.js +125 -0
- package/openclaw.plugin.json +15 -0
- package/package.json +30 -0
- package/preload/preload.js +57 -0
- package/renderer/css/effects.css +87 -0
- package/renderer/css/launcher.css +127 -0
- package/renderer/css/pet.css +109 -0
- package/renderer/css/speech.css +72 -0
- package/renderer/first-run.html +90 -0
- package/renderer/index.html +62 -0
- package/renderer/js/ai-controller.js +206 -0
- package/renderer/js/app.js +107 -0
- package/renderer/js/character.js +396 -0
- package/renderer/js/interactions.js +164 -0
- package/renderer/js/memory.js +322 -0
- package/renderer/js/mode-manager.js +82 -0
- package/renderer/js/pet-engine.js +228 -0
- package/renderer/js/speech.js +116 -0
- package/renderer/js/state-machine.js +175 -0
- package/renderer/js/time-aware.js +93 -0
- package/renderer/launcher.html +58 -0
- package/shared/constants.js +80 -0
- package/shared/messages.js +103 -0
- package/shared/personalities.js +106 -0
- package/skills/launch-pet/index.js +64 -0
- package/skills/launch-pet/skill.json +26 -0
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 픽셀 아트 랍스터(Claw) 캐릭터 렌더러
|
|
3
|
+
* 16x16 그리드 → CSS div로 렌더링 → 4x 확대 (64x64px)
|
|
4
|
+
*
|
|
5
|
+
* 색상 코드:
|
|
6
|
+
* 0 = 투명, 1 = primary(빨강), 2 = secondary(연빨강),
|
|
7
|
+
* 3 = dark(갈색), 4 = eye, 5 = pupil, 6 = claw 전용
|
|
8
|
+
*/
|
|
9
|
+
const Character = (() => {
|
|
10
|
+
const PIXEL = 4;
|
|
11
|
+
const GRID = 16;
|
|
12
|
+
const SIZE = PIXEL * GRID;
|
|
13
|
+
|
|
14
|
+
// --- 프레임 데이터 (16x16 배열) ---
|
|
15
|
+
const FRAMES = {
|
|
16
|
+
idle: [
|
|
17
|
+
// Frame 0: 기본 자세 — 집게 열림
|
|
18
|
+
[
|
|
19
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
20
|
+
[0,0,6,6,0,0,0,0,0,0,0,0,6,6,0,0],
|
|
21
|
+
[0,6,0,0,6,0,0,0,0,0,0,6,0,0,6,0],
|
|
22
|
+
[0,6,0,0,6,0,0,0,0,0,0,6,0,0,6,0],
|
|
23
|
+
[0,0,6,6,0,0,0,0,0,0,0,0,6,6,0,0],
|
|
24
|
+
[0,0,0,6,1,1,0,0,0,0,1,1,6,0,0,0],
|
|
25
|
+
[0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0],
|
|
26
|
+
[0,0,0,1,1,4,5,1,1,4,5,1,1,0,0,0],
|
|
27
|
+
[0,0,0,1,1,4,5,1,1,4,5,1,1,0,0,0],
|
|
28
|
+
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
|
|
29
|
+
[0,0,1,2,1,1,1,1,1,1,1,1,2,1,0,0],
|
|
30
|
+
[0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0],
|
|
31
|
+
[0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0],
|
|
32
|
+
[0,0,0,3,3,0,3,3,3,3,0,3,3,0,0,0],
|
|
33
|
+
[0,0,3,3,0,0,0,3,3,0,0,0,3,3,0,0],
|
|
34
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
35
|
+
],
|
|
36
|
+
// Frame 1: 집게 닫힘 (물결)
|
|
37
|
+
[
|
|
38
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
39
|
+
[0,0,6,6,0,0,0,0,0,0,0,0,6,6,0,0],
|
|
40
|
+
[0,0,6,6,0,0,0,0,0,0,0,0,6,6,0,0],
|
|
41
|
+
[0,0,6,6,0,0,0,0,0,0,0,0,6,6,0,0],
|
|
42
|
+
[0,0,0,6,6,0,0,0,0,0,0,6,6,0,0,0],
|
|
43
|
+
[0,0,0,6,1,1,0,0,0,0,1,1,6,0,0,0],
|
|
44
|
+
[0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0],
|
|
45
|
+
[0,0,0,1,1,4,5,1,1,4,5,1,1,0,0,0],
|
|
46
|
+
[0,0,0,1,1,4,5,1,1,4,5,1,1,0,0,0],
|
|
47
|
+
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
|
|
48
|
+
[0,0,1,2,1,1,1,1,1,1,1,1,2,1,0,0],
|
|
49
|
+
[0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0],
|
|
50
|
+
[0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0],
|
|
51
|
+
[0,0,0,3,3,0,3,3,3,3,0,3,3,0,0,0],
|
|
52
|
+
[0,0,3,3,0,0,0,3,3,0,0,0,3,3,0,0],
|
|
53
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
54
|
+
],
|
|
55
|
+
],
|
|
56
|
+
|
|
57
|
+
walk: [
|
|
58
|
+
// Frame 0: 왼발 앞
|
|
59
|
+
[
|
|
60
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
61
|
+
[0,0,6,6,0,0,0,0,0,0,0,0,6,6,0,0],
|
|
62
|
+
[0,6,0,0,6,0,0,0,0,0,0,6,0,0,6,0],
|
|
63
|
+
[0,6,0,0,6,0,0,0,0,0,0,6,0,0,6,0],
|
|
64
|
+
[0,0,6,6,0,0,0,0,0,0,0,0,6,6,0,0],
|
|
65
|
+
[0,0,0,6,1,1,0,0,0,0,1,1,6,0,0,0],
|
|
66
|
+
[0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0],
|
|
67
|
+
[0,0,0,1,1,4,5,1,1,4,5,1,1,0,0,0],
|
|
68
|
+
[0,0,0,1,1,4,5,1,1,4,5,1,1,0,0,0],
|
|
69
|
+
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
|
|
70
|
+
[0,0,1,2,1,1,1,1,1,1,1,1,2,1,0,0],
|
|
71
|
+
[0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0],
|
|
72
|
+
[0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0],
|
|
73
|
+
[0,0,3,3,0,0,3,3,3,3,0,0,3,3,0,0],
|
|
74
|
+
[0,3,3,0,0,0,0,3,3,0,0,0,0,3,3,0],
|
|
75
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
76
|
+
],
|
|
77
|
+
// Frame 1: 오른발 앞
|
|
78
|
+
[
|
|
79
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
80
|
+
[0,0,6,6,0,0,0,0,0,0,0,0,6,6,0,0],
|
|
81
|
+
[0,6,0,0,6,0,0,0,0,0,0,6,0,0,6,0],
|
|
82
|
+
[0,6,0,0,6,0,0,0,0,0,0,6,0,0,6,0],
|
|
83
|
+
[0,0,6,6,0,0,0,0,0,0,0,0,6,6,0,0],
|
|
84
|
+
[0,0,0,6,1,1,0,0,0,0,1,1,6,0,0,0],
|
|
85
|
+
[0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0],
|
|
86
|
+
[0,0,0,1,1,4,5,1,1,4,5,1,1,0,0,0],
|
|
87
|
+
[0,0,0,1,1,4,5,1,1,4,5,1,1,0,0,0],
|
|
88
|
+
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
|
|
89
|
+
[0,0,1,2,1,1,1,1,1,1,1,1,2,1,0,0],
|
|
90
|
+
[0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0],
|
|
91
|
+
[0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0],
|
|
92
|
+
[0,0,0,3,3,0,0,3,3,0,0,3,3,0,0,0],
|
|
93
|
+
[0,0,0,0,3,3,0,0,0,0,3,3,0,0,0,0],
|
|
94
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
95
|
+
],
|
|
96
|
+
// Frame 2: 왼발 뒤
|
|
97
|
+
[
|
|
98
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
99
|
+
[0,0,6,6,0,0,0,0,0,0,0,0,6,6,0,0],
|
|
100
|
+
[0,0,6,6,0,0,0,0,0,0,0,0,6,6,0,0],
|
|
101
|
+
[0,0,6,6,0,0,0,0,0,0,0,0,6,6,0,0],
|
|
102
|
+
[0,0,0,6,6,0,0,0,0,0,0,6,6,0,0,0],
|
|
103
|
+
[0,0,0,6,1,1,0,0,0,0,1,1,6,0,0,0],
|
|
104
|
+
[0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0],
|
|
105
|
+
[0,0,0,1,1,4,5,1,1,4,5,1,1,0,0,0],
|
|
106
|
+
[0,0,0,1,1,4,5,1,1,4,5,1,1,0,0,0],
|
|
107
|
+
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
|
|
108
|
+
[0,0,1,2,1,1,1,1,1,1,1,1,2,1,0,0],
|
|
109
|
+
[0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0],
|
|
110
|
+
[0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0],
|
|
111
|
+
[0,0,3,3,0,0,3,3,3,3,0,0,3,3,0,0],
|
|
112
|
+
[0,3,3,0,0,0,0,3,3,0,0,0,0,3,3,0],
|
|
113
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
114
|
+
],
|
|
115
|
+
// Frame 3: 오른발 뒤
|
|
116
|
+
[
|
|
117
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
118
|
+
[0,0,6,6,0,0,0,0,0,0,0,0,6,6,0,0],
|
|
119
|
+
[0,0,6,6,0,0,0,0,0,0,0,0,6,6,0,0],
|
|
120
|
+
[0,0,6,6,0,0,0,0,0,0,0,0,6,6,0,0],
|
|
121
|
+
[0,0,0,6,6,0,0,0,0,0,0,6,6,0,0,0],
|
|
122
|
+
[0,0,0,6,1,1,0,0,0,0,1,1,6,0,0,0],
|
|
123
|
+
[0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0],
|
|
124
|
+
[0,0,0,1,1,4,5,1,1,4,5,1,1,0,0,0],
|
|
125
|
+
[0,0,0,1,1,4,5,1,1,4,5,1,1,0,0,0],
|
|
126
|
+
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
|
|
127
|
+
[0,0,1,2,1,1,1,1,1,1,1,1,2,1,0,0],
|
|
128
|
+
[0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0],
|
|
129
|
+
[0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0],
|
|
130
|
+
[0,0,0,3,3,0,0,3,3,0,0,3,3,0,0,0],
|
|
131
|
+
[0,0,0,0,3,3,0,0,0,0,3,3,0,0,0,0],
|
|
132
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
133
|
+
],
|
|
134
|
+
],
|
|
135
|
+
|
|
136
|
+
climb: [
|
|
137
|
+
// Frame 0: 기어오르기 포즈 1 (옆모습)
|
|
138
|
+
[
|
|
139
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
140
|
+
[0,0,0,0,6,6,0,0,0,0,0,0,0,0,0,0],
|
|
141
|
+
[0,0,0,6,0,0,6,0,0,0,0,0,0,0,0,0],
|
|
142
|
+
[0,0,0,6,0,0,6,0,0,0,0,0,0,0,0,0],
|
|
143
|
+
[0,0,0,0,6,6,1,1,0,0,0,0,0,0,0,0],
|
|
144
|
+
[0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0],
|
|
145
|
+
[0,0,0,0,1,4,5,1,1,0,0,0,0,0,0,0],
|
|
146
|
+
[0,0,0,0,1,4,5,1,1,1,0,0,0,0,0,0],
|
|
147
|
+
[0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0],
|
|
148
|
+
[0,0,0,1,2,1,1,1,1,0,0,0,0,0,0,0],
|
|
149
|
+
[0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0],
|
|
150
|
+
[0,0,0,0,3,0,3,0,0,0,0,0,0,0,0,0],
|
|
151
|
+
[0,0,0,3,0,0,0,3,0,0,0,0,0,0,0,0],
|
|
152
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
153
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
154
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
155
|
+
],
|
|
156
|
+
// Frame 1: 기어오르기 포즈 2
|
|
157
|
+
[
|
|
158
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
159
|
+
[0,0,0,0,6,6,0,0,0,0,0,0,0,0,0,0],
|
|
160
|
+
[0,0,0,6,0,0,6,0,0,0,0,0,0,0,0,0],
|
|
161
|
+
[0,0,0,6,0,0,6,0,0,0,0,0,0,0,0,0],
|
|
162
|
+
[0,0,0,0,6,6,1,1,0,0,0,0,0,0,0,0],
|
|
163
|
+
[0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0],
|
|
164
|
+
[0,0,0,0,1,4,5,1,1,0,0,0,0,0,0,0],
|
|
165
|
+
[0,0,0,0,1,4,5,1,1,1,0,0,0,0,0,0],
|
|
166
|
+
[0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0],
|
|
167
|
+
[0,0,0,1,2,1,1,1,1,0,0,0,0,0,0,0],
|
|
168
|
+
[0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0],
|
|
169
|
+
[0,0,0,3,0,0,0,3,0,0,0,0,0,0,0,0],
|
|
170
|
+
[0,0,0,0,3,0,3,0,0,0,0,0,0,0,0,0],
|
|
171
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
172
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
173
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
174
|
+
],
|
|
175
|
+
],
|
|
176
|
+
|
|
177
|
+
sleep: [
|
|
178
|
+
[
|
|
179
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
180
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
181
|
+
[0,0,6,6,0,0,0,0,0,0,0,0,6,6,0,0],
|
|
182
|
+
[0,0,6,6,0,0,0,0,0,0,0,0,6,6,0,0],
|
|
183
|
+
[0,0,0,6,6,0,0,0,0,0,0,6,6,0,0,0],
|
|
184
|
+
[0,0,0,6,1,1,0,0,0,0,1,1,6,0,0,0],
|
|
185
|
+
[0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0],
|
|
186
|
+
[0,0,0,1,1,3,3,1,1,3,3,1,1,0,0,0],
|
|
187
|
+
[0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0],
|
|
188
|
+
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
|
|
189
|
+
[0,0,1,2,1,1,1,1,1,1,1,1,2,1,0,0],
|
|
190
|
+
[0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0],
|
|
191
|
+
[0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0],
|
|
192
|
+
[0,0,0,3,3,0,3,3,3,3,0,3,3,0,0,0],
|
|
193
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
194
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
195
|
+
],
|
|
196
|
+
],
|
|
197
|
+
|
|
198
|
+
carry: [
|
|
199
|
+
// Frame 0: 파일 들고 걷기 1
|
|
200
|
+
[
|
|
201
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
202
|
+
[0,0,6,1,1,1,1,0,0,1,1,1,1,6,0,0],
|
|
203
|
+
[0,0,6,1,2,2,1,0,0,1,2,2,1,6,0,0],
|
|
204
|
+
[0,0,6,1,1,1,1,0,0,1,1,1,1,6,0,0],
|
|
205
|
+
[0,0,0,6,1,1,0,0,0,0,1,1,6,0,0,0],
|
|
206
|
+
[0,0,0,6,1,1,0,0,0,0,1,1,6,0,0,0],
|
|
207
|
+
[0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0],
|
|
208
|
+
[0,0,0,1,1,4,5,1,1,4,5,1,1,0,0,0],
|
|
209
|
+
[0,0,0,1,1,4,5,1,1,4,5,1,1,0,0,0],
|
|
210
|
+
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
|
|
211
|
+
[0,0,1,2,1,1,1,1,1,1,1,1,2,1,0,0],
|
|
212
|
+
[0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0],
|
|
213
|
+
[0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0],
|
|
214
|
+
[0,0,3,3,0,0,3,3,3,3,0,0,3,3,0,0],
|
|
215
|
+
[0,3,3,0,0,0,0,3,3,0,0,0,0,3,3,0],
|
|
216
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
217
|
+
],
|
|
218
|
+
// Frame 1: 파일 들고 걷기 2
|
|
219
|
+
[
|
|
220
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
221
|
+
[0,0,6,1,1,1,1,0,0,1,1,1,1,6,0,0],
|
|
222
|
+
[0,0,6,1,2,2,1,0,0,1,2,2,1,6,0,0],
|
|
223
|
+
[0,0,6,1,1,1,1,0,0,1,1,1,1,6,0,0],
|
|
224
|
+
[0,0,0,6,1,1,0,0,0,0,1,1,6,0,0,0],
|
|
225
|
+
[0,0,0,6,1,1,0,0,0,0,1,1,6,0,0,0],
|
|
226
|
+
[0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0],
|
|
227
|
+
[0,0,0,1,1,4,5,1,1,4,5,1,1,0,0,0],
|
|
228
|
+
[0,0,0,1,1,4,5,1,1,4,5,1,1,0,0,0],
|
|
229
|
+
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
|
|
230
|
+
[0,0,1,2,1,1,1,1,1,1,1,1,2,1,0,0],
|
|
231
|
+
[0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0],
|
|
232
|
+
[0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0],
|
|
233
|
+
[0,0,0,3,3,0,0,3,3,0,0,3,3,0,0,0],
|
|
234
|
+
[0,0,0,0,3,3,0,0,0,0,3,3,0,0,0,0],
|
|
235
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
236
|
+
],
|
|
237
|
+
],
|
|
238
|
+
|
|
239
|
+
scared: [
|
|
240
|
+
// Frame 0: 놀람 — 눈 크게
|
|
241
|
+
[
|
|
242
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
243
|
+
[0,0,6,6,0,0,0,0,0,0,0,0,6,6,0,0],
|
|
244
|
+
[0,6,0,0,6,0,0,0,0,0,0,6,0,0,6,0],
|
|
245
|
+
[0,6,0,0,6,0,0,0,0,0,0,6,0,0,6,0],
|
|
246
|
+
[0,0,6,6,0,0,0,0,0,0,0,0,6,6,0,0],
|
|
247
|
+
[0,0,0,6,1,1,0,0,0,0,1,1,6,0,0,0],
|
|
248
|
+
[0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0],
|
|
249
|
+
[0,0,0,1,4,4,5,1,1,4,4,5,1,0,0,0],
|
|
250
|
+
[0,0,0,1,4,4,5,1,1,4,4,5,1,0,0,0],
|
|
251
|
+
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
|
|
252
|
+
[0,0,1,2,1,1,1,1,1,1,1,1,2,1,0,0],
|
|
253
|
+
[0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0],
|
|
254
|
+
[0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0],
|
|
255
|
+
[0,0,3,3,0,0,3,3,3,3,0,0,3,3,0,0],
|
|
256
|
+
[0,3,3,0,0,0,0,3,3,0,0,0,0,3,3,0],
|
|
257
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
258
|
+
],
|
|
259
|
+
// Frame 1: 뒤로 움찔
|
|
260
|
+
[
|
|
261
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
262
|
+
[0,0,0,6,6,0,0,0,0,0,0,6,6,0,0,0],
|
|
263
|
+
[0,0,6,0,0,6,0,0,0,0,6,0,0,6,0,0],
|
|
264
|
+
[0,0,6,0,0,6,0,0,0,0,6,0,0,6,0,0],
|
|
265
|
+
[0,0,0,6,6,0,0,0,0,0,0,6,6,0,0,0],
|
|
266
|
+
[0,0,0,0,6,1,1,0,0,1,1,6,0,0,0,0],
|
|
267
|
+
[0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0],
|
|
268
|
+
[0,0,0,0,1,4,4,5,4,4,5,1,0,0,0,0],
|
|
269
|
+
[0,0,0,0,1,4,4,5,4,4,5,1,0,0,0,0],
|
|
270
|
+
[0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0],
|
|
271
|
+
[0,0,0,1,2,1,1,1,1,1,1,2,1,0,0,0],
|
|
272
|
+
[0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0],
|
|
273
|
+
[0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0],
|
|
274
|
+
[0,0,0,0,3,3,0,3,3,0,3,3,0,0,0,0],
|
|
275
|
+
[0,0,0,3,3,0,0,0,0,0,0,3,3,0,0,0],
|
|
276
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
277
|
+
],
|
|
278
|
+
],
|
|
279
|
+
|
|
280
|
+
excited: [
|
|
281
|
+
// Frame 0: 점프 업
|
|
282
|
+
[
|
|
283
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
284
|
+
[0,6,6,0,0,0,0,0,0,0,0,0,0,6,6,0],
|
|
285
|
+
[6,0,0,6,0,0,0,0,0,0,0,0,6,0,0,6],
|
|
286
|
+
[6,0,0,6,0,0,0,0,0,0,0,0,6,0,0,6],
|
|
287
|
+
[0,6,6,0,0,0,0,0,0,0,0,0,0,6,6,0],
|
|
288
|
+
[0,0,6,1,1,0,0,0,0,0,0,1,1,6,0,0],
|
|
289
|
+
[0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0],
|
|
290
|
+
[0,0,1,1,4,5,1,1,1,1,4,5,1,1,0,0],
|
|
291
|
+
[0,0,1,1,4,5,1,1,1,1,4,5,1,1,0,0],
|
|
292
|
+
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
|
|
293
|
+
[0,1,2,1,1,1,1,1,1,1,1,1,1,2,1,0],
|
|
294
|
+
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
|
|
295
|
+
[0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0],
|
|
296
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
297
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
298
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
299
|
+
],
|
|
300
|
+
// Frame 1: 착지
|
|
301
|
+
[
|
|
302
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
303
|
+
[0,0,6,6,0,0,0,0,0,0,0,0,6,6,0,0],
|
|
304
|
+
[0,6,0,0,6,0,0,0,0,0,0,6,0,0,6,0],
|
|
305
|
+
[0,6,0,0,6,0,0,0,0,0,0,6,0,0,6,0],
|
|
306
|
+
[0,0,6,6,0,0,0,0,0,0,0,0,6,6,0,0],
|
|
307
|
+
[0,0,0,6,1,1,0,0,0,0,1,1,6,0,0,0],
|
|
308
|
+
[0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0],
|
|
309
|
+
[0,0,0,1,1,4,5,1,1,4,5,1,1,0,0,0],
|
|
310
|
+
[0,0,0,1,1,4,5,1,1,4,5,1,1,0,0,0],
|
|
311
|
+
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
|
|
312
|
+
[0,0,1,2,1,1,1,1,1,1,1,1,2,1,0,0],
|
|
313
|
+
[0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0],
|
|
314
|
+
[0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0],
|
|
315
|
+
[0,3,3,3,3,0,3,3,3,3,0,3,3,3,3,0],
|
|
316
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
317
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
318
|
+
],
|
|
319
|
+
],
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
// 상태 → 프레임셋 매핑
|
|
323
|
+
const STATE_FRAMES = {
|
|
324
|
+
idle: 'idle',
|
|
325
|
+
walking: 'walk',
|
|
326
|
+
climbing_up: 'climb',
|
|
327
|
+
climbing_down: 'climb',
|
|
328
|
+
ceiling_walk: 'walk',
|
|
329
|
+
sleeping: 'sleep',
|
|
330
|
+
carrying: 'carry',
|
|
331
|
+
playing: 'idle',
|
|
332
|
+
interacting: 'excited',
|
|
333
|
+
scared: 'scared',
|
|
334
|
+
excited: 'excited',
|
|
335
|
+
};
|
|
336
|
+
|
|
337
|
+
let currentCanvas = null;
|
|
338
|
+
let currentColorMap = null;
|
|
339
|
+
|
|
340
|
+
function createCanvas(container) {
|
|
341
|
+
const canvas = document.createElement('canvas');
|
|
342
|
+
canvas.width = SIZE;
|
|
343
|
+
canvas.height = SIZE;
|
|
344
|
+
canvas.style.width = SIZE + 'px';
|
|
345
|
+
canvas.style.height = SIZE + 'px';
|
|
346
|
+
canvas.style.imageRendering = 'pixelated';
|
|
347
|
+
container.appendChild(canvas);
|
|
348
|
+
currentCanvas = canvas;
|
|
349
|
+
return canvas;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
function setColorMap(colors) {
|
|
353
|
+
currentColorMap = {
|
|
354
|
+
0: 'transparent',
|
|
355
|
+
1: colors.primary,
|
|
356
|
+
2: colors.secondary,
|
|
357
|
+
3: colors.dark,
|
|
358
|
+
4: colors.eye,
|
|
359
|
+
5: colors.pupil,
|
|
360
|
+
6: colors.claw || colors.primary,
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function renderFrame(state, frameIndex, flipX = false) {
|
|
365
|
+
if (!currentCanvas || !currentColorMap) return;
|
|
366
|
+
const ctx = currentCanvas.getContext('2d');
|
|
367
|
+
ctx.clearRect(0, 0, SIZE, SIZE);
|
|
368
|
+
|
|
369
|
+
const frameSet = STATE_FRAMES[state] || 'idle';
|
|
370
|
+
const frames = FRAMES[frameSet];
|
|
371
|
+
if (!frames) return;
|
|
372
|
+
|
|
373
|
+
const frame = frames[frameIndex % frames.length];
|
|
374
|
+
if (!frame) return;
|
|
375
|
+
|
|
376
|
+
for (let y = 0; y < GRID; y++) {
|
|
377
|
+
for (let x = 0; x < GRID; x++) {
|
|
378
|
+
const colorCode = frame[y][x];
|
|
379
|
+
if (colorCode === 0) continue;
|
|
380
|
+
const color = currentColorMap[colorCode] || 'transparent';
|
|
381
|
+
if (color === 'transparent') continue;
|
|
382
|
+
|
|
383
|
+
ctx.fillStyle = color;
|
|
384
|
+
const drawX = flipX ? (GRID - 1 - x) * PIXEL : x * PIXEL;
|
|
385
|
+
ctx.fillRect(drawX, y * PIXEL, PIXEL, PIXEL);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
function getFrameCount(state) {
|
|
391
|
+
const frameSet = STATE_FRAMES[state] || 'idle';
|
|
392
|
+
return (FRAMES[frameSet] || FRAMES.idle).length;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
return { createCanvas, setColorMap, renderFrame, getFrameCount, SIZE, FRAMES, STATE_FRAMES };
|
|
396
|
+
})();
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 마우스/클릭/드래그 상호작용 시스템
|
|
3
|
+
*
|
|
4
|
+
* AI 연결 시: 이벤트를 OpenClaw에 전달 → AI가 반응 결정
|
|
5
|
+
* AI 미연결 시: 자율 반응 (랜덤 FSM)
|
|
6
|
+
*/
|
|
7
|
+
const Interactions = (() => {
|
|
8
|
+
let isDragging = false;
|
|
9
|
+
let dragOffsetX = 0;
|
|
10
|
+
let dragOffsetY = 0;
|
|
11
|
+
let dragStartPos = null;
|
|
12
|
+
let clickCount = 0;
|
|
13
|
+
let clickTimer = null;
|
|
14
|
+
let lastCursorCheck = 0;
|
|
15
|
+
const CURSOR_CHECK_INTERVAL = 500;
|
|
16
|
+
|
|
17
|
+
function init() {
|
|
18
|
+
const pet = document.getElementById('pet-container');
|
|
19
|
+
if (!pet) return;
|
|
20
|
+
|
|
21
|
+
pet.addEventListener('mouseenter', () => {
|
|
22
|
+
window.clawmate.setClickThrough(false);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
pet.addEventListener('mouseleave', () => {
|
|
26
|
+
if (!isDragging) {
|
|
27
|
+
window.clawmate.setClickThrough(true);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
pet.addEventListener('mousedown', onMouseDown);
|
|
32
|
+
document.addEventListener('mousemove', onMouseMove);
|
|
33
|
+
document.addEventListener('mouseup', onMouseUp);
|
|
34
|
+
document.addEventListener('mousemove', onGlobalMouseMove);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function onMouseDown(e) {
|
|
38
|
+
e.preventDefault();
|
|
39
|
+
e.stopPropagation();
|
|
40
|
+
|
|
41
|
+
const pos = PetEngine.getPosition();
|
|
42
|
+
dragOffsetX = e.clientX - pos.x;
|
|
43
|
+
dragOffsetY = e.clientY - pos.y;
|
|
44
|
+
dragStartPos = { x: pos.x, y: pos.y };
|
|
45
|
+
isDragging = true;
|
|
46
|
+
|
|
47
|
+
const pet = document.getElementById('pet-container');
|
|
48
|
+
pet.classList.add('dragging');
|
|
49
|
+
PetEngine.stop();
|
|
50
|
+
|
|
51
|
+
clickCount++;
|
|
52
|
+
clearTimeout(clickTimer);
|
|
53
|
+
clickTimer = setTimeout(() => {
|
|
54
|
+
if (clickCount >= 3) {
|
|
55
|
+
onTripleClick();
|
|
56
|
+
} else if (clickCount === 1) {
|
|
57
|
+
onSingleClick();
|
|
58
|
+
}
|
|
59
|
+
clickCount = 0;
|
|
60
|
+
}, 400);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function onMouseMove(e) {
|
|
64
|
+
if (!isDragging) return;
|
|
65
|
+
PetEngine.setPosition(e.clientX - dragOffsetX, e.clientY - dragOffsetY);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function onMouseUp() {
|
|
69
|
+
if (!isDragging) return;
|
|
70
|
+
isDragging = false;
|
|
71
|
+
|
|
72
|
+
const pet = document.getElementById('pet-container');
|
|
73
|
+
pet.classList.remove('dragging');
|
|
74
|
+
|
|
75
|
+
const endPos = PetEngine.getPosition();
|
|
76
|
+
PetEngine.snapToNearestEdge();
|
|
77
|
+
StateMachine.forceState('idle');
|
|
78
|
+
PetEngine.start();
|
|
79
|
+
|
|
80
|
+
window.clawmate.setClickThrough(true);
|
|
81
|
+
|
|
82
|
+
// AI에 드래그 이벤트 리포트
|
|
83
|
+
if (dragStartPos) {
|
|
84
|
+
AIController.reportDrag(dragStartPos, endPos);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function onSingleClick() {
|
|
89
|
+
const pos = PetEngine.getPosition();
|
|
90
|
+
|
|
91
|
+
// AI에 클릭 이벤트 리포트
|
|
92
|
+
AIController.reportClick(pos);
|
|
93
|
+
|
|
94
|
+
// AI 연결 시: AI가 반응 결정 (아무것도 안 함, AI 응답 대기)
|
|
95
|
+
// AI 미연결 시: 자율 반응
|
|
96
|
+
if (AIController.isAutonomous()) {
|
|
97
|
+
StateMachine.forceState('interacting');
|
|
98
|
+
Speech.show(Speech.getReactionMessage());
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
Memory.recordClick();
|
|
102
|
+
spawnHeartEffect();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function onTripleClick() {
|
|
106
|
+
if (typeof ModeManager !== 'undefined') {
|
|
107
|
+
ModeManager.toggle();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function onGlobalMouseMove(e) {
|
|
112
|
+
if (isDragging) return;
|
|
113
|
+
const now = Date.now();
|
|
114
|
+
if (now - lastCursorCheck < CURSOR_CHECK_INTERVAL) return;
|
|
115
|
+
lastCursorCheck = now;
|
|
116
|
+
|
|
117
|
+
const pos = PetEngine.getPosition();
|
|
118
|
+
const dist = Math.hypot(e.clientX - (pos.x + 32), e.clientY - (pos.y + 32));
|
|
119
|
+
|
|
120
|
+
if (dist < 100) {
|
|
121
|
+
// AI에 커서 접근 리포트
|
|
122
|
+
AIController.reportCursorNear(dist);
|
|
123
|
+
|
|
124
|
+
// AI 미연결 시: 자율 반응
|
|
125
|
+
if (AIController.isAutonomous()) {
|
|
126
|
+
const state = StateMachine.getState();
|
|
127
|
+
if (state === 'idle' || state === 'walking') {
|
|
128
|
+
if (Math.random() < 0.5) {
|
|
129
|
+
StateMachine.forceState('scared');
|
|
130
|
+
PetEngine.setDirection(e.clientX > pos.x + 32 ? -1 : 1);
|
|
131
|
+
} else {
|
|
132
|
+
StateMachine.forceState('excited');
|
|
133
|
+
Speech.show(Speech.getGreetingMessage());
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function spawnHeartEffect() {
|
|
141
|
+
const pos = PetEngine.getPosition();
|
|
142
|
+
const heart = document.createElement('div');
|
|
143
|
+
heart.className = 'heart-effect';
|
|
144
|
+
heart.textContent = '\u2764\uFE0F';
|
|
145
|
+
heart.style.left = (pos.x + 20 + Math.random() * 24) + 'px';
|
|
146
|
+
heart.style.top = (pos.y - 10) + 'px';
|
|
147
|
+
document.getElementById('world').appendChild(heart);
|
|
148
|
+
setTimeout(() => heart.remove(), 1000);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function spawnStarEffect() {
|
|
152
|
+
const pos = PetEngine.getPosition();
|
|
153
|
+
for (let i = 0; i < 4; i++) {
|
|
154
|
+
const star = document.createElement('div');
|
|
155
|
+
star.className = 'star-effect';
|
|
156
|
+
star.style.left = (pos.x + Math.random() * 64) + 'px';
|
|
157
|
+
star.style.top = (pos.y + Math.random() * 64) + 'px';
|
|
158
|
+
document.getElementById('world').appendChild(star);
|
|
159
|
+
setTimeout(() => star.remove(), 600);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return { init, spawnHeartEffect, spawnStarEffect };
|
|
164
|
+
})();
|