Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -158,49 +158,49 @@ THEME_EXAMPLES = {
|
|
| 158 |
def generate_image_prompts(theme: str, game_type: str) -> dict:
|
| 159 |
client = get_groq_client()
|
| 160 |
if game_type == "Top-Down Shooter":
|
| 161 |
-
|
| 162 |
-
char_style
|
| 163 |
-
"
|
| 164 |
-
"character seen from above looking down,
|
| 165 |
-
"
|
|
|
|
| 166 |
)
|
| 167 |
else:
|
| 168 |
-
|
| 169 |
-
char_style
|
| 170 |
-
"2D side-view platformer sprite, character facing right, "
|
| 171 |
-
"full body visible from the side
|
| 172 |
-
"
|
|
|
|
| 173 |
)
|
| 174 |
|
| 175 |
seeds = {
|
| 176 |
"sprite_player.png": (
|
| 177 |
-
f"
|
| 178 |
-
f"
|
| 179 |
-
f"
|
| 180 |
-
f"single character only, no scenery no environment"
|
| 181 |
),
|
| 182 |
"sprite_background.png": (
|
| 183 |
-
f"
|
| 184 |
-
f"wide
|
| 185 |
f"no characters no sprites, environment only"
|
| 186 |
),
|
| 187 |
"sprite_enemy.png": (
|
| 188 |
-
f"
|
| 189 |
-
f"menacing
|
| 190 |
-
f"
|
| 191 |
-
f"single enemy only, no scenery no environment"
|
| 192 |
),
|
| 193 |
}
|
| 194 |
if game_type == "Platformer":
|
| 195 |
seeds["sprite_platform.png"] = (
|
| 196 |
-
f"pixel-art
|
| 197 |
-
f"rectangular
|
| 198 |
-
f"
|
| 199 |
)
|
| 200 |
seeds["sprite_goal.png"] = (
|
| 201 |
-
f"pixel-art
|
| 202 |
-
f"glowing
|
| 203 |
-
f"
|
| 204 |
)
|
| 205 |
prompts = {}
|
| 206 |
for sprite_name, seed in seeds.items():
|
|
@@ -312,7 +312,7 @@ 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: "
|
| 316 |
"1. Declare sprites at the very top of the script BEFORE anything else: "
|
| 317 |
" const playerImg = new Image(); playerImg.src = 'sprite_player.png'; "
|
| 318 |
" const bgImg = new Image(); bgImg.src = 'sprite_background.png'; "
|
|
@@ -321,31 +321,36 @@ CODE_SYSTEM = (
|
|
| 321 |
"2. Use Promise.all to wait for ALL images before starting: "
|
| 322 |
" function loadImg(img) { return new Promise(r => { img.onload = r; }); } "
|
| 323 |
" Promise.all([loadImg(playerImg), loadImg(bgImg), loadImg(enemyImg)]).then(startGame); "
|
| 324 |
-
"3. function startGame()
|
|
|
|
| 325 |
" window.addEventListener('keydown', e => keys.add(e.key)); "
|
| 326 |
" window.addEventListener('keyup', e => keys.delete(e.key)); "
|
| 327 |
" canvas.addEventListener('click', onShoot); "
|
| 328 |
" requestAnimationFrame(gameLoop); } "
|
| 329 |
"4. Define gameLoop() and ALL functions at TOP LEVEL not inside startGame or .then(). "
|
| 330 |
-
"5. FOR TOP-DOWN SHOOTER
|
| 331 |
-
"
|
| 332 |
-
"
|
| 333 |
-
"
|
| 334 |
-
"
|
| 335 |
-
"
|
| 336 |
-
"
|
| 337 |
-
"
|
| 338 |
-
"
|
| 339 |
-
"
|
| 340 |
-
" Draw
|
| 341 |
-
"
|
| 342 |
-
"
|
| 343 |
-
"
|
| 344 |
-
"
|
| 345 |
-
"
|
| 346 |
-
"
|
| 347 |
-
"
|
| 348 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 349 |
"Output ONLY the raw HTML - no markdown fences, no explanation, nothing else."
|
| 350 |
)
|
| 351 |
|
|
|
|
| 158 |
def generate_image_prompts(theme: str, game_type: str) -> dict:
|
| 159 |
client = get_groq_client()
|
| 160 |
if game_type == "Top-Down Shooter":
|
| 161 |
+
bg_style = "bird's eye overhead view, top-down 2D game background, viewed from directly above, like a map"
|
| 162 |
+
char_style = (
|
| 163 |
+
"top-down overhead game sprite, viewed from directly above, "
|
| 164 |
+
"character body seen from above like looking straight down, "
|
| 165 |
+
"head at top shoulders below, like Metal Slug or GTA 2 sprite angle, "
|
| 166 |
+
"pure black background, character only"
|
| 167 |
)
|
| 168 |
else:
|
| 169 |
+
bg_style = "2D side-scrolling platformer background, horizontal landscape viewed from the side"
|
| 170 |
+
char_style = (
|
| 171 |
+
"2D side-view platformer game sprite, character facing right, "
|
| 172 |
+
"full body visible from the side like Super Mario or Mega Man, "
|
| 173 |
+
"classic side-scrolling game art style, "
|
| 174 |
+
"pure black background, character only"
|
| 175 |
)
|
| 176 |
|
| 177 |
seeds = {
|
| 178 |
"sprite_player.png": (
|
| 179 |
+
f"{char_style}, {theme} theme, "
|
| 180 |
+
f"vibrant colors, strong clear silhouette, 64x64 pixel style, "
|
| 181 |
+
f"single character centered, no scenery no ground no environment"
|
|
|
|
| 182 |
),
|
| 183 |
"sprite_background.png": (
|
| 184 |
+
f"{bg_style}, {theme} theme, "
|
| 185 |
+
f"wide atmospheric scene, game art style, 800x450, "
|
| 186 |
f"no characters no sprites, environment only"
|
| 187 |
),
|
| 188 |
"sprite_enemy.png": (
|
| 189 |
+
f"{char_style}, {theme} theme, enemy monster villain, "
|
| 190 |
+
f"menacing threatening design, strong clear silhouette, 64x64 pixel style, "
|
| 191 |
+
f"single enemy centered, no scenery no ground no environment"
|
|
|
|
| 192 |
),
|
| 193 |
}
|
| 194 |
if game_type == "Platformer":
|
| 195 |
seeds["sprite_platform.png"] = (
|
| 196 |
+
f"2D side-view pixel-art platform tile, {theme} theme, "
|
| 197 |
+
f"rectangular solid surface like a game platform, stone or wood texture, "
|
| 198 |
+
f"pure black background, platform only, 128x24 pixel style"
|
| 199 |
)
|
| 200 |
seeds["sprite_goal.png"] = (
|
| 201 |
+
f"2D side-view pixel-art treasure chest or glowing star goal, {theme} theme, "
|
| 202 |
+
f"glowing clearly visible reward item, "
|
| 203 |
+
f"pure black background, item only, 40x40 pixel style"
|
| 204 |
)
|
| 205 |
prompts = {}
|
| 206 |
for sprite_name, seed in seeds.items():
|
|
|
|
| 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 sprites at the very top of the script BEFORE anything else: "
|
| 317 |
" const playerImg = new Image(); playerImg.src = 'sprite_player.png'; "
|
| 318 |
" const bgImg = new Image(); bgImg.src = 'sprite_background.png'; "
|
|
|
|
| 321 |
"2. Use Promise.all to wait for ALL images before starting: "
|
| 322 |
" function loadImg(img) { return new Promise(r => { img.onload = r; }); } "
|
| 323 |
" Promise.all([loadImg(playerImg), loadImg(bgImg), loadImg(enemyImg)]).then(startGame); "
|
| 324 |
+
"3. function startGame() sets up listeners and starts the loop: "
|
| 325 |
+
" function startGame() { "
|
| 326 |
" window.addEventListener('keydown', e => keys.add(e.key)); "
|
| 327 |
" window.addEventListener('keyup', e => keys.delete(e.key)); "
|
| 328 |
" canvas.addEventListener('click', onShoot); "
|
| 329 |
" requestAnimationFrame(gameLoop); } "
|
| 330 |
"4. Define gameLoop() and ALL functions at TOP LEVEL not inside startGame or .then(). "
|
| 331 |
+
"5. FOR TOP-DOWN SHOOTER - STRICT RULES: "
|
| 332 |
+
" a. NO gravity, NO velY += 0.5, NO grounded variable. "
|
| 333 |
+
" b. Player starts at CENTER of canvas: player = {x: canvas.width/2 - 24, y: canvas.height/2 - 24, w: 48, h: 48, speed: 4}. "
|
| 334 |
+
" c. 4-direction WASD movement - clamp inside canvas after each move. "
|
| 335 |
+
" d. BULLETS travel straight UPWARD at constant speed -10 px/frame: "
|
| 336 |
+
" function onShoot(e) { bullets.push({x: player.x + player.w/2 - 4, y: player.y, w: 8, h: 16, vy: -10}); } "
|
| 337 |
+
" Each frame: b.y += b.vy; remove bullet when b.y + b.h < 0. "
|
| 338 |
+
" NEVER use mouse position to set bullet direction - bullets ALWAYS go straight up. "
|
| 339 |
+
" e. Enemies spawn at top (y=0), fall straight down: e.y += e.speed each frame. "
|
| 340 |
+
" Remove enemy when e.y > canvas.height. "
|
| 341 |
+
" f. Draw enemies: ctx.drawImage(enemyImg, e.x, e.y, e.w, e.h). "
|
| 342 |
+
" g. RESTART: define a reset() function that resets ALL game variables to initial values "
|
| 343 |
+
" and calls requestAnimationFrame(gameLoop). "
|
| 344 |
+
" Show restart button on canvas game-over screen that calls reset() when clicked. "
|
| 345 |
+
"6. FOR PLATFORMER - STRICT RULES: "
|
| 346 |
+
" a. Gravity: velY += 0.5 every frame AFTER updating position. "
|
| 347 |
+
" b. Set grounded=false BEFORE platform loop. Inside loop set grounded=true and velY=0 on landing. "
|
| 348 |
+
" c. Jump only when grounded: ArrowUp/W/Space sets velY=-12. "
|
| 349 |
+
" d. Always include full-width ground platform at y=420. "
|
| 350 |
+
" e. RESTART: define reset() that resets player position and lives, calls requestAnimationFrame(gameLoop). "
|
| 351 |
+
"7. Draw bgImg FIRST each frame: ctx.drawImage(bgImg, 0, 0, canvas.width, canvas.height). "
|
| 352 |
+
"8. Draw player: ctx.drawImage(playerImg, player.x, player.y, player.w, player.h). "
|
| 353 |
+
"9. Keep player inside canvas at all times. "
|
| 354 |
"Output ONLY the raw HTML - no markdown fences, no explanation, nothing else."
|
| 355 |
)
|
| 356 |
|