hexyz is tower defense game, and a lua library for dealing with hexagonal grids
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

188 lines
5.9 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. ----- [[ AXIAL/CUBE COORDINATE SYSTEM FOR AMULET/LUA]] -------------------------
  2. --[[ author@churchianity.ca
  3. -- INTRODUCTION
  4. this is a hexagonal grid library for amulet/lua.
  5. it uses axial coordinates or cube/hex coordinates when necessary.
  6. by amulet convention, hexes are either vec2(s, t) or vec3(s, t, z)
  7. but nearly always the former.
  8. in some rare cases, coordinates will be passed individually, usually
  9. because they are only passed internally and should never be adjusted
  10. directly.
  11. in amulet, vector arithmetic already works via: + - * /
  12. additional things such as equality, and distance are implemented here.
  13. +support for parallelogram, triangular, hexagonal and rectangular maps.
  14. +support for simple irregular hexagons (horizontal and vertical stretching).
  15. classes are used sparsely. maps implement a few constructors, for storing
  16. your maps elsewhere.
  17. -- RESOURCES USED TO DEVELOP THIS LIBRARY
  18. https://redblobgames.com/grid/hexagons - simply amazing.
  19. http://amulet.xyz/doc - amulet documentation
  20. TODO that place that had the inner circle/outer circle ratio??
  21. ]]
  22. ----- [[ GENERALLY USEFUL FUNCTIONS ]] -----------------------------------------
  23. -- just incase you don't already have a rounding function.
  24. local function round(n)
  25. return n % 1 >= 0.5 and math.ceil(n) or math.floor(n)
  26. end
  27. ---- [[ HEX CONSTANTS ]] -------------------------------------------------------
  28. -- all possible vector directions from a given hex by edge
  29. local HEX_DIRECTIONS = {vec2( 1 , 0),
  30. vec2( 1 , -1),
  31. vec2( 0 , -1),
  32. vec2(-1 , 0),
  33. vec2(-1 , 1),
  34. vec2( 0 , 1)}
  35. -- HEX UTILITY FUNCTIONS -------------------------------------------------------
  36. local function hex_round(s, t)
  37. rs = round(s)
  38. rt = round(t)
  39. rz = round(-s - t)
  40. sdelta = math.abs(rs - s)
  41. tdelta = math.abs(rt - t)
  42. zdelta = math.abs(rz - (-s - t))
  43. if sdelta > tdelta and sdelta > zdelta then
  44. rs = -rt - rz
  45. elseif tdelta > zdelta then
  46. rt = -rs - rz
  47. else
  48. rz = -rs - rt
  49. end
  50. return vec2(rs, rt)
  51. end
  52. ----- [[ LAYOUT, ORIENTATION & COORDINATE CONVERSION ]] -----------------------
  53. -- forward & inverse matrices used for the flat orientation.
  54. local FLAT = {3.0/2.0, 0.0, 3.0^0.5/2.0, 3.0^0.5,
  55. 2.0/3.0, 0.0, -1.0/3.0 , 3.0^0.5/3.0}
  56. -- forward & inverse matrices used for the pointy orientation.
  57. local POINTY = {3.0^0.5, 3.0^0.5/2.0, 0.0, 3.0/2.0,
  58. 3.0^0.5/3.0, -1.0/3.0, 0.0, 2.0/3.0}
  59. -- layout.
  60. function layout_init(origin, size, orientation)
  61. return {origin = origin or vec2(0),
  62. size = size or vec2(11),
  63. orientation = orientation or FLAT}
  64. end
  65. -- hex to screen
  66. function hex_to_pixel(hex, layout)
  67. M = layout.orientation
  68. x = (M[1] * hex.s + M[2] * hex.t) * layout.size.x
  69. y = (M[3] * hex.s + M[4] * hex.t) * layout.size.y
  70. return vec2(x + layout.origin.x, y + layout.origin.y)
  71. end
  72. -- screen to hex
  73. function pixel_to_hex(pix, layout)
  74. M = layout.orientation
  75. pix = (pix - layout.origin) / layout.size
  76. s = M[5] * pix.x + M[6] * pix.y
  77. t = M[7] * pix.x + M[8] * pix.y
  78. return hex_round(s, t)
  79. end
  80. ----- [[ MAP STORAGE & RETRIEVAL ]] --------------------------------------------
  81. --[[ _init functions return a table of tables;
  82. a map of points in a chosen shape and specified layout.
  83. the shape, as well as the layout used is stored in a metatable
  84. for reuse.
  85. ]]
  86. -- returns parallelogram-shaped map.
  87. function map_parallelogram_init(layout, width, height)
  88. map = {}
  89. setmetatable(map, {__index={layout=layout,
  90. width=width,
  91. height=height,
  92. shape="parallelogram"}})
  93. for s = 0, width do
  94. for t = 0, height do
  95. table.insert(map, hex_to_pixel(vec2(s, t), layout))
  96. end
  97. end
  98. return map
  99. end
  100. -- returns triangular map.
  101. function map_triangular_init(layout, size)
  102. map = {}
  103. setmetatable(map, {__index={layout=layout,
  104. size=size,
  105. shape="triangular"}})
  106. for s = 0, size do
  107. for t = size - s, size do
  108. table.insert(map, hex_to_pixel(vec2(s, t), layout))
  109. end
  110. end
  111. return map
  112. end
  113. -- returns hexagonal map. length of map is radius * 2 + 1
  114. function map_hexagonal_init(layout, radius)
  115. map = {}
  116. setmetatable(map, {__index={layout=layout,
  117. radius=radius,
  118. shape="hexagonal"}})
  119. for s = -radius, radius do
  120. t1 = math.max(-radius, -s - radius)
  121. t2 = math.min(radius, -s + radius)
  122. for t = t1, t2 do
  123. table.insert(map, hex_to_pixel(vec2(s, t), layout))
  124. end
  125. end
  126. return map
  127. end
  128. -- returns rectangular map.
  129. function map_rectangular_init(layout, width, height)
  130. map = {}
  131. mt = {__index = {layout = layout, width = width, height = height,
  132. retrieve = function(pix)
  133. hex = pixel_to_hex(pix, layout)
  134. print(tostring(hex))
  135. print(map[tostring(hex)])
  136. return vec2(hex.s, hex.t + math.floor(hex.s / 2))
  137. end,
  138. store = function(hex)
  139. pix = hex_to_pixel(hex, layout)
  140. return vec2(pix.x - math.floor(pix.y / 2), pix.y)
  141. end}}
  142. for s = 0, width do
  143. soffset = math.floor(s/2)
  144. for t = -soffset, height - soffset do
  145. map[tostring(vec2(s, t))] = hex_to_pixel(vec2(s, t), layout)
  146. end
  147. end
  148. setmetatable(map, mt)
  149. return map
  150. end