LeafCat79 commited on
Commit
e61e8fe
·
verified ·
1 Parent(s): df65baa

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +52 -41
app.py CHANGED
@@ -157,14 +157,38 @@ THEME_EXAMPLES = {
157
 
158
  def generate_image_prompts(theme: str, game_type: str) -> dict:
159
  client = get_groq_client()
 
 
 
 
 
 
 
160
  seeds = {
161
- "sprite_player.png": f"pixel-art game player character for a {theme} themed {game_type} game, front-facing sprite, vibrant colors, clear silhouette, 64x64 pixel style",
162
- "sprite_background.png": f"2D game background scene for a {theme} themed {game_type} game, wide landscape, atmospheric, game art style, 800x450",
163
- "sprite_enemy.png": f"pixel-art enemy character for a {theme} themed {game_type} game, menacing, clear silhouette, 64x64 pixel style",
 
 
 
 
 
 
 
 
 
 
 
164
  }
165
  if game_type == "Platformer":
166
- seeds["sprite_platform.png"] = f"pixel-art solid platform tile for a {theme} themed platformer game, rectangular, textured surface, 128x24 pixel style"
167
- seeds["sprite_goal.png"] = f"pixel-art goal or treasure chest for a {theme} themed platformer game, glowing, clearly visible, 40x40 pixel style"
 
 
 
 
 
 
168
  prompts = {}
169
  for sprite_name, seed in seeds.items():
170
  try:
@@ -256,56 +280,43 @@ def _inject_sprites(html_code: str, sprite_map: dict) -> str:
256
  CODE_SYSTEM = (
257
  "You are an expert HTML5 game developer. "
258
  "Write a complete, working, single-file HTML5 game using canvas and vanilla JavaScript. "
259
- "CRITICAL RULES - follow every one exactly: "
260
- "1. SPRITES: Declare these at the very top of the script BEFORE anything else: "
261
  " const playerImg = new Image(); playerImg.src = 'sprite_player.png'; "
262
  " const bgImg = new Image(); bgImg.src = 'sprite_background.png'; "
263
  " const enemyImg = new Image(); enemyImg.src = 'sprite_enemy.png'; "
264
  " const keys = new Set(); "
265
- "2. IMAGE LOADING: After declaring sprites use Promise.all to start the game: "
266
  " function loadImg(img) { return new Promise(r => { img.onload = r; }); } "
267
  " Promise.all([loadImg(playerImg), loadImg(bgImg), loadImg(enemyImg)]).then(startGame); "
268
- "3. startGame function sets up listeners and calls gameLoop: "
269
- " function startGame() { "
270
  " window.addEventListener('keydown', e => keys.add(e.key)); "
271
  " window.addEventListener('keyup', e => keys.delete(e.key)); "
272
  " canvas.addEventListener('click', onShoot); "
273
  " requestAnimationFrame(gameLoop); } "
274
- "4. Define gameLoop() and ALL game logic functions at TOP LEVEL - NOT inside startGame or Promise.then. "
275
- "5. MOVEMENT RULES DEPEND ON GAME TYPE: "
276
- " FOR TOP-DOWN SHOOTER - follow these EXACTLY inside gameLoop() every frame: "
277
- " NO gravity, NO velY += 0.5, NO grounded variable, NO jumping. "
278
- " STEP A - move player from keys every frame: "
279
- " if (keys.has('w') || keys.has('ArrowUp')) player.y -= player.speed; "
280
- " if (keys.has('s') || keys.has('ArrowDown')) player.y += player.speed; "
281
- " if (keys.has('a') || keys.has('ArrowLeft')) player.x -= player.speed; "
282
- " if (keys.has('d') || keys.has('ArrowRight')) player.x += player.speed; "
283
- " player.x = Math.max(0, Math.min(canvas.width-player.w, player.x)); "
284
- " player.y = Math.max(0, Math.min(canvas.height-player.h, player.y)); "
285
- " STEP B - move every bullet forward every frame (THIS IS REQUIRED): "
286
- " bullets.forEach(b => { b.x += b.vx; b.y += b.vy; }); "
287
- " bullets = bullets.filter(b => b.x>=0 && b.x<=canvas.width && b.y>=0 && b.y<=canvas.height); "
288
- " STEP C - move enemies toward player every frame: "
289
- " enemies.forEach(e => { const dx=player.x-e.x; const dy=player.y-e.y; "
290
- " const d=Math.sqrt(dx*dx+dy*dy); if(d>0){e.x+=dx/d*e.speed; e.y+=dy/d*e.speed;} }); "
291
- " STEP D - for shooting, add click listener on canvas inside startGame(): "
292
- " canvas.addEventListener('click', function(e){ "
293
- " const r=canvas.getBoundingClientRect(); "
294
- " const mx=e.clientX-r.left; const my=e.clientY-r.top; "
295
- " const dx=mx-(player.x+player.w/2); const dy=my-(player.y+player.h/2); "
296
- " const d=Math.sqrt(dx*dx+dy*dy); "
297
- " if(d>0) bullets.push({x:player.x+player.w/2, y:player.y+player.h/2, vx:dx/d*10, vy:dy/d*10, w:6, h:6}); }); "
298
- " FOR PLATFORMER: use gravity velY += 0.5, grounded checks, jump with ArrowUp/W/Space (velY=-12). "
299
- " Set grounded=false BEFORE platform loop. Set grounded=true and velY=0 only on landing. "
300
  " Always include full-width ground platform at y=420. "
301
- " FOR PLATFORMER: also declare platformImg and goalImg at top and include them in Promise.all. "
302
- "6. Draw background FIRST each frame: ctx.drawImage(bgImg, 0, 0, canvas.width, canvas.height). "
303
- "7. Draw player/enemies with ctx.drawImage(playerImg, x, y, w, h). "
304
- "8. Always keep player inside canvas boundaries. "
305
  "Output ONLY the raw HTML - no markdown fences, no explanation, nothing else."
306
  )
307
 
308
-
309
  def generate_game_code(game_type: str, theme: str, temperature: float, max_new_tokens: int):
310
  if not theme.strip():
311
  return "", "", "Please enter a theme first.", _placeholder_html("Enter a theme and generate a game.")
 
157
 
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 = "top-down aerial view"
162
+ char_style = "top-down aerial view sprite, character seen from directly above"
163
+ else:
164
+ perspective = "2D side-view flat"
165
+ char_style = "2D side-view flat sprite, full body visible from the side"
166
+
167
  seeds = {
168
+ "sprite_player.png": (
169
+ f"pixel-art game player character, {char_style}, {theme} theme, "
170
+ f"vibrant colors, character ONLY with NO background, transparent background, "
171
+ f"clear silhouette, 64x64 pixel style"
172
+ ),
173
+ "sprite_background.png": (
174
+ f"2D game background scene, {perspective}, {theme} theme, "
175
+ f"wide landscape, atmospheric, game art style, 800x450, no characters"
176
+ ),
177
+ "sprite_enemy.png": (
178
+ f"pixel-art enemy character, {char_style}, {theme} theme, "
179
+ f"menacing, character ONLY with NO background, transparent background, "
180
+ f"clear silhouette, 64x64 pixel style"
181
+ ),
182
  }
183
  if game_type == "Platformer":
184
+ seeds["sprite_platform.png"] = (
185
+ f"pixel-art solid platform tile, 2D side-view, {theme} theme, "
186
+ f"rectangular textured surface, NO background, transparent background, 128x24"
187
+ )
188
+ seeds["sprite_goal.png"] = (
189
+ f"pixel-art goal treasure chest or star, 2D side-view, {theme} theme, "
190
+ f"glowing, clearly visible, NO background, transparent background, 40x40"
191
+ )
192
  prompts = {}
193
  for sprite_name, seed in seeds.items():
194
  try:
 
280
  CODE_SYSTEM = (
281
  "You are an expert HTML5 game developer. "
282
  "Write a complete, working, single-file HTML5 game using canvas and vanilla JavaScript. "
283
+ "CRITICAL RULES: "
284
+ "1. Declare sprites at the very top of the script BEFORE anything else: "
285
  " const playerImg = new Image(); playerImg.src = 'sprite_player.png'; "
286
  " const bgImg = new Image(); bgImg.src = 'sprite_background.png'; "
287
  " const enemyImg = new Image(); enemyImg.src = 'sprite_enemy.png'; "
288
  " const keys = new Set(); "
289
+ "2. Use Promise.all to wait for ALL images before starting: "
290
  " function loadImg(img) { return new Promise(r => { img.onload = r; }); } "
291
  " Promise.all([loadImg(playerImg), loadImg(bgImg), loadImg(enemyImg)]).then(startGame); "
292
+ "3. function startGame() { "
 
293
  " window.addEventListener('keydown', e => keys.add(e.key)); "
294
  " window.addEventListener('keyup', e => keys.delete(e.key)); "
295
  " canvas.addEventListener('click', onShoot); "
296
  " requestAnimationFrame(gameLoop); } "
297
+ "4. Define gameLoop() and ALL functions at TOP LEVEL not inside startGame or .then(). "
298
+ "5. FOR TOP-DOWN SHOOTER movement - player moves in ALL 4 directions, NO gravity: "
299
+ " if (keys.has('w') || keys.has('W') || keys.has('ArrowUp')) player.y -= player.speed; "
300
+ " if (keys.has('s') || keys.has('S') || keys.has('ArrowDown')) player.y += player.speed; "
301
+ " if (keys.has('a') || keys.has('A') || keys.has('ArrowLeft')) player.x -= player.speed; "
302
+ " if (keys.has('d') || keys.has('D') || keys.has('ArrowRight')) player.x += player.speed; "
303
+ " Clamp player inside canvas after movement. "
304
+ "6. FOR TOP-DOWN SHOOTER bullets - shoot straight UPWARD on click, constant speed: "
305
+ " function onShoot(e) { bullets.push({x: player.x + player.w/2 - 4, y: player.y, w: 8, h: 16, vy: -10}); } "
306
+ " Each frame move every bullet: b.y += b.vy; "
307
+ " Remove bullets when b.y + b.h < 0. "
308
+ " Draw bullets with ctx.fillStyle and ctx.fillRect. "
309
+ "7. FOR TOP-DOWN SHOOTER enemies - draw with ctx.drawImage(enemyImg, e.x, e.y, e.w, e.h). "
310
+ " Enemies fall straight down: e.y += e.speed each frame. "
311
+ " Remove enemy if e.y > canvas.height. "
312
+ "8. FOR PLATFORMER: gravity velY+=0.5, grounded checks, jump ArrowUp/W/Space velY=-12. "
313
+ " Set grounded=false BEFORE platform loop, set grounded=true and velY=0 only on landing. "
 
 
 
 
 
 
 
 
 
314
  " Always include full-width ground platform at y=420. "
315
+ "9. Draw bgImg FIRST each frame: ctx.drawImage(bgImg, 0, 0, canvas.width, canvas.height). "
316
+ "10. Draw player: ctx.drawImage(playerImg, player.x, player.y, player.w, player.h). "
 
 
317
  "Output ONLY the raw HTML - no markdown fences, no explanation, nothing else."
318
  )
319
 
 
320
  def generate_game_code(game_type: str, theme: str, temperature: float, max_new_tokens: int):
321
  if not theme.strip():
322
  return "", "", "Please enter a theme first.", _placeholder_html("Enter a theme and generate a game.")