aka gravity ninja golf
at main 85 lines 2.6 kB view raw
1extends Node2D 2 3var polyinner: PackedVector2Array 4var colyinner: PackedColorArray 5var polyouter: PackedVector2Array 6var colyouter: PackedColorArray 7var BOUNDS: Rect2 8 9 10func initialize(fg: Color, bounds: Rect2): 11 colyinner = [] 12 colyinner.resize(11 + 14 + 2) 13 colyinner.fill(fg) 14 15 colyouter = [] 16 colyouter.resize(23 + 19 + 2) 17 colyouter.fill(fg) 18 BOUNDS = bounds 19 sketch() 20 21func sketch(): 22 polyinner = genring(genpolygon(11, 14.0, 1.0), genpolygon(14, 28.0, 1.1)) 23 polyouter = genring(genpolygon(19, 50.0, 1.3), genpolygon(23, 62.0, 1.5)) 24 queue_redraw() 25 26func _draw(): 27 for dx in [-1, 0, 1]: 28 for dy in [-1, 0, 1]: 29 draw_polygon(offsetpoly(polyouter, dx, dy), colyouter) 30 draw_polygon(offsetpoly(polyinner, dx, dy), colyinner) 31 32func offsetpoly(a: PackedVector2Array, dx: int, dy: int) -> PackedVector2Array: 33 if dx == 0 && dy == 0: return a 34 var offset = Vector2.ZERO 35 offset.x = dx * BOUNDS.size.x 36 offset.y = dy * BOUNDS.size.y 37 var res: PackedVector2Array = [] 38 res.resize(a.size()) 39 for i in range(a.size()): 40 res[i] = a[i] + offset 41 return res 42 43## genring takes an [param inner] polygon and an [param outer] polygon, and concatenates them so that 44## they form a polygon with the inner polygon cut out from the outer polygon. doesn't do any checks 45## to make sure that the polygon actually tesselates, but it does pick the best point in the inner polygon 46## to connect to the first point from the outer polygon 47func genring(inner: PackedVector2Array, outer: PackedVector2Array) -> PackedVector2Array: 48 var res: PackedVector2Array = [] 49 res.resize(inner.size() + outer.size() + 2) 50 for i in range(outer.size()): 51 res[i] = outer[i] 52 var fouter = outer[0] 53 res[outer.size()] = fouter 54 var bi: int = -1 55 var best: float = 100000.0 56 for j in range(inner.size()): 57 var nl = (fouter - inner[j]).length() 58 if nl < best: 59 best = nl 60 bi = j 61 var os = outer.size() + 1 62 for j in range(inner.size()): 63 var idx = (inner.size() - j + bi) % inner.size() 64 res[os + j] = inner[idx] 65 res[os + inner.size()] = inner[bi] 66 return res 67 68## genpolygon generates a (nonconvex polygon) with [param n] vertices, and the given [param radius] 69## and [param deviation] 70func genpolygon(n: int, radius: float, deviation: float) -> PackedVector2Array: 71 var rads = [] 72 rads.resize(n) 73 var rots = [] 74 rots.resize(n) 75 var rsum = 0 76 for i in range(n): 77 rads[i] = randfn(radius, deviation) 78 rots[i] = rsum + randf() + .2 79 rsum = rots[i] 80 var poly = PackedVector2Array() 81 poly.resize(n) 82 var randrot = randf() * TAU 83 for i in range(n): 84 poly[i] = Vector2(rads[i], 0).rotated(rots[i] / rsum * TAU + randrot) 85 return poly