LeafCat79 commited on
Commit
4769793
·
verified ·
1 Parent(s): afeadcc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +52 -47
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
- perspective = "bird's eye view directly overhead, isometric top-down game art"
162
- char_style = (
163
- "bird's eye view directly overhead, isometric top-down game sprite, "
164
- "character seen from above looking down, head visible at top, feet at bottom, "
165
- "no perspective distortion, flat top-down angle"
 
166
  )
167
  else:
168
- perspective = "2D side-scrolling platformer background, horizontal flat landscape"
169
- char_style = (
170
- "2D side-view platformer sprite, character facing right, "
171
- "full body visible from the side, flat 2D game art style, "
172
- "like classic side-scrolling game characters"
 
173
  )
174
 
175
  seeds = {
176
  "sprite_player.png": (
177
- f"pixel-art game player character, {char_style}, {theme} theme, "
178
- f"isolated character on pure solid-color background, "
179
- f"strong clear silhouette, vibrant colors, 64x64 pixel style, "
180
- f"single character only, no scenery no environment"
181
  ),
182
  "sprite_background.png": (
183
- f"2D game background scene, {perspective}, {theme} theme, "
184
- f"wide landscape, atmospheric, game art style, 800x450, "
185
  f"no characters no sprites, environment only"
186
  ),
187
  "sprite_enemy.png": (
188
- f"pixel-art enemy character, {char_style}, {theme} theme, "
189
- f"menacing and threatening, isolated character on pure solid-color background, "
190
- f"strong clear silhouette, 64x64 pixel style, "
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 solid platform tile, 2D side-view, {theme} theme, "
197
- f"rectangular stone or wooden surface, isolated on solid-color background, "
198
- f"no characters, 128x24 pixel style"
199
  )
200
  seeds["sprite_goal.png"] = (
201
- f"pixel-art goal treasure chest or glowing star, 2D side-view, {theme} theme, "
202
- f"glowing and clearly visible, isolated on solid-color background, "
203
- f"no characters, 40x40 pixel style"
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 movement - player moves in ALL 4 directions, NO gravity: "
331
- " if (keys.has('w') || keys.has('W') || keys.has('ArrowUp')) player.y -= player.speed; "
332
- " if (keys.has('s') || keys.has('S') || keys.has('ArrowDown')) player.y += player.speed; "
333
- " if (keys.has('a') || keys.has('A') || keys.has('ArrowLeft')) player.x -= player.speed; "
334
- " if (keys.has('d') || keys.has('D') || keys.has('ArrowRight')) player.x += player.speed; "
335
- " Clamp player inside canvas after movement. "
336
- "6. FOR TOP-DOWN SHOOTER bullets - shoot straight UPWARD on click, constant speed: "
337
- " function onShoot(e) { bullets.push({x: player.x + player.w/2 - 4, y: player.y, w: 8, h: 16, vy: -10}); } "
338
- " Each frame move every bullet: b.y += b.vy; "
339
- " Remove bullets when b.y + b.h < 0. "
340
- " Draw bullets with ctx.fillStyle and ctx.fillRect. "
341
- "7. FOR TOP-DOWN SHOOTER enemies - draw with ctx.drawImage(enemyImg, e.x, e.y, e.w, e.h). "
342
- " Enemies fall straight down: e.y += e.speed each frame. "
343
- " Remove enemy if e.y > canvas.height. "
344
- "8. FOR PLATFORMER: gravity velY+=0.5, grounded checks, jump ArrowUp/W/Space velY=-12. "
345
- " Set grounded=false BEFORE platform loop, set grounded=true and velY=0 only on landing. "
346
- " Always include full-width ground platform at y=420. "
347
- "9. Draw bgImg FIRST each frame: ctx.drawImage(bgImg, 0, 0, canvas.width, canvas.height). "
348
- "10. Draw player: ctx.drawImage(playerImg, player.x, player.y, player.w, player.h). "
 
 
 
 
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