134 lines
4.0 KiB
Python
134 lines
4.0 KiB
Python
import math
|
|
|
|
from PIL import Image
|
|
|
|
|
|
TILESHAPES = "sprites/tileshapes.png"
|
|
SPITE_MARGIN = 10
|
|
TILEDATA = [
|
|
[ 20, 20, 64, 31, -31, 7],
|
|
[ 20, 70, 64, 31, -31, 7],
|
|
[ 20, 120, 64, 23, -31, 7],
|
|
[ 20, 170, 64, 23, -31, 7],
|
|
[ 20, 220, 64, 31, -31, 7],
|
|
[ 20, 270, 64, 31, -31, 7],
|
|
[ 20, 320, 64, 23, -31, 7],
|
|
[ 20, 370, 64, 23, -31, 7],
|
|
[ 20, 420, 64, 39, -31, -1],
|
|
[ 20, 470, 64, 39, -31, -1],
|
|
[ 20, 520, 64, 31, -31, -1],
|
|
[ 20, 570, 64, 31, -31, -1],
|
|
[ 20, 620, 64, 39, -31, -1],
|
|
[ 20, 670, 64, 39, -31, -1],
|
|
[ 20, 720, 64, 31, -31, -1],
|
|
[ 20, 770, 64, 47, -31, -9],
|
|
[ 20, 820, 64, 15, -31, 7],
|
|
[ 20, 870, 64, 31, -31, -1],
|
|
[ 20, 920, 64, 31, -31, -1],
|
|
]
|
|
|
|
def pointdist(x, y, p):
|
|
xx, yy = p
|
|
return math.hypot(xx - x, yy - y)
|
|
|
|
def linedist(x, y, p1, p2):
|
|
x1, y1 = p1
|
|
x2, y2 = p2
|
|
return abs((y2 - y1) * x - (x2 - x1) * y + x2 * y1 - y2 * x1) / math.hypot(y2 - y1, x2 - x1)
|
|
|
|
def gen_borders(tile, borders, corner):
|
|
D = 4
|
|
w, h = tile.size
|
|
|
|
res = tile.copy()
|
|
pixels = res.load()
|
|
|
|
mx = w // 2
|
|
my1, my2 = 0, 0
|
|
for i in range(h):
|
|
if pixels[0, i]:
|
|
my1 = i
|
|
if pixels[w - 1, i]:
|
|
my2 = i
|
|
|
|
ptop = (32, -1) # -.5 extra instead of adding .5 to pixels
|
|
pbottom = (32, h)
|
|
pleft = (0, my1)
|
|
pright = (64, my2)
|
|
for y in range(h):
|
|
for x in range(w):
|
|
if pixels[x, y] == 0:
|
|
continue
|
|
d = D + 1
|
|
if borders & 1:
|
|
d = min(d, linedist(x, y, ptop, pleft))
|
|
|
|
if borders & 2:
|
|
d = min(d, linedist(x, y, ptop, pright))
|
|
|
|
if borders & 4:
|
|
d = min(d, linedist(x, y, pbottom, pright))
|
|
|
|
if borders & 8:
|
|
d = min(d, linedist(x, y, pbottom, pleft))
|
|
|
|
if corner:
|
|
d = min(d, pointdist(x, y, [None, ptop, pright, pbottom, pleft][corner]))
|
|
# d = D + 1
|
|
# dxa, dxb, dya, dyb = 0, 0, 0, 0
|
|
# if borders & 1 and x < mx and y <= my1:
|
|
# dxa, dya, d = -D, -D, min(d, x + 1, y + 1)
|
|
# if borders & 2 and x >= mx and y <= my2:
|
|
# dxb, dya, d = D, -D, min(d, w - x, y + 1)
|
|
# if borders & 4 and x >= mx and y > my2:
|
|
# dxb, dyb, d = D, D, min(d, w - x, h - y)
|
|
# if borders & 8 and x < mx and y > my1:
|
|
# dxa, dyb, d = -D, D, min(d, x + 1, h - y)
|
|
|
|
# for j in range(max(0, y + dya), min(h, y + dyb + 1)):
|
|
# for i in range(max(0, x + dxa), min(w, x + dxb + 1)):
|
|
# if pixels[i, j] == 0:
|
|
# d = min(d, dist(i, j, x, y))
|
|
# d = min(d, dist(x, y, 31, -1), dist(x, y, 32, -1))
|
|
# d = min(d, dist(x, y, 31, h), dist(x, y, 32, h))
|
|
# d = min(d, dist(x, y, -1, my1), dist(x, y, w, my2))
|
|
if d <= D:
|
|
pixels[x, y] = 0x0f - int(d * 1.4)
|
|
else:
|
|
# pixels[x, y] = int(bool(pixels[x, y])) * 0xD7
|
|
pixels[x, y] = 0
|
|
|
|
return res
|
|
|
|
def process_tile(iimg, oimg, tiledata, x_ofs, y_ofs):
|
|
x, y, w, h, ox, oy = tiledata
|
|
tile = iimg.crop((x, y, x + w, y + h))
|
|
|
|
def add_sprite(res):
|
|
nonlocal x_ofs
|
|
oimg.paste(res, (x_ofs, y_ofs))
|
|
print(f"[{x_ofs:4}, {y_ofs:4}, {w:2}, {h:2}, {ox:3}, {oy:3}]")
|
|
x_ofs += w + SPITE_MARGIN
|
|
|
|
for borders in range(1, 16):
|
|
add_sprite(gen_borders(tile, borders, 0))
|
|
|
|
for corner in range(1, 5):
|
|
add_sprite(gen_borders(tile, 0, corner))
|
|
|
|
return h
|
|
|
|
|
|
iimg = Image.open(TILESHAPES)
|
|
oimg = iimg.crop((0, 0, 19 * (64 + SPITE_MARGIN) + SPITE_MARGIN, 789))
|
|
oimg.load()
|
|
oimg.paste(0xf, (0, 0, oimg.width, oimg.height))
|
|
|
|
x_ofs = SPITE_MARGIN
|
|
y_ofs = SPITE_MARGIN
|
|
for p in TILEDATA:
|
|
h = process_tile(iimg, oimg, p, x_ofs, y_ofs)
|
|
y_ofs += h + SPITE_MARGIN
|
|
oimg.save('sprites/borderhighlight.png')
|
|
oimg.show()
|