Add option to shade trees on slopes
This commit is contained in:
133
grf/cmclient/bordergen.py
Normal file
133
grf/cmclient/bordergen.py
Normal file
@@ -0,0 +1,133 @@
|
||||
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()
|
||||
Reference in New Issue
Block a user