LukasBe commited on
Commit
2170f29
·
verified ·
1 Parent(s): e0b2948

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +6 -4
  2. index.html +397 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Procedural Character Spritesheet
3
- emoji: 🚀
4
- colorFrom: yellow
5
  colorTo: green
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: procedural-character-spritesheet
3
+ emoji: 🐳
4
+ colorFrom: red
5
  colorTo: green
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,397 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Plants vs. Zombies - Procedural Spritesheet</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <style>
9
+ @keyframes idle {
10
+ 0%, 100% { transform: translateY(0); }
11
+ 50% { transform: translateY(-5px); }
12
+ }
13
+
14
+ @keyframes walk {
15
+ 0% { transform: translateX(0); }
16
+ 100% { transform: translateX(5px); }
17
+ }
18
+
19
+ @keyframes attack {
20
+ 0%, 100% { transform: scale(1); }
21
+ 50% { transform: scale(1.1); }
22
+ }
23
+
24
+ .sprite {
25
+ image-rendering: pixelated;
26
+ width: 80px;
27
+ height: 80px;
28
+ }
29
+
30
+ .idle-animation {
31
+ animation: idle 2s infinite ease-in-out;
32
+ }
33
+
34
+ .walk-animation {
35
+ animation: walk 0.5s infinite alternate ease-in-out;
36
+ }
37
+
38
+ .attack-animation {
39
+ animation: attack 0.3s infinite alternate ease-in-out;
40
+ }
41
+
42
+ .grid-item {
43
+ transition: all 0.3s ease;
44
+ }
45
+
46
+ .grid-item:hover {
47
+ transform: scale(1.05);
48
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.2);
49
+ }
50
+ </style>
51
+ </head>
52
+ <body class="bg-green-50 min-h-screen p-8">
53
+ <div class="max-w-6xl mx-auto">
54
+ <header class="text-center mb-12">
55
+ <h1 class="text-5xl font-bold text-green-800 mb-2">Plants vs. Zombies</h1>
56
+ <h2 class="text-2xl font-semibold text-yellow-600">Procedural Character Spritesheet</h2>
57
+ <div class="mt-4">
58
+ <button id="generate-btn" class="bg-green-600 hover:bg-green-700 text-white font-bold py-2 px-6 rounded-full transition-all">
59
+ Generate New Sprites
60
+ </button>
61
+ </div>
62
+ </header>
63
+
64
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-8 mb-12">
65
+ <!-- Plants Section -->
66
+ <div class="bg-white rounded-xl shadow-lg overflow-hidden">
67
+ <div class="bg-green-600 p-4">
68
+ <h3 class="text-xl font-bold text-white">Plants</h3>
69
+ </div>
70
+ <div class="p-4 grid grid-cols-2 sm:grid-cols-3 gap-4" id="plants-container">
71
+ <!-- Plants will be generated here -->
72
+ </div>
73
+ </div>
74
+
75
+ <!-- Zombies Section -->
76
+ <div class="bg-white rounded-xl shadow-lg overflow-hidden">
77
+ <div class="bg-gray-800 p-4">
78
+ <h3 class="text-xl font-bold text-white">Zombies</h3>
79
+ </div>
80
+ <div class="p-4 grid grid-cols-2 sm:grid-cols-3 gap-4" id="zombies-container">
81
+ <!-- Zombies will be generated here -->
82
+ </div>
83
+ </div>
84
+ </div>
85
+
86
+ <div class="bg-white rounded-xl shadow-lg overflow-hidden mb-12">
87
+ <div class="bg-blue-600 p-4">
88
+ <h3 class="text-xl font-bold text-white">Animations Preview</h3>
89
+ </div>
90
+ <div class="p-6 grid grid-cols-1 sm:grid-cols-3 gap-6" id="animations-container">
91
+ <!-- Animation previews will be here -->
92
+ </div>
93
+ </div>
94
+ </div>
95
+
96
+ <script>
97
+ document.addEventListener('DOMContentLoaded', function() {
98
+ generateSprites();
99
+
100
+ document.getElementById('generate-btn').addEventListener('click', function() {
101
+ generateSprites();
102
+ });
103
+ });
104
+
105
+ function generateSprites() {
106
+ generatePlants();
107
+ generateZombies();
108
+ generateAnimations();
109
+ }
110
+
111
+ function generatePlants() {
112
+ const plants = [
113
+ { name: "Sunflower", color: "#FFD700", type: "support" },
114
+ { name: "Peashooter", color: "#4CAF50", type: "ranged" },
115
+ { name: "Wall-nut", color: "#8B4513", type: "defense" },
116
+ { name: "Cherry Bomb", color: "#FF4500", type: "explosive" },
117
+ { name: "Chomper", color: "#9370DB", type: "melee" },
118
+ { name: "Snow Pea", color: "#ADD8E6", type: "ranged" }
119
+ ];
120
+
121
+ const container = document.getElementById('plants-container');
122
+ container.innerHTML = '';
123
+
124
+ plants.forEach(plant => {
125
+ const canvas = document.createElement('canvas');
126
+ canvas.width = 80;
127
+ canvas.height = 80;
128
+ const ctx = canvas.getContext('2d');
129
+
130
+ // Draw plant body
131
+ ctx.fillStyle = plant.color;
132
+ ctx.beginPath();
133
+ ctx.arc(40, 50, 20, 0, Math.PI * 2);
134
+ ctx.fill();
135
+
136
+ // Draw stem
137
+ ctx.fillStyle = "#228B22";
138
+ ctx.fillRect(38, 50, 4, 20);
139
+
140
+ // Draw leaves
141
+ ctx.fillStyle = "#32CD32";
142
+ ctx.beginPath();
143
+ ctx.ellipse(30, 60, 15, 5, Math.PI/4, 0, Math.PI * 2);
144
+ ctx.fill();
145
+ ctx.beginPath();
146
+ ctx.ellipse(50, 60, 15, 5, -Math.PI/4, 0, Math.PI * 2);
147
+ ctx.fill();
148
+
149
+ // Draw face
150
+ ctx.fillStyle = "#000";
151
+ ctx.beginPath();
152
+ ctx.arc(35, 45, 2, 0, Math.PI * 2);
153
+ ctx.arc(45, 45, 2, 0, Math.PI * 2);
154
+ ctx.fill();
155
+
156
+ ctx.beginPath();
157
+ ctx.arc(40, 50, 4, 0, Math.PI);
158
+ ctx.stroke();
159
+
160
+ // Special features based on type
161
+ if (plant.type === "ranged") {
162
+ ctx.fillStyle = "#FF6347";
163
+ ctx.beginPath();
164
+ ctx.arc(60, 40, 10, 0, Math.PI * 2);
165
+ ctx.fill();
166
+ } else if (plant.type === "explosive") {
167
+ ctx.fillStyle = "#FF0000";
168
+ ctx.beginPath();
169
+ ctx.moveTo(60, 40);
170
+ ctx.lineTo(70, 30);
171
+ ctx.lineTo(70, 50);
172
+ ctx.closePath();
173
+ ctx.fill();
174
+ } else if (plant.type === "support") {
175
+ ctx.fillStyle = "#FFD700";
176
+ ctx.beginPath();
177
+ ctx.arc(40, 30, 10, 0, Math.PI * 2);
178
+ ctx.fill();
179
+ }
180
+
181
+ const dataUrl = canvas.toDataURL();
182
+
183
+ const item = document.createElement('div');
184
+ item.className = 'grid-item bg-green-50 rounded-lg p-3 flex flex-col items-center';
185
+ item.innerHTML = `
186
+ <img src="${dataUrl}" class="sprite mb-2" alt="${plant.name}">
187
+ <h4 class="font-bold text-green-800">${plant.name}</h4>
188
+ <span class="text-xs text-gray-600">${plant.type}</span>
189
+ `;
190
+
191
+ container.appendChild(item);
192
+ });
193
+ }
194
+
195
+ function generateZombies() {
196
+ const zombies = [
197
+ { name: "Basic Zombie", color: "#808080", feature: "none" },
198
+ { name: "Conehead Zombie", color: "#A9A9A9", feature: "cone" },
199
+ { name: "Buckethead Zombie", color: "#696969", feature: "bucket" },
200
+ { name: "Football Zombie", color: "#FFA500", feature: "helmet" },
201
+ { name: "Dancing Zombie", color: "#BA55D3", feature: "glasses" },
202
+ { name: "Gargantuar", color: "#2F4F4F", feature: "giant" }
203
+ ];
204
+
205
+ const container = document.getElementById('zombies-container');
206
+ container.innerHTML = '';
207
+
208
+ zombies.forEach(zombie => {
209
+ const canvas = document.createElement('canvas');
210
+ canvas.width = 80;
211
+ canvas.height = 80;
212
+ const ctx = canvas.getContext('2d');
213
+
214
+ // Draw body
215
+ ctx.fillStyle = zombie.color;
216
+ ctx.fillRect(30, 20, 20, 40);
217
+
218
+ // Draw head
219
+ ctx.fillStyle = "#D2B48C";
220
+ ctx.beginPath();
221
+ ctx.arc(40, 20, 15, 0, Math.PI * 2);
222
+ ctx.fill();
223
+
224
+ // Draw face
225
+ ctx.fillStyle = "#000";
226
+ ctx.beginPath();
227
+ ctx.arc(35, 15, 2, 0, Math.PI * 2);
228
+ ctx.arc(45, 15, 2, 0, Math.PI * 2);
229
+ ctx.fill();
230
+
231
+ ctx.beginPath();
232
+ ctx.arc(40, 20, 3, 0, Math.PI);
233
+ ctx.stroke();
234
+
235
+ // Draw arms
236
+ ctx.fillStyle = zombie.color;
237
+ ctx.fillRect(25, 25, 5, 20);
238
+ ctx.fillRect(50, 25, 5, 20);
239
+
240
+ // Draw legs
241
+ ctx.fillRect(30, 60, 10, 15);
242
+ ctx.fillRect(40, 60, 10, 15);
243
+
244
+ // Special features
245
+ if (zombie.feature === "cone") {
246
+ ctx.fillStyle = "#F5DEB3";
247
+ ctx.beginPath();
248
+ ctx.moveTo(25, 5);
249
+ ctx.lineTo(55, 5);
250
+ ctx.lineTo(40, 20);
251
+ ctx.closePath();
252
+ ctx.fill();
253
+ } else if (zombie.feature === "bucket") {
254
+ ctx.fillStyle = "#C0C0C0";
255
+ ctx.beginPath();
256
+ ctx.arc(40, 15, 18, 0, Math.PI * 2);
257
+ ctx.fill();
258
+ } else if (zombie.feature === "helmet") {
259
+ ctx.fillStyle = "#1E90FF";
260
+ ctx.beginPath();
261
+ ctx.arc(40, 15, 18, 0, Math.PI * 2);
262
+ ctx.fill();
263
+ ctx.fillStyle = "#FFFFFF";
264
+ ctx.fillRect(30, 5, 20, 5);
265
+ } else if (zombie.feature === "glasses") {
266
+ ctx.fillStyle = "#000";
267
+ ctx.fillRect(30, 15, 20, 5);
268
+ ctx.fillRect(35, 10, 5, 5);
269
+ ctx.fillRect(40, 10, 5, 5);
270
+ } else if (zombie.feature === "giant") {
271
+ // Scale up for giant
272
+ ctx.scale(1.5, 1.5);
273
+ ctx.translate(-13, -13);
274
+
275
+ // Redraw body larger
276
+ ctx.fillStyle = zombie.color;
277
+ ctx.fillRect(30, 20, 20, 40);
278
+
279
+ // Redraw head larger
280
+ ctx.fillStyle = "#D2B48C";
281
+ ctx.beginPath();
282
+ ctx.arc(40, 20, 15, 0, Math.PI * 2);
283
+ ctx.fill();
284
+
285
+ // Redraw face
286
+ ctx.fillStyle = "#000";
287
+ ctx.beginPath();
288
+ ctx.arc(35, 15, 2, 0, Math.PI * 2);
289
+ ctx.arc(45, 15, 2, 0, Math.PI * 2);
290
+ ctx.fill();
291
+ ctx.beginPath();
292
+ ctx.arc(40, 20, 3, 0, Math.PI);
293
+ ctx.stroke();
294
+
295
+ // Redraw arms
296
+ ctx.fillStyle = zombie.color;
297
+ ctx.fillRect(25, 25, 5, 20);
298
+ ctx.fillRect(50, 25, 5, 20);
299
+
300
+ // Redraw legs
301
+ ctx.fillRect(30, 60, 10, 15);
302
+ ctx.fillRect(40, 60, 10, 15);
303
+
304
+ // Reset transform
305
+ ctx.setTransform(1, 0, 0, 1, 0, 0);
306
+ }
307
+
308
+ const dataUrl = canvas.toDataURL();
309
+
310
+ const item = document.createElement('div');
311
+ item.className = 'grid-item bg-gray-100 rounded-lg p-3 flex flex-col items-center';
312
+ item.innerHTML = `
313
+ <img src="${dataUrl}" class="sprite mb-2" alt="${zombie.name}">
314
+ <h4 class="font-bold text-gray-800">${zombie.name}</h4>
315
+ <span class="text-xs text-gray-600">${zombie.feature}</span>
316
+ `;
317
+
318
+ container.appendChild(item);
319
+ });
320
+ }
321
+
322
+ function generateAnimations() {
323
+ const animations = [
324
+ { name: "Idle", type: "idle-animation" },
325
+ { name: "Walk", type: "walk-animation" },
326
+ { name: "Attack", type: "attack-animation" }
327
+ ];
328
+
329
+ const container = document.getElementById('animations-container');
330
+ container.innerHTML = '';
331
+
332
+ animations.forEach(anim => {
333
+ const canvas = document.createElement('canvas');
334
+ canvas.width = 80;
335
+ canvas.height = 80;
336
+ const ctx = canvas.getContext('2d');
337
+
338
+ // Draw a sample character for animation
339
+ // Body
340
+ ctx.fillStyle = "#4CAF50";
341
+ ctx.beginPath();
342
+ ctx.arc(40, 50, 20, 0, Math.PI * 2);
343
+ ctx.fill();
344
+
345
+ // Stem
346
+ ctx.fillStyle = "#228B22";
347
+ ctx.fillRect(38, 50, 4, 20);
348
+
349
+ // Face
350
+ ctx.fillStyle = "#000";
351
+ ctx.beginPath();
352
+ ctx.arc(35, 45, 2, 0, Math.PI * 2);
353
+ ctx.arc(45, 45, 2, 0, Math.PI * 2);
354
+ ctx.fill();
355
+
356
+ ctx.beginPath();
357
+ ctx.arc(40, 50, 4, 0, Math.PI);
358
+ ctx.stroke();
359
+
360
+ // For walk animation, add some motion lines
361
+ if (anim.type === "walk-animation") {
362
+ ctx.strokeStyle = "#000";
363
+ ctx.beginPath();
364
+ ctx.moveTo(60, 70);
365
+ ctx.lineTo(70, 70);
366
+ ctx.stroke();
367
+
368
+ ctx.beginPath();
369
+ ctx.moveTo(65, 65);
370
+ ctx.lineTo(70, 70);
371
+ ctx.stroke();
372
+ }
373
+
374
+ // For attack animation, add some "attack" effect
375
+ if (anim.type === "attack-animation") {
376
+ ctx.fillStyle = "#FF6347";
377
+ ctx.beginPath();
378
+ ctx.arc(60, 40, 10, 0, Math.PI * 2);
379
+ ctx.fill();
380
+ }
381
+
382
+ const dataUrl = canvas.toDataURL();
383
+
384
+ const item = document.createElement('div');
385
+ item.className = 'grid-item bg-blue-50 rounded-lg p-4 flex flex-col items-center';
386
+ item.innerHTML = `
387
+ <img src="${dataUrl}" class="sprite ${anim.type} mb-3" alt="${anim.name} Animation">
388
+ <h4 class="font-bold text-blue-800">${anim.name} Animation</h4>
389
+ <p class="text-sm text-center text-gray-600 mt-1">Click "Generate" to see variations</p>
390
+ `;
391
+
392
+ container.appendChild(item);
393
+ });
394
+ }
395
+ </script>
396
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=LukasBe/procedural-character-spritesheet" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
397
+ </html>