Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -312,46 +312,63 @@ def _inject_sprites(html_code: str, sprite_map: dict) -> str:
|
|
| 312 |
CODE_SYSTEM = (
|
| 313 |
"You are an expert HTML5 game developer. "
|
| 314 |
"Write a complete, working, single-file HTML5 game using canvas and vanilla JavaScript. "
|
| 315 |
-
"CRITICAL RULES - follow every one exactly: "
|
| 316 |
-
"1. Declare
|
| 317 |
" const playerImg = new Image(); playerImg.src = 'sprite_player.png'; "
|
| 318 |
" const bgImg = new Image(); bgImg.src = 'sprite_background.png'; "
|
| 319 |
" const enemyImg = new Image(); enemyImg.src = 'sprite_enemy.png'; "
|
| 320 |
" const keys = new Set(); "
|
| 321 |
-
"
|
|
|
|
|
|
|
| 322 |
" function loadImg(img) { return new Promise(r => { img.onload = r; }); } "
|
| 323 |
" Promise.all([loadImg(playerImg), loadImg(bgImg), loadImg(enemyImg)]).then(startGame); "
|
| 324 |
-
"3.
|
| 325 |
" function startGame() { "
|
| 326 |
-
"
|
| 327 |
-
"
|
| 328 |
-
"
|
| 329 |
-
"
|
| 330 |
-
"4. Define
|
| 331 |
-
"5. FOR TOP-DOWN SHOOTER -
|
| 332 |
-
"
|
| 333 |
-
"
|
| 334 |
-
"
|
| 335 |
-
"
|
| 336 |
-
"
|
| 337 |
-
"
|
| 338 |
-
"
|
| 339 |
-
"
|
| 340 |
-
"
|
| 341 |
-
"
|
| 342 |
-
"
|
| 343 |
-
"
|
| 344 |
-
"
|
| 345 |
-
"
|
| 346 |
-
"
|
| 347 |
-
"
|
| 348 |
-
"
|
| 349 |
-
"
|
| 350 |
-
"
|
| 351 |
-
"
|
| 352 |
-
"
|
| 353 |
-
"
|
| 354 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 355 |
)
|
| 356 |
|
| 357 |
def generate_game_code(game_type: str, theme: str, temperature: float, max_new_tokens: int):
|
|
|
|
| 312 |
CODE_SYSTEM = (
|
| 313 |
"You are an expert HTML5 game developer. "
|
| 314 |
"Write a complete, working, single-file HTML5 game using canvas and vanilla JavaScript. "
|
| 315 |
+
"CRITICAL RULES - follow every one exactly, copy the patterns EXACTLY as written: "
|
| 316 |
+
"1. Declare at the very top of script: "
|
| 317 |
" const playerImg = new Image(); playerImg.src = 'sprite_player.png'; "
|
| 318 |
" const bgImg = new Image(); bgImg.src = 'sprite_background.png'; "
|
| 319 |
" const enemyImg = new Image(); enemyImg.src = 'sprite_enemy.png'; "
|
| 320 |
" const keys = new Set(); "
|
| 321 |
+
" const bullets = []; "
|
| 322 |
+
" const enemies = []; "
|
| 323 |
+
"2. Use Promise.all to wait for images: "
|
| 324 |
" function loadImg(img) { return new Promise(r => { img.onload = r; }); } "
|
| 325 |
" Promise.all([loadImg(playerImg), loadImg(bgImg), loadImg(enemyImg)]).then(startGame); "
|
| 326 |
+
"3. startGame() MUST look exactly like this: "
|
| 327 |
" function startGame() { "
|
| 328 |
+
" window.addEventListener('keydown', e => keys.add(e.key)); "
|
| 329 |
+
" window.addEventListener('keyup', e => keys.delete(e.key)); "
|
| 330 |
+
" canvas.addEventListener('click', onShoot); "
|
| 331 |
+
" requestAnimationFrame(gameLoop); } "
|
| 332 |
+
"4. Define ALL functions at TOP LEVEL not inside startGame or .then(). "
|
| 333 |
+
"5. FOR TOP-DOWN SHOOTER ONLY - copy this EXACT player setup and movement: "
|
| 334 |
+
" let player = {x: canvas.width/2 - 24, y: canvas.height/2 - 24, w: 48, h: 48, speed: 4}; "
|
| 335 |
+
" Inside gameLoop() move player like this EXACTLY: "
|
| 336 |
+
" if (keys.has('w') || keys.has('W') || keys.has('ArrowUp')) { player.y -= player.speed; } "
|
| 337 |
+
" if (keys.has('s') || keys.has('S') || keys.has('ArrowDown')) { player.y += player.speed; } "
|
| 338 |
+
" if (keys.has('a') || keys.has('A') || keys.has('ArrowLeft')) { player.x -= player.speed; } "
|
| 339 |
+
" if (keys.has('d') || keys.has('D') || keys.has('ArrowRight')) { player.x += player.speed; } "
|
| 340 |
+
" player.x = Math.max(0, Math.min(canvas.width - player.w, player.x)); "
|
| 341 |
+
" player.y = Math.max(0, Math.min(canvas.height - player.h, player.y)); "
|
| 342 |
+
"6. FOR TOP-DOWN SHOOTER ONLY - bullet fires on MOUSE CLICK, travels straight UP: "
|
| 343 |
+
" function onShoot(e) { "
|
| 344 |
+
" bullets.push({x: player.x + player.w/2 - 4, y: player.y - 16, w: 8, h: 16, vy: -10}); } "
|
| 345 |
+
" Inside gameLoop() update bullets: "
|
| 346 |
+
" for (let i = bullets.length-1; i >= 0; i--) { "
|
| 347 |
+
" bullets[i].y += bullets[i].vy; "
|
| 348 |
+
" ctx.fillStyle='yellow'; ctx.fillRect(bullets[i].x, bullets[i].y, 8, 16); "
|
| 349 |
+
" if (bullets[i].y + 16 < 0) { bullets.splice(i, 1); continue; } "
|
| 350 |
+
" for check enemy collision and remove both bullet and enemy if hit } "
|
| 351 |
+
"7. FOR TOP-DOWN SHOOTER ONLY - enemies spawn every 120 FRAMES (use a frameCount variable): "
|
| 352 |
+
" let frameCount = 0; "
|
| 353 |
+
" Inside gameLoop(): frameCount++; "
|
| 354 |
+
" if (frameCount % 120 === 0) spawn ONE new enemy at random x, y=0. "
|
| 355 |
+
" Enemy size 32x32, speed 1.5. Draw with ctx.drawImage(enemyImg, e.x, e.y, 32, 32). "
|
| 356 |
+
" Each frame: e.y += e.speed. Remove enemy if e.y > canvas.height. "
|
| 357 |
+
" If enemy overlaps player: health -= 1, remove enemy. "
|
| 358 |
+
"8. FOR TOP-DOWN SHOOTER ONLY - RESTART: "
|
| 359 |
+
" function reset() { "
|
| 360 |
+
" player.x = canvas.width/2-24; player.y = canvas.height/2-24; "
|
| 361 |
+
" bullets.length=0; enemies.length=0; "
|
| 362 |
+
" score=0; health=3; frameCount=0; "
|
| 363 |
+
" requestAnimationFrame(gameLoop); } "
|
| 364 |
+
" When health <= 0: stop loop, draw GAME OVER text on canvas, "
|
| 365 |
+
" draw a clickable RESTART button on canvas, "
|
| 366 |
+
" add ONE-TIME canvas click listener that calls reset() and removes itself. "
|
| 367 |
+
"9. FOR PLATFORMER ONLY: gravity velY+=0.5, jump ArrowUp/W/Space velY=-12 when grounded. "
|
| 368 |
+
" Set grounded=false BEFORE platform loop. Set grounded=true and velY=0 only on landing. "
|
| 369 |
+
" Always include full-width ground platform at y=420. "
|
| 370 |
+
"10. Draw bgImg FIRST each frame: ctx.drawImage(bgImg, 0, 0, canvas.width, canvas.height). "
|
| 371 |
+
"Output ONLY the raw HTML - no markdown fences, no explanation."
|
| 372 |
)
|
| 373 |
|
| 374 |
def generate_game_code(game_type: str, theme: str, temperature: float, max_new_tokens: int):
|