182 lines
5.1 KiB
Python
182 lines
5.1 KiB
Python
"""
|
|
Generate block_atlas.png — 4x4 atlas (256x256), 64x64 tiles
|
|
Row 0: SAND, ROCK, CORAL_RED, CORAL_BLUE
|
|
Row 1: KELP, WRECK_WOOD, ICE, BEDROCK
|
|
Row 2-3: unused (blank)
|
|
"""
|
|
from PIL import Image, ImageDraw
|
|
import random
|
|
|
|
TILE = 64
|
|
ATLAS_COLS = 4
|
|
ATLAS_ROWS = 4
|
|
W = TILE * ATLAS_COLS
|
|
H = TILE * ATLAS_ROWS
|
|
|
|
atlas = Image.new("RGBA", (W, H), (0, 0, 0, 255))
|
|
|
|
|
|
def noise_tile(base_color, variation=20, seed=0):
|
|
r = random.Random(seed)
|
|
img = Image.new("RGBA", (TILE, TILE))
|
|
px = img.load()
|
|
br, bg, bb = base_color
|
|
for y in range(TILE):
|
|
for x in range(TILE):
|
|
v = r.randint(-variation, variation)
|
|
px[x, y] = (
|
|
max(0, min(255, br + v)),
|
|
max(0, min(255, bg + v)),
|
|
max(0, min(255, bb + v)),
|
|
255
|
|
)
|
|
return img
|
|
|
|
|
|
def sand_tile():
|
|
img = noise_tile((194, 178, 128), variation=18, seed=2)
|
|
draw = ImageDraw.Draw(img)
|
|
r = random.Random(2)
|
|
for _ in range(60):
|
|
x, y = r.randint(0, TILE-1), r.randint(0, TILE-1)
|
|
c = r.randint(160, 210)
|
|
draw.point((x, y), fill=(c, c-10, c-30, 255))
|
|
return img
|
|
|
|
|
|
def rock_tile():
|
|
img = noise_tile((115, 115, 115), variation=25, seed=3)
|
|
draw = ImageDraw.Draw(img)
|
|
r = random.Random(3)
|
|
for _ in range(4):
|
|
y = r.randint(5, TILE-5)
|
|
x0 = r.randint(0, 10)
|
|
x1 = r.randint(TILE-10, TILE-1)
|
|
draw.line([(x0, y), (x1, y + r.randint(-2, 2))], fill=(80, 80, 80, 255), width=1)
|
|
return img
|
|
|
|
|
|
def coral_red_tile():
|
|
img = noise_tile((230, 64, 52), variation=15, seed=4)
|
|
draw = ImageDraw.Draw(img)
|
|
r = random.Random(4)
|
|
for _ in range(20):
|
|
x, y = r.randint(0, TILE-3), r.randint(0, TILE-3)
|
|
draw.ellipse([x, y, x+2, y+2], fill=(255, 200, 180, 255))
|
|
return img
|
|
|
|
|
|
def coral_blue_tile():
|
|
img = noise_tile((51, 127, 242), variation=15, seed=5)
|
|
draw = ImageDraw.Draw(img)
|
|
r = random.Random(5)
|
|
for _ in range(20):
|
|
x, y = r.randint(0, TILE-3), r.randint(0, TILE-3)
|
|
draw.ellipse([x, y, x+2, y+2], fill=(180, 220, 255, 255))
|
|
return img
|
|
|
|
|
|
def kelp_tile():
|
|
img = noise_tile((38, 153, 51), variation=12, seed=6)
|
|
draw = ImageDraw.Draw(img)
|
|
r = random.Random(6)
|
|
for i in range(0, TILE, 8):
|
|
x = i + r.randint(-2, 2)
|
|
draw.line([(x, 0), (x, TILE-1)], fill=(20, 100, 30, 255), width=2)
|
|
return img
|
|
|
|
|
|
def wood_tile():
|
|
img = noise_tile((89, 56, 31), variation=12, seed=7)
|
|
draw = ImageDraw.Draw(img)
|
|
r = random.Random(7)
|
|
for i in range(0, TILE, 6):
|
|
y = i + r.randint(-1, 1)
|
|
shade = r.randint(50, 90)
|
|
draw.line([(0, y), (TILE-1, y + r.randint(-1, 1))], fill=(shade, shade//2, shade//4, 255), width=1)
|
|
return img
|
|
|
|
|
|
def ice_tile():
|
|
img = noise_tile((191, 230, 255), variation=10, seed=8)
|
|
draw = ImageDraw.Draw(img)
|
|
r = random.Random(8)
|
|
for _ in range(5):
|
|
x0, y0 = r.randint(0, TILE-1), r.randint(0, TILE-1)
|
|
x1 = x0 + r.randint(-15, 15)
|
|
y1 = y0 + r.randint(-15, 15)
|
|
draw.line([(x0, y0), (x1, y1)], fill=(140, 200, 240, 255), width=1)
|
|
return img
|
|
|
|
|
|
def bedrock_tile():
|
|
img = noise_tile((38, 38, 38), variation=10, seed=9)
|
|
draw = ImageDraw.Draw(img)
|
|
r = random.Random(9)
|
|
for _ in range(12):
|
|
x, y = r.randint(0, TILE-5), r.randint(0, TILE-5)
|
|
c = r.randint(20, 50)
|
|
draw.ellipse([x, y, x+4, y+4], fill=(c, c, c, 255))
|
|
return img
|
|
|
|
|
|
def glow_coral_cyan_tile():
|
|
img = noise_tile((51, 204, 255), variation=12, seed=10)
|
|
draw = ImageDraw.Draw(img)
|
|
r = random.Random(10)
|
|
for _ in range(25):
|
|
x, y = r.randint(0, TILE-3), r.randint(0, TILE-3)
|
|
draw.ellipse([x, y, x+3, y+3], fill=(180, 255, 255, 255))
|
|
return img
|
|
|
|
|
|
def glow_coral_violet_tile():
|
|
img = noise_tile((178, 77, 230), variation=12, seed=11)
|
|
draw = ImageDraw.Draw(img)
|
|
r = random.Random(11)
|
|
for _ in range(25):
|
|
x, y = r.randint(0, TILE-3), r.randint(0, TILE-3)
|
|
draw.ellipse([x, y, x+3, y+3], fill=(230, 180, 255, 255))
|
|
return img
|
|
|
|
|
|
def lava_vent_tile():
|
|
img = noise_tile((60, 30, 10), variation=10, seed=12)
|
|
draw = ImageDraw.Draw(img)
|
|
r = random.Random(12)
|
|
# glowing cracks in orange/red
|
|
for _ in range(8):
|
|
x0, y0 = r.randint(10, TILE-10), r.randint(10, TILE-10)
|
|
x1 = x0 + r.randint(-12, 12)
|
|
y1 = y0 + r.randint(-12, 12)
|
|
draw.line([(x0, y0), (x1, y1)], fill=(255, 120, 20, 255), width=2)
|
|
# hot center glow
|
|
for _ in range(6):
|
|
x, y = r.randint(20, TILE-20), r.randint(20, TILE-20)
|
|
draw.ellipse([x, y, x+5, y+5], fill=(255, 200, 50, 255))
|
|
return img
|
|
|
|
|
|
tiles = [
|
|
(0, 0, sand_tile()),
|
|
(1, 0, rock_tile()),
|
|
(2, 0, coral_red_tile()),
|
|
(3, 0, coral_blue_tile()),
|
|
(0, 1, kelp_tile()),
|
|
(1, 1, wood_tile()),
|
|
(2, 1, ice_tile()),
|
|
(3, 1, bedrock_tile()),
|
|
(0, 2, glow_coral_cyan_tile()),
|
|
(1, 2, glow_coral_violet_tile()),
|
|
(2, 2, lava_vent_tile()),
|
|
]
|
|
|
|
for col, row, tile in tiles:
|
|
atlas.paste(tile, (col * TILE, row * TILE))
|
|
|
|
out = "block_atlas.png"
|
|
atlas.save(out)
|
|
import os
|
|
size = os.path.getsize(out)
|
|
print(f"Atlas saved: {out} ({W}x{H}) — {size} bytes ({size//1024} Ko)")
|