feat: Initial commit Plants vs Zombies Web Edition v2.4

- 5 Biomes: Day, Night, Pool, Fog, Roof (25 Campaign levels)
- Minigames: Wall-nut Bowling, I Zombie, Roguelike, Boss Rush & Dr. Zomboss
- Systems: Zen Garden, Workshop Crafting, Almanac, Tree of Wisdom, Achievements
- Backend: REST API + SQLite Accounts & Save Synchronization
- Infrastructure: Nginx HTTPS & Docker deployment
This commit is contained in:
Antigravity committed 2026-09-17 09:30:52 +00:00
commit 6457a8904e
50 files changed
+14486

No files matched your search

+87
View File
@@ -0,0 +1,87 @@
#!/usr/bin/env python3
import os
import zlib
import struct
import math
def make_png(w, h, get_pixel):
def chunk(tag, data):
return struct.pack('>I', len(data)) + tag + data + struct.pack('>I', zlib.crc32(tag + data) & 0xffffffff)
ihdr = struct.pack('>IIBBBBB', w, h, 8, 6, 0, 0, 0) # RGBA 8-bit
raw_rows = []
for y in range(h):
row = [0] # filter type 0
for x in range(w):
r, g, b, a = get_pixel(x, y, w, h)
row.extend([r, g, b, a])
raw_rows.append(bytes(row))
raw_data = b''.join(raw_rows)
idat = zlib.compress(raw_data, 9)
return b'\x89PNG\r\n\x1a\n' + chunk(b'IHDR', ihdr) + chunk(b'IDAT', idat) + chunk(b'IEND', b'')
def render_pvz_icon(x, y, w, h):
# Normalized coords (-1 to 1)
nx = (x - w / 2) / (w / 2)
ny = (y - h / 2) / (h / 2)
dist = math.hypot(nx, ny)
# Outer dark green circle border
if dist > 0.96:
return 0, 0, 0, 0
if dist > 0.90:
return 27, 94, 32, 255
# Background circle (lawn green gradient)
if dist <= 0.90:
# Sunflower petals or Peashooter head
# Let's draw stylized bright yellow sunflower with green peashooter center!
angle = math.atan2(ny, nx)
petal_r = 0.55 + 0.15 * math.sin(angle * 8)
# Petal check
if dist < petal_r and dist > 0.40:
return 255, 213, 79, 255 # Yellow sunflower petals
# Peashooter green head in center
center_dist = math.hypot(nx + 0.08, ny)
if center_dist < 0.35:
# Snout pointing right
snout = (nx > 0.05 and nx < 0.35 and abs(ny) < 0.12)
if snout:
return 76, 175, 80, 255
# Eye
eye_dist = math.hypot(nx - (-0.05), ny - (-0.12))
if eye_dist < 0.06:
return 255, 255, 255, 255
if eye_dist < 0.03:
return 0, 0, 0, 255
return 67, 160, 71, 255
# Green lawn background inside circle
grad = int(46 + (1.0 - dist) * 60)
return 27, min(255, grad + 80), 32, 255
def main():
game_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "game")
# Generate 192x192
p192 = make_png(192, 192, render_pvz_icon)
with open(os.path.join(game_dir, "icon-192.png"), "wb") as f:
f.write(p192)
print("Generated icon-192.png:", len(p192), "bytes")
# Generate 512x512
p512 = make_png(512, 512, render_pvz_icon)
with open(os.path.join(game_dir, "icon-512.png"), "wb") as f:
f.write(p512)
print("Generated icon-512.png:", len(p512), "bytes")
# Generate favicon.ico (valid 32x32 PNG inside or 32x32 favicon)
p32 = make_png(32, 32, render_pvz_icon)
with open(os.path.join(game_dir, "favicon.ico"), "wb") as f:
f.write(p32)
print("Generated favicon.ico:", len(p32), "bytes")
if __name__ == "__main__":
main()