pysolver33 commited on
Commit
63b58c1
Β·
verified Β·
1 Parent(s): b1e0f41

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +954 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Awesome Games
3
- emoji: πŸš€
4
- colorFrom: red
5
- colorTo: yellow
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: awesome-games
3
+ emoji: 🐳
4
+ colorFrom: purple
5
+ colorTo: blue
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,954 @@
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>AI Game Creator</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.min.js"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/tone@14.7.77/build/Tone.min.js"></script>
10
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
11
+ <style>
12
+ .gradient-bg {
13
+ background: linear-gradient(135deg, #6e8efb, #a777e3);
14
+ }
15
+ .game-canvas {
16
+ border-radius: 12px;
17
+ box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
18
+ background-color: #1a1a2e;
19
+ }
20
+ .prompt-input {
21
+ transition: all 0.3s ease;
22
+ }
23
+ .prompt-input:focus {
24
+ box-shadow: 0 0 0 3px rgba(167, 119, 227, 0.3);
25
+ }
26
+ .scaffold-card:hover {
27
+ transform: translateY(-5px);
28
+ box-shadow: 0 15px 30px rgba(0, 0, 0, 0.15);
29
+ }
30
+ .loading-dots::after {
31
+ content: '.';
32
+ animation: dots 1.5s steps(5, end) infinite;
33
+ }
34
+ @keyframes dots {
35
+ 0%, 20% { content: '.'; }
36
+ 40% { content: '..'; }
37
+ 60% { content: '...'; }
38
+ 80%, 100% { content: ''; }
39
+ }
40
+ .typewriter {
41
+ overflow: hidden;
42
+ border-right: 3px solid #a777e3;
43
+ white-space: nowrap;
44
+ margin: 0 auto;
45
+ letter-spacing: 2px;
46
+ animation: typing 3.5s steps(40, end), blink-caret 0.75s step-end infinite;
47
+ }
48
+ @keyframes typing {
49
+ from { width: 0 }
50
+ to { width: 100% }
51
+ }
52
+ @keyframes blink-caret {
53
+ from, to { border-color: transparent }
54
+ 50% { border-color: #a777e3; }
55
+ }
56
+ </style>
57
+ </head>
58
+ <body class="gradient-bg min-h-screen text-white">
59
+ <div class="container mx-auto px-4 py-12">
60
+ <!-- Header -->
61
+ <header class="text-center mb-12">
62
+ <h1 class="text-5xl font-bold mb-4 flex items-center justify-center">
63
+ <i class="fas fa-gamepad mr-4"></i>
64
+ <span class="typewriter">AI Game Creator</span>
65
+ </h1>
66
+ <p class="text-xl opacity-90 max-w-2xl mx-auto">
67
+ Describe your dream game and watch it come to life with AI magic!
68
+ </p>
69
+ </header>
70
+
71
+ <!-- Main Content -->
72
+ <div class="flex flex-col lg:flex-row gap-8">
73
+ <!-- Left Panel - Input & Scaffolds -->
74
+ <div class="w-full lg:w-1/3 space-y-6">
75
+ <!-- Prompt Input -->
76
+ <div class="bg-white/10 backdrop-blur-sm rounded-xl p-6 shadow-lg">
77
+ <h2 class="text-2xl font-semibold mb-4 flex items-center">
78
+ <i class="fas fa-lightbulb mr-2"></i> Game Concept
79
+ </h2>
80
+ <textarea
81
+ id="gamePrompt"
82
+ class="w-full h-32 px-4 py-3 rounded-lg bg-white/20 border border-white/30 text-white placeholder-white/50 prompt-input focus:outline-none"
83
+ placeholder="Describe your game idea... (e.g. 'A platformer where you play as a cat collecting fish while avoiding dogs')"></textarea>
84
+
85
+ <div class="mt-4 flex justify-between items-center">
86
+ <button id="generateBtn" class="bg-purple-600 hover:bg-purple-700 text-white font-bold py-3 px-6 rounded-lg transition flex items-center">
87
+ <i class="fas fa-magic mr-2"></i> Generate Game
88
+ </button>
89
+ <div id="loadingIndicator" class="hidden items-center text-sm">
90
+ <span class="loading-dots">Generating</span>
91
+ <i class="fas fa-spinner fa-spin ml-2"></i>
92
+ </div>
93
+ </div>
94
+ </div>
95
+
96
+ <!-- Scaffold Selection -->
97
+ <div class="bg-white/10 backdrop-blur-sm rounded-xl p-6 shadow-lg">
98
+ <h2 class="text-2xl font-semibold mb-4 flex items-center">
99
+ <i class="fas fa-layer-group mr-2"></i> Game Templates
100
+ </h2>
101
+ <div class="grid grid-cols-1 gap-4" id="scaffoldContainer">
102
+ <!-- Scaffold cards will be inserted here by JavaScript -->
103
+ </div>
104
+ </div>
105
+
106
+ <!-- Generated Code Preview -->
107
+ <div class="bg-white/10 backdrop-blur-sm rounded-xl p-6 shadow-lg">
108
+ <h2 class="text-2xl font-semibold mb-4 flex items-center">
109
+ <i class="fas fa-code mr-2"></i> Generated Code
110
+ </h2>
111
+ <div class="bg-gray-900 rounded-lg p-4 h-64 overflow-auto">
112
+ <pre id="generatedCode" class="text-sm text-green-400 font-mono">// Your generated game code will appear here...</pre>
113
+ </div>
114
+ </div>
115
+ </div>
116
+
117
+ <!-- Right Panel - Game Display -->
118
+ <div class="w-full lg:w-2/3">
119
+ <div class="bg-white/10 backdrop-blur-sm rounded-xl p-6 shadow-lg h-full">
120
+ <div class="flex justify-between items-center mb-4">
121
+ <h2 class="text-2xl font-semibold flex items-center">
122
+ <i class="fas fa-play-circle mr-2"></i> Game Preview
123
+ </h2>
124
+ <div class="flex space-x-2">
125
+ <button id="fullscreenBtn" class="bg-white/10 hover:bg-white/20 p-2 rounded-lg transition">
126
+ <i class="fas fa-expand"></i>
127
+ </button>
128
+ <button id="soundToggle" class="bg-white/10 hover:bg-white/20 p-2 rounded-lg transition">
129
+ <i class="fas fa-volume-up"></i>
130
+ </button>
131
+ </div>
132
+ </div>
133
+
134
+ <div id="gameContainer" class="game-canvas w-full h-[500px] flex items-center justify-center">
135
+ <div id="placeholderText" class="text-center p-8">
136
+ <i class="fas fa-gamepad text-5xl mb-4 opacity-30"></i>
137
+ <p class="text-xl opacity-50">Your AI-generated game will appear here</p>
138
+ </div>
139
+ </div>
140
+
141
+ <div class="mt-4 flex flex-wrap gap-2" id="gameControls">
142
+ <!-- Dynamic game controls will appear here -->
143
+ </div>
144
+ </div>
145
+ </div>
146
+ </div>
147
+ </div>
148
+
149
+ <script>
150
+ // Game Scaffolds Data
151
+ const scaffolds = [
152
+ {
153
+ id: 'platformer',
154
+ title: 'Platformer',
155
+ icon: 'fas fa-running',
156
+ description: 'Jump and run through levels with obstacles and enemies',
157
+ keywords: ['platform', 'jump', 'run', 'side-scroller', 'mario']
158
+ },
159
+ {
160
+ id: 'rhythm',
161
+ title: 'Rhythm Game',
162
+ icon: 'fas fa-music',
163
+ description: 'Hit notes to the beat of the music',
164
+ keywords: ['music', 'beat', 'dance', 'rhythm', 'sound']
165
+ },
166
+ {
167
+ id: 'puzzle',
168
+ title: 'Puzzle Game',
169
+ icon: 'fas fa-puzzle-piece',
170
+ description: 'Solve challenging puzzles to progress',
171
+ keywords: ['puzzle', 'solve', 'brain', 'logic', 'challenge']
172
+ },
173
+ {
174
+ id: 'shooter',
175
+ title: 'Shooter',
176
+ icon: 'fas fa-space-shuttle',
177
+ description: 'Shoot enemies and avoid projectiles',
178
+ keywords: ['shoot', 'space', 'bullet', 'enemy', 'arcade']
179
+ },
180
+ {
181
+ id: 'adventure',
182
+ title: 'Adventure',
183
+ icon: 'fas fa-map',
184
+ description: 'Explore a world and complete quests',
185
+ keywords: ['explore', 'quest', 'story', 'rpg', 'world']
186
+ },
187
+ {
188
+ id: 'racing',
189
+ title: 'Racing',
190
+ icon: 'fas fa-car',
191
+ description: 'Race against time or opponents',
192
+ keywords: ['race', 'speed', 'car', 'track', 'drive']
193
+ }
194
+ ];
195
+
196
+ // DOM Elements
197
+ const gamePrompt = document.getElementById('gamePrompt');
198
+ const generateBtn = document.getElementById('generateBtn');
199
+ const loadingIndicator = document.getElementById('loadingIndicator');
200
+ const scaffoldContainer = document.getElementById('scaffoldContainer');
201
+ const gameContainer = document.getElementById('gameContainer');
202
+ const placeholderText = document.getElementById('placeholderText');
203
+ const gameControls = document.getElementById('gameControls');
204
+ const generatedCode = document.getElementById('generatedCode');
205
+ const fullscreenBtn = document.getElementById('fullscreenBtn');
206
+ const soundToggle = document.getElementById('soundToggle');
207
+
208
+ // Current game state
209
+ let currentGame = null;
210
+ let selectedScaffold = null;
211
+ let isSoundOn = true;
212
+
213
+ // Initialize the app
214
+ function init() {
215
+ renderScaffoldCards();
216
+ setupEventListeners();
217
+ }
218
+
219
+ // Render scaffold selection cards
220
+ function renderScaffoldCards() {
221
+ scaffoldContainer.innerHTML = '';
222
+
223
+ scaffolds.forEach(scaffold => {
224
+ const card = document.createElement('div');
225
+ card.className = `bg-white/5 hover:bg-white/10 border border-white/10 rounded-lg p-4 cursor-pointer transition scaffold-card ${selectedScaffold?.id === scaffold.id ? 'border-purple-500 bg-purple-500/10' : ''}`;
226
+ card.innerHTML = `
227
+ <div class="flex items-center">
228
+ <div class="w-10 h-10 rounded-full bg-purple-600/30 flex items-center justify-center mr-3">
229
+ <i class="${scaffold.icon} text-purple-300"></i>
230
+ </div>
231
+ <div>
232
+ <h3 class="font-semibold">${scaffold.title}</h3>
233
+ <p class="text-sm opacity-80">${scaffold.description}</p>
234
+ </div>
235
+ </div>
236
+ `;
237
+
238
+ card.addEventListener('click', () => {
239
+ selectedScaffold = scaffold;
240
+ renderScaffoldCards();
241
+ updateUI();
242
+ });
243
+
244
+ scaffoldContainer.appendChild(card);
245
+ });
246
+ }
247
+
248
+ // Set up event listeners
249
+ function setupEventListeners() {
250
+ generateBtn.addEventListener('click', generateGame);
251
+ fullscreenBtn.addEventListener('click', toggleFullscreen);
252
+ soundToggle.addEventListener('click', toggleSound);
253
+
254
+ // Allow Enter key to trigger generation
255
+ gamePrompt.addEventListener('keydown', (e) => {
256
+ if (e.key === 'Enter' && !e.shiftKey) {
257
+ e.preventDefault();
258
+ generateGame();
259
+ }
260
+ });
261
+ }
262
+
263
+ // Generate game based on prompt and selected scaffold
264
+ async function generateGame() {
265
+ const prompt = gamePrompt.value.trim();
266
+
267
+ if (!prompt) {
268
+ showAlert('Please enter a game description', 'error');
269
+ return;
270
+ }
271
+
272
+ if (!selectedScaffold) {
273
+ showAlert('Please select a game template', 'error');
274
+ return;
275
+ }
276
+
277
+ // Show loading state
278
+ generateBtn.disabled = true;
279
+ loadingIndicator.classList.remove('hidden');
280
+
281
+ try {
282
+ // In a real app, this would call your backend API
283
+ // For this demo, we'll simulate the API call
284
+ const gameData = await simulateLLMGeneration(prompt, selectedScaffold);
285
+
286
+ // Create the game
287
+ createGame(gameData);
288
+
289
+ // Update the code preview
290
+ generatedCode.textContent = gameData.code || '// No code generated';
291
+
292
+ showAlert('Game generated successfully!', 'success');
293
+ } catch (error) {
294
+ console.error('Error generating game:', error);
295
+ showAlert('Failed to generate game. Please try again.', 'error');
296
+ } finally {
297
+ // Hide loading state
298
+ generateBtn.disabled = false;
299
+ loadingIndicator.classList.add('hidden');
300
+ }
301
+ }
302
+
303
+ // Simulate LLM generation (in a real app, this would be an API call)
304
+ async function simulateLLMGeneration(prompt, scaffold) {
305
+ // Simulate network delay
306
+ await new Promise(resolve => setTimeout(resolve, 2000));
307
+
308
+ // Generate mock game data based on scaffold type
309
+ let gameData = {
310
+ scaffold: scaffold.id,
311
+ prompt: prompt,
312
+ code: generateMockCode(scaffold.id, prompt),
313
+ config: {}
314
+ };
315
+
316
+ // Add scaffold-specific config
317
+ switch (scaffold.id) {
318
+ case 'platformer':
319
+ gameData.config = {
320
+ player: { speed: 300, jumpForce: 600 },
321
+ platforms: generatePlatforms(10),
322
+ enemies: generateEnemies(3),
323
+ collectibles: generateCollectibles(5)
324
+ };
325
+ break;
326
+ case 'rhythm':
327
+ gameData.config = {
328
+ bpm: 120,
329
+ notes: generateNotes(16),
330
+ difficulty: 'medium'
331
+ };
332
+ break;
333
+ case 'puzzle':
334
+ gameData.config = {
335
+ gridSize: 8,
336
+ pieces: generatePuzzlePieces(6),
337
+ movesAllowed: 20
338
+ };
339
+ break;
340
+ case 'shooter':
341
+ gameData.config = {
342
+ player: { speed: 400, fireRate: 500 },
343
+ enemies: generateSpaceEnemies(5),
344
+ powerups: generatePowerups(2)
345
+ };
346
+ break;
347
+ case 'adventure':
348
+ gameData.config = {
349
+ worldSize: { width: 10, height: 10 },
350
+ npcs: generateNPCs(3),
351
+ items: generateAdventureItems(4)
352
+ };
353
+ break;
354
+ case 'racing':
355
+ gameData.config = {
356
+ track: generateTrack(),
357
+ opponents: 3,
358
+ laps: 3
359
+ };
360
+ break;
361
+ }
362
+
363
+ return gameData;
364
+ }
365
+
366
+ // Generate mock code for preview
367
+ function generateMockCode(scaffoldId, prompt) {
368
+ const codeSnippets = {
369
+ platformer: `// Platformer game based on: "${prompt}"
370
+ const config = {
371
+ type: Phaser.AUTO,
372
+ width: 800,
373
+ height: 600,
374
+ physics: {
375
+ default: 'arcade',
376
+ arcade: { gravity: { y: 300 }, debug: false }
377
+ },
378
+ scene: {
379
+ preload: function() {
380
+ // Load assets here
381
+ },
382
+ create: function() {
383
+ // Create player, platforms, enemies
384
+ this.player = this.physics.add.sprite(100, 450, 'player');
385
+ this.player.setCollideWorldBounds(true);
386
+
387
+ // Generated platforms
388
+ const platforms = this.physics.add.staticGroup();
389
+ platforms.create(400, 568, 'ground').setScale(2).refreshBody();
390
+
391
+ // Physics
392
+ this.physics.add.collider(this.player, platforms);
393
+ },
394
+ update: function() {
395
+ // Game loop
396
+ }
397
+ }
398
+ };
399
+
400
+ const game = new Phaser.Game(config);`,
401
+ rhythm: `// Rhythm game based on: "${prompt}"
402
+ const synth = new Tone.Synth().toDestination();
403
+ const notes = ['C4', 'D4', 'E4', 'F4', 'G4'];
404
+ let currentNote = 0;
405
+
406
+ function setupGame() {
407
+ // Create note targets
408
+ const container = document.getElementById('gameContainer');
409
+ notes.forEach((note, i) => {
410
+ const noteEl = document.createElement('div');
411
+ noteEl.className = 'note-target';
412
+ noteEl.style.left = \`\${(i + 1) * 15}%\`;
413
+ noteEl.dataset.note = note;
414
+ container.appendChild(noteEl);
415
+ });
416
+
417
+ // Start music
418
+ Tone.Transport.bpm.value = 120;
419
+ Tone.Transport.scheduleRepeat(time => {
420
+ synth.triggerAttackRelease(notes[currentNote], "8n", time);
421
+ currentNote = (currentNote + 1) % notes.length;
422
+ }, "8n");
423
+
424
+ Tone.Transport.start();
425
+ }`,
426
+ puzzle: `// Puzzle game based on: "${prompt}"
427
+ class PuzzleGame {
428
+ constructor() {
429
+ this.gridSize = 8;
430
+ this.pieces = [];
431
+ this.selectedPiece = null;
432
+
433
+ this.initBoard();
434
+ }
435
+
436
+ initBoard() {
437
+ // Generate random puzzle pieces
438
+ for (let i = 0; i < this.gridSize; i++) {
439
+ this.pieces[i] = [];
440
+ for (let j = 0; j < this.gridSize; j++) {
441
+ this.pieces[i][j] = {
442
+ type: Math.floor(Math.random() * 6),
443
+ x: i,
444
+ y: j
445
+ };
446
+ }
447
+ }
448
+
449
+ this.render();
450
+ }
451
+
452
+ render() {
453
+ // Draw the puzzle board
454
+ const container = document.getElementById('gameContainer');
455
+ container.innerHTML = '';
456
+
457
+ this.pieces.forEach(row => {
458
+ row.forEach(piece => {
459
+ const pieceEl = document.createElement('div');
460
+ pieceEl.className = \`puzzle-piece type-\${piece.type}\`;
461
+ pieceEl.dataset.x = piece.x;
462
+ pieceEl.dataset.y = piece.y;
463
+ container.appendChild(pieceEl);
464
+ });
465
+ });
466
+ }
467
+ }`
468
+ };
469
+
470
+ return codeSnippets[scaffoldId] || '// No template found for this game type';
471
+ }
472
+
473
+ // Create the actual game
474
+ function createGame(gameData) {
475
+ // Clear previous game if exists
476
+ if (currentGame) {
477
+ if (currentGame instanceof Phaser.Game) {
478
+ currentGame.destroy(true);
479
+ } else if (typeof currentGame.cleanup === 'function') {
480
+ currentGame.cleanup();
481
+ }
482
+ currentGame = null;
483
+ }
484
+
485
+ // Hide placeholder
486
+ placeholderText.style.display = 'none';
487
+
488
+ // Create game based on scaffold type
489
+ switch (gameData.scaffold) {
490
+ case 'platformer':
491
+ createPlatformerGame(gameData);
492
+ break;
493
+ case 'rhythm':
494
+ createRhythmGame(gameData);
495
+ break;
496
+ case 'puzzle':
497
+ createPuzzleGame(gameData);
498
+ break;
499
+ default:
500
+ // For other types, just show a placeholder
501
+ placeholderText.style.display = 'block';
502
+ placeholderText.innerHTML = `
503
+ <i class="fas fa-gamepad text-5xl mb-4 opacity-30"></i>
504
+ <p class="text-xl opacity-50">Preview not available for ${selectedScaffold.title} template</p>
505
+ <p class="text-sm opacity-30 mt-2">Check the code tab to see the generated code</p>
506
+ `;
507
+ }
508
+
509
+ // Update game controls
510
+ updateGameControls(gameData.scaffold);
511
+ }
512
+
513
+ // Create a platformer game
514
+ function createPlatformerGame(gameData) {
515
+ const config = {
516
+ type: Phaser.AUTO,
517
+ width: gameContainer.clientWidth,
518
+ height: gameContainer.clientHeight,
519
+ physics: {
520
+ default: 'arcade',
521
+ arcade: {
522
+ gravity: { y: 300 },
523
+ debug: false
524
+ }
525
+ },
526
+ parent: 'gameContainer',
527
+ scene: {
528
+ preload: preload,
529
+ create: create,
530
+ update: update
531
+ }
532
+ };
533
+
534
+ currentGame = new Phaser.Game(config);
535
+
536
+ function preload() {
537
+ // Load assets (in a real app, these would be generated or selected based on prompt)
538
+ this.load.image('sky', 'https://labs.phaser.io/assets/skies/space3.png');
539
+ this.load.image('ground', 'https://labs.phaser.io/assets/platform.png');
540
+ this.load.image('star', 'https://labs.phaser.io/assets/sprites/star.png');
541
+ this.load.spritesheet('dude', 'https://labs.phaser.io/assets/sprites/dude.png', {
542
+ frameWidth: 32, frameHeight: 48
543
+ });
544
+ }
545
+
546
+ function create() {
547
+ // Add background
548
+ this.add.image(400, 300, 'sky').setDisplaySize(config.width, config.height);
549
+
550
+ // Platforms
551
+ const platforms = this.physics.add.staticGroup();
552
+
553
+ // Ground
554
+ platforms.create(400, 568, 'ground').setScale(2).refreshBody();
555
+
556
+ // Additional platforms
557
+ platforms.create(600, 400, 'ground');
558
+ platforms.create(50, 250, 'ground');
559
+ platforms.create(750, 220, 'ground');
560
+
561
+ // Player
562
+ const player = this.physics.add.sprite(100, 450, 'dude');
563
+ player.setBounce(0.2);
564
+ player.setCollideWorldBounds(true);
565
+
566
+ // Animation
567
+ this.anims.create({
568
+ key: 'left',
569
+ frames: this.anims.generateFrameNumbers('dude', { start: 0, end: 3 }),
570
+ frameRate: 10,
571
+ repeat: -1
572
+ });
573
+
574
+ this.anims.create({
575
+ key: 'turn',
576
+ frames: [ { key: 'dude', frame: 4 } ],
577
+ frameRate: 20
578
+ });
579
+
580
+ this.anims.create({
581
+ key: 'right',
582
+ frames: this.anims.generateFrameNumbers('dude', { start: 5, end: 8 }),
583
+ frameRate: 10,
584
+ repeat: -1
585
+ });
586
+
587
+ // Stars
588
+ const stars = this.physics.add.group({
589
+ key: 'star',
590
+ repeat: 11,
591
+ setXY: { x: 12, y: 0, stepX: 70 }
592
+ });
593
+
594
+ stars.children.iterate(function (child) {
595
+ child.setBounceY(Phaser.Math.FloatBetween(0.4, 0.8));
596
+ });
597
+
598
+ // Physics
599
+ this.physics.add.collider(player, platforms);
600
+ this.physics.add.collider(stars, platforms);
601
+ this.physics.add.overlap(player, stars, collectStar, null, this);
602
+
603
+ // Input
604
+ this.cursors = this.input.keyboard.createCursorKeys();
605
+
606
+ // Score
607
+ this.score = 0;
608
+ this.scoreText = this.add.text(16, 16, 'Score: 0', {
609
+ fontSize: '32px',
610
+ fill: '#fff',
611
+ fontFamily: 'Arial'
612
+ });
613
+
614
+ function collectStar(player, star) {
615
+ star.disableBody(true, true);
616
+
617
+ this.score += 10;
618
+ this.scoreText.setText('Score: ' + this.score);
619
+
620
+ // Play sound if enabled
621
+ if (isSoundOn) {
622
+ const synth = new Tone.Synth().toDestination();
623
+ synth.triggerAttackRelease("C5", "8n");
624
+ }
625
+ }
626
+ }
627
+
628
+ function update() {
629
+ const cursors = this.cursors;
630
+ const player = this.physics.world.bodies.entries[0].gameObject;
631
+
632
+ if (cursors.left.isDown) {
633
+ player.setVelocityX(-160);
634
+ player.anims.play('left', true);
635
+ } else if (cursors.right.isDown) {
636
+ player.setVelocityX(160);
637
+ player.anims.play('right', true);
638
+ } else {
639
+ player.setVelocityX(0);
640
+ player.anims.play('turn');
641
+ }
642
+
643
+ if (cursors.up.isDown && player.body.touching.down) {
644
+ player.setVelocityY(-330);
645
+ }
646
+ }
647
+ }
648
+
649
+ // Create a rhythm game
650
+ function createRhythmGame(gameData) {
651
+ // Clear container
652
+ gameContainer.innerHTML = '';
653
+
654
+ // Create note targets
655
+ const notes = ['C', 'D', 'E', 'F', 'G'];
656
+ const colors = ['#FF5252', '#FFD740', '#69F0AE', '#40C4FF', '#E040FB'];
657
+
658
+ notes.forEach((note, i) => {
659
+ const noteEl = document.createElement('div');
660
+ noteEl.className = 'w-16 h-16 rounded-full flex items-center justify-center text-white font-bold cursor-pointer transition-transform hover:scale-110';
661
+ noteEl.style.backgroundColor = colors[i];
662
+ noteEl.style.position = 'absolute';
663
+ noteEl.style.left = `${(i + 1) * 15}%`;
664
+ noteEl.style.top = '50%';
665
+ noteEl.style.transform = 'translate(-50%, -50%)';
666
+ noteEl.textContent = note;
667
+ noteEl.dataset.note = `${note}4`;
668
+
669
+ noteEl.addEventListener('click', () => {
670
+ if (isSoundOn) {
671
+ const synth = new Tone.Synth().toDestination();
672
+ synth.triggerAttackRelease(noteEl.dataset.note, "8n");
673
+ }
674
+ noteEl.style.transform = 'translate(-50%, -50%) scale(1.2)';
675
+ setTimeout(() => {
676
+ noteEl.style.transform = 'translate(-50%, -50%) scale(1)';
677
+ }, 200);
678
+ });
679
+
680
+ gameContainer.appendChild(noteEl);
681
+ });
682
+
683
+ // Add visualizer
684
+ const visualizer = document.createElement('div');
685
+ visualizer.className = 'w-full h-2 bg-white/20 rounded-full absolute bottom-8 left-0';
686
+ visualizer.style.overflow = 'hidden';
687
+
688
+ const progress = document.createElement('div');
689
+ progress.className = 'h-full bg-purple-500 rounded-full';
690
+ progress.style.width = '0%';
691
+ progress.style.transition = 'width 0.1s linear';
692
+ visualizer.appendChild(progress);
693
+
694
+ gameContainer.appendChild(visualizer);
695
+
696
+ // Start music if sound is on
697
+ if (isSoundOn) {
698
+ const synth = new Tone.Synth().toDestination();
699
+ const notes = ['C4', 'D4', 'E4', 'F4', 'G4'];
700
+ let currentNote = 0;
701
+
702
+ Tone.Transport.bpm.value = 120;
703
+ Tone.Transport.scheduleRepeat(time => {
704
+ synth.triggerAttackRelease(notes[currentNote], "8n", time);
705
+ currentNote = (currentNote + 1) % notes.length;
706
+
707
+ // Update visualizer
708
+ progress.style.width = `${(currentNote / notes.length) * 100}%`;
709
+ }, "8n");
710
+
711
+ Tone.Transport.start();
712
+ }
713
+
714
+ currentGame = {
715
+ cleanup: () => {
716
+ Tone.Transport.cancel();
717
+ Tone.Transport.stop();
718
+ }
719
+ };
720
+ }
721
+
722
+ // Create a puzzle game
723
+ function createPuzzleGame(gameData) {
724
+ // Clear container
725
+ gameContainer.innerHTML = '';
726
+
727
+ // Create puzzle board
728
+ const boardSize = 4;
729
+ const pieceSize = gameContainer.clientWidth / boardSize - 10;
730
+
731
+ // Create pieces
732
+ for (let i = 0; i < boardSize * boardSize; i++) {
733
+ const piece = document.createElement('div');
734
+ piece.className = 'absolute bg-white/20 border border-white/30 rounded-lg cursor-pointer transition-all hover:bg-white/30';
735
+ piece.style.width = `${pieceSize}px`;
736
+ piece.style.height = `${pieceSize}px`;
737
+ piece.style.left = `${(i % boardSize) * (pieceSize + 10)}px`;
738
+ piece.style.top = `${Math.floor(i / boardSize) * (pieceSize + 10)}px`;
739
+
740
+ // Random color
741
+ const hue = Math.floor(Math.random() * 360);
742
+ piece.style.backgroundColor = `hsla(${hue}, 80%, 60%, 0.7)`;
743
+
744
+ piece.addEventListener('click', () => {
745
+ piece.style.transform = 'scale(0.95) rotate(5deg)';
746
+ setTimeout(() => {
747
+ piece.style.transform = '';
748
+ }, 200);
749
+
750
+ if (isSoundOn) {
751
+ const note = ['C4', 'E4', 'G4', 'C5'][Math.floor(Math.random() * 4)];
752
+ const synth = new Tone.Synth().toDestination();
753
+ synth.triggerAttackRelease(note, "8n");
754
+ }
755
+ });
756
+
757
+ gameContainer.appendChild(piece);
758
+ }
759
+
760
+ currentGame = {
761
+ cleanup: () => {
762
+ // No special cleanup needed
763
+ }
764
+ };
765
+ }
766
+
767
+ // Update game controls based on game type
768
+ function updateGameControls(gameType) {
769
+ gameControls.innerHTML = '';
770
+
771
+ const controls = {
772
+ platformer: [
773
+ { label: 'Left/Right', keys: '← β†’', desc: 'Move player' },
774
+ { label: 'Jump', keys: '↑', desc: 'Jump' }
775
+ ],
776
+ rhythm: [
777
+ { label: 'Tap', keys: 'Click', desc: 'Hit notes' }
778
+ ],
779
+ puzzle: [
780
+ { label: 'Select', keys: 'Click', desc: 'Select pieces' }
781
+ ],
782
+ default: [
783
+ { label: 'No controls', desc: 'This game type has no interactive controls' }
784
+ ]
785
+ };
786
+
787
+ const currentControls = controls[gameType] || controls.default;
788
+
789
+ currentControls.forEach(control => {
790
+ const controlEl = document.createElement('div');
791
+ controlEl.className = 'bg-white/10 rounded-lg px-4 py-2 flex items-center';
792
+
793
+ const keysEl = document.createElement('div');
794
+ keysEl.className = 'bg-purple-600 rounded px-2 py-1 mr-3 font-mono text-sm';
795
+ keysEl.textContent = control.keys || '';
796
+
797
+ const textEl = document.createElement('div');
798
+ textEl.className = 'text-sm';
799
+ textEl.innerHTML = `<span class="font-semibold">${control.label}</span>: ${control.desc}`;
800
+
801
+ if (control.keys) {
802
+ controlEl.appendChild(keysEl);
803
+ }
804
+ controlEl.appendChild(textEl);
805
+
806
+ gameControls.appendChild(controlEl);
807
+ });
808
+ }
809
+
810
+ // Toggle fullscreen mode
811
+ function toggleFullscreen() {
812
+ if (!document.fullscreenElement) {
813
+ gameContainer.requestFullscreen().catch(err => {
814
+ console.error('Error attempting to enable fullscreen:', err);
815
+ });
816
+ } else {
817
+ document.exitFullscreen();
818
+ }
819
+ }
820
+
821
+ // Toggle sound on/off
822
+ function toggleSound() {
823
+ isSoundOn = !isSoundOn;
824
+ soundToggle.innerHTML = isSoundOn ? '<i class="fas fa-volume-up"></i>' : '<i class="fas fa-volume-mute"></i>';
825
+
826
+ if (isSoundOn && currentGame && selectedScaffold?.id === 'rhythm') {
827
+ // Restart music if it's a rhythm game
828
+ createGame({ scaffold: 'rhythm' });
829
+ }
830
+ }
831
+
832
+ // Show alert message
833
+ function showAlert(message, type) {
834
+ const alert = document.createElement('div');
835
+ alert.className = `fixed top-4 right-4 px-6 py-3 rounded-lg shadow-lg z-50 transition-all ${
836
+ type === 'error' ? 'bg-red-500' : 'bg-green-500'
837
+ }`;
838
+ alert.textContent = message;
839
+
840
+ document.body.appendChild(alert);
841
+
842
+ setTimeout(() => {
843
+ alert.style.opacity = '0';
844
+ setTimeout(() => {
845
+ alert.remove();
846
+ }, 300);
847
+ }, 3000);
848
+ }
849
+
850
+ // Helper functions for mock data generation
851
+ function generatePlatforms(count) {
852
+ return Array.from({ length: count }, (_, i) => ({
853
+ x: Math.floor(Math.random() * 700) + 50,
854
+ y: Math.floor(Math.random() * 400) + 100,
855
+ width: Math.floor(Math.random() * 200) + 50
856
+ }));
857
+ }
858
+
859
+ function generateEnemies(count) {
860
+ return Array.from({ length: count }, (_, i) => ({
861
+ type: ['dog', 'ghost', 'spider'][Math.floor(Math.random() * 3)],
862
+ x: Math.floor(Math.random() * 700) + 50,
863
+ speed: Math.floor(Math.random() * 100) + 50,
864
+ patrol: Math.random() > 0.5 ? 'left-right' : 'up-down'
865
+ }));
866
+ }
867
+
868
+ function generateCollectibles(count) {
869
+ return Array.from({ length: count }, (_, i) => ({
870
+ type: ['coin', 'gem', 'star'][Math.floor(Math.random() * 3)],
871
+ x: Math.floor(Math.random() * 700) + 50,
872
+ y: Math.floor(Math.random() * 500) + 50,
873
+ value: Math.floor(Math.random() * 5) + 1
874
+ }));
875
+ }
876
+
877
+ function generateNotes(count) {
878
+ return Array.from({ length: count }, (_, i) => ({
879
+ time: i * 0.5,
880
+ note: ['C', 'D', 'E', 'F', 'G'][Math.floor(Math.random() * 5)],
881
+ duration: 0.25
882
+ }));
883
+ }
884
+
885
+ function generatePuzzlePieces(count) {
886
+ return Array.from({ length: count }, (_, i) => ({
887
+ type: i,
888
+ color: `hsl(${Math.floor(Math.random() * 360)}, 80%, 60%)`,
889
+ shape: ['circle', 'square', 'triangle'][Math.floor(Math.random() * 3)]
890
+ }));
891
+ }
892
+
893
+ function generateSpaceEnemies(count) {
894
+ return Array.from({ length: count }, (_, i) => ({
895
+ type: ['alien', 'asteroid', 'ufo'][Math.floor(Math.random() * 3)],
896
+ health: Math.floor(Math.random() * 3) + 1,
897
+ speed: Math.floor(Math.random() * 150) + 50,
898
+ pattern: ['straight', 'zigzag', 'circle'][Math.floor(Math.random() * 3)]
899
+ }));
900
+ }
901
+
902
+ function generatePowerups(count) {
903
+ return Array.from({ length: count }, (_, i) => ({
904
+ type: ['shield', 'speed', 'multishot'][Math.floor(Math.random() * 3)],
905
+ duration: Math.floor(Math.random() * 5) + 3
906
+ }));
907
+ }
908
+
909
+ function generateNPCs(count) {
910
+ return Array.from({ length: count }, (_, i) => ({
911
+ name: ['Wizard', 'Merchant', 'Guard'][Math.floor(Math.random() * 3)],
912
+ dialogue: [
913
+ 'Hello adventurer!',
914
+ 'Have you seen my lost treasure?',
915
+ 'Beware of the dragon!'
916
+ ][Math.floor(Math.random() * 3)],
917
+ quest: Math.random() > 0.5
918
+ }));
919
+ }
920
+
921
+ function generateAdventureItems(count) {
922
+ return Array.from({ length: count }, (_, i) => ({
923
+ name: ['Sword', 'Potion', 'Key', 'Map'][Math.floor(Math.random() * 4)],
924
+ description: [
925
+ 'A sharp blade for combat',
926
+ 'Restores health when consumed',
927
+ 'Opens locked doors',
928
+ 'Shows hidden locations'
929
+ ][Math.floor(Math.random() * 4)]
930
+ }));
931
+ }
932
+
933
+ function generateTrack() {
934
+ return {
935
+ length: Math.floor(Math.random() * 5) + 3,
936
+ turns: ['sharp', 'wide', 's-curve'][Math.floor(Math.random() * 3)],
937
+ obstacles: Math.floor(Math.random() * 10)
938
+ };
939
+ }
940
+
941
+ // Update UI based on current state
942
+ function updateUI() {
943
+ // Update generate button state
944
+ generateBtn.disabled = !gamePrompt.value.trim() || !selectedScaffold;
945
+ }
946
+
947
+ // Initialize the app when DOM is loaded
948
+ document.addEventListener('DOMContentLoaded', init);
949
+
950
+ // Update UI when prompt changes
951
+ gamePrompt.addEventListener('input', updateUI);
952
+ </script>
953
+ <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=pysolver33/awesome-games" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
954
+ </html>