Improve top-down shooter asset matching
Browse files
app.py
CHANGED
|
@@ -178,6 +178,40 @@ def draw_background(spec: AssetSpec, rng: random.Random) -> bytes:
|
|
| 178 |
draw = ImageDraw.Draw(image, "RGBA")
|
| 179 |
prompt = spec.prompt.lower()
|
| 180 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 181 |
if any(word in prompt for word in ("space", "star", "nebula", "galaxy", "cosmic")):
|
| 182 |
image = Image.new("RGBA", (spec.width, spec.height), (3, 4, 18, 255))
|
| 183 |
draw = ImageDraw.Draw(image, "RGBA")
|
|
@@ -279,14 +313,77 @@ def draw_sprite(spec: AssetSpec, rng: random.Random) -> bytes:
|
|
| 279 |
draw = ImageDraw.Draw(image, "RGBA")
|
| 280 |
cx, cy = spec.width // 2, spec.height // 2
|
| 281 |
scale = min(spec.width, spec.height) / 128
|
| 282 |
-
|
| 283 |
-
shadow = (int(cx - 36 * scale), int(cy + 34 * scale), int(cx + 36 * scale), int(cy + 48 * scale))
|
| 284 |
-
draw.ellipse(shadow, fill=(0, 0, 0, 65))
|
| 285 |
outline = (18, 24, 31, 255)
|
| 286 |
body = colors[0] + (255,)
|
| 287 |
accent = colors[1] + (255,)
|
| 288 |
trim = colors[3] + (255,)
|
| 289 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 290 |
body_box = (cx - 26 * scale, cy - 18 * scale, cx + 26 * scale, cy + 34 * scale)
|
| 291 |
head_box = (cx - 20 * scale, cy - 52 * scale, cx + 20 * scale, cy - 12 * scale)
|
| 292 |
draw.rounded_rectangle(body_box, radius=int(12 * scale), fill=outline)
|
|
|
|
| 178 |
draw = ImageDraw.Draw(image, "RGBA")
|
| 179 |
prompt = spec.prompt.lower()
|
| 180 |
|
| 181 |
+
if any(word in prompt for word in ("sci-fi", "scifi", "arena", "metal", "hazard", "grid", "shooter")):
|
| 182 |
+
image = Image.new("RGBA", (spec.width, spec.height), (18, 22, 31, 255))
|
| 183 |
+
draw = ImageDraw.Draw(image, "RGBA")
|
| 184 |
+
panel = 64
|
| 185 |
+
for y in range(0, spec.height, panel):
|
| 186 |
+
for x in range(0, spec.width, panel):
|
| 187 |
+
shade = 24 + ((x // panel + y // panel) % 2) * 12
|
| 188 |
+
draw.rectangle(
|
| 189 |
+
(x, y, x + panel - 2, y + panel - 2),
|
| 190 |
+
fill=(shade, shade + 4, shade + 14, 255),
|
| 191 |
+
outline=(58, 74, 92, 170),
|
| 192 |
+
)
|
| 193 |
+
for x in range(0, spec.width, 96):
|
| 194 |
+
draw.line((x, 0, x, spec.height), fill=(34, 215, 236, 95), width=2)
|
| 195 |
+
for y in range(0, spec.height, 96):
|
| 196 |
+
draw.line((0, y, spec.width, y), fill=(34, 215, 236, 95), width=2)
|
| 197 |
+
for _ in range(8):
|
| 198 |
+
x = rng.randint(0, spec.width - 120)
|
| 199 |
+
y = rng.randint(0, spec.height - 34)
|
| 200 |
+
draw.rectangle((x, y, x + 120, y + 34), fill=(36, 42, 53, 235), outline=(110, 125, 142, 210))
|
| 201 |
+
for stripe in range(0, 120, 24):
|
| 202 |
+
draw.polygon(
|
| 203 |
+
[(x + stripe, y), (x + stripe + 12, y), (x + stripe - 12, y + 34), (x + stripe - 24, y + 34)],
|
| 204 |
+
fill=(245, 192, 51, 210),
|
| 205 |
+
)
|
| 206 |
+
for _ in range(18):
|
| 207 |
+
x = rng.randint(0, spec.width)
|
| 208 |
+
y = rng.randint(0, spec.height)
|
| 209 |
+
r = rng.randint(10, 32)
|
| 210 |
+
draw.ellipse((x - r, y - r, x + r, y + r), outline=(224, 54, 85, 100), width=2)
|
| 211 |
+
out = io.BytesIO()
|
| 212 |
+
image.save(out, format="PNG")
|
| 213 |
+
return out.getvalue()
|
| 214 |
+
|
| 215 |
if any(word in prompt for word in ("space", "star", "nebula", "galaxy", "cosmic")):
|
| 216 |
image = Image.new("RGBA", (spec.width, spec.height), (3, 4, 18, 255))
|
| 217 |
draw = ImageDraw.Draw(image, "RGBA")
|
|
|
|
| 313 |
draw = ImageDraw.Draw(image, "RGBA")
|
| 314 |
cx, cy = spec.width // 2, spec.height // 2
|
| 315 |
scale = min(spec.width, spec.height) / 128
|
| 316 |
+
role_prompt = f"{spec.role} {spec.prompt}".lower()
|
|
|
|
|
|
|
| 317 |
outline = (18, 24, 31, 255)
|
| 318 |
body = colors[0] + (255,)
|
| 319 |
accent = colors[1] + (255,)
|
| 320 |
trim = colors[3] + (255,)
|
| 321 |
|
| 322 |
+
if any(word in role_prompt for word in ("bullet", "projectile", "laser", "energy")):
|
| 323 |
+
glow = colors[1] + (85,)
|
| 324 |
+
draw.ellipse((cx - 30 * scale, cy - 42 * scale, cx + 30 * scale, cy + 42 * scale), fill=glow)
|
| 325 |
+
draw.rounded_rectangle(
|
| 326 |
+
(cx - 9 * scale, cy - 40 * scale, cx + 9 * scale, cy + 38 * scale),
|
| 327 |
+
radius=int(9 * scale),
|
| 328 |
+
fill=outline,
|
| 329 |
+
)
|
| 330 |
+
draw.rounded_rectangle(
|
| 331 |
+
(cx - 5 * scale, cy - 35 * scale, cx + 5 * scale, cy + 33 * scale),
|
| 332 |
+
radius=int(5 * scale),
|
| 333 |
+
fill=accent,
|
| 334 |
+
)
|
| 335 |
+
out = io.BytesIO()
|
| 336 |
+
image.save(out, format="PNG")
|
| 337 |
+
return out.getvalue()
|
| 338 |
+
|
| 339 |
+
if any(word in role_prompt for word in ("enemy", "drone", "alien", "monster")):
|
| 340 |
+
draw.ellipse((cx - 38 * scale, cy - 28 * scale, cx + 38 * scale, cy + 28 * scale), fill=outline)
|
| 341 |
+
draw.ellipse((cx - 32 * scale, cy - 22 * scale, cx + 32 * scale, cy + 22 * scale), fill=(150, 35, 63, 255))
|
| 342 |
+
draw.ellipse((cx - 16 * scale, cy - 16 * scale, cx + 16 * scale, cy + 16 * scale), fill=accent)
|
| 343 |
+
for side in (-1, 1):
|
| 344 |
+
draw.polygon(
|
| 345 |
+
[
|
| 346 |
+
(cx + side * 28 * scale, cy - 8 * scale),
|
| 347 |
+
(cx + side * 56 * scale, cy - 28 * scale),
|
| 348 |
+
(cx + side * 48 * scale, cy + 20 * scale),
|
| 349 |
+
],
|
| 350 |
+
fill=outline,
|
| 351 |
+
)
|
| 352 |
+
draw.line((cx + side * 14 * scale, cy, cx + side * 58 * scale, cy), fill=trim, width=max(2, int(5 * scale)))
|
| 353 |
+
out = io.BytesIO()
|
| 354 |
+
image.save(out, format="PNG")
|
| 355 |
+
return out.getvalue()
|
| 356 |
+
|
| 357 |
+
if any(word in role_prompt for word in ("shooter", "ship", "tank", "hero", "player", "armored")):
|
| 358 |
+
shadow = (int(cx - 36 * scale), int(cy + 34 * scale), int(cx + 36 * scale), int(cy + 48 * scale))
|
| 359 |
+
draw.ellipse(shadow, fill=(0, 0, 0, 55))
|
| 360 |
+
draw.polygon(
|
| 361 |
+
[
|
| 362 |
+
(cx, cy - 50 * scale),
|
| 363 |
+
(cx - 34 * scale, cy + 34 * scale),
|
| 364 |
+
(cx, cy + 20 * scale),
|
| 365 |
+
(cx + 34 * scale, cy + 34 * scale),
|
| 366 |
+
],
|
| 367 |
+
fill=outline,
|
| 368 |
+
)
|
| 369 |
+
draw.polygon(
|
| 370 |
+
[
|
| 371 |
+
(cx, cy - 42 * scale),
|
| 372 |
+
(cx - 24 * scale, cy + 23 * scale),
|
| 373 |
+
(cx, cy + 12 * scale),
|
| 374 |
+
(cx + 24 * scale, cy + 23 * scale),
|
| 375 |
+
],
|
| 376 |
+
fill=body,
|
| 377 |
+
)
|
| 378 |
+
draw.ellipse((cx - 11 * scale, cy - 14 * scale, cx + 11 * scale, cy + 10 * scale), fill=accent)
|
| 379 |
+
draw.line((cx, cy - 42 * scale, cx, cy - 62 * scale), fill=trim, width=max(3, int(6 * scale)))
|
| 380 |
+
out = io.BytesIO()
|
| 381 |
+
image.save(out, format="PNG")
|
| 382 |
+
return out.getvalue()
|
| 383 |
+
|
| 384 |
+
shadow = (int(cx - 36 * scale), int(cy + 34 * scale), int(cx + 36 * scale), int(cy + 48 * scale))
|
| 385 |
+
draw.ellipse(shadow, fill=(0, 0, 0, 65))
|
| 386 |
+
|
| 387 |
body_box = (cx - 26 * scale, cy - 18 * scale, cx + 26 * scale, cy + 34 * scale)
|
| 388 |
head_box = (cx - 20 * scale, cy - 52 * scale, cx + 20 * scale, cy - 12 * scale)
|
| 389 |
draw.rounded_rectangle(body_box, radius=int(12 * scale), fill=outline)
|