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.6 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
  1. ----- [[ AXIAL/CUBE COORDINATE SYSTEM FOR AMULET/LUA]] -------------------------
  2. --[[ author@churchianity.ca
  3. -- INTRODUCTION
  4. this is a library for making grids of hexagons using lua.
  5. it has made use of exclusively standard lua 5.2 functionality,
  6. making it as portable as possible. it doesn't even use a point
  7. class, (or classes/metatables at all) simply returning tables
  8. of integers, which can later be unpacked into your amulet
  9. vectors, or whatever else you want to use.
  10. this can result in some nasty looking lines with lots of table
  11. unpacks, but if your graphics library likes traditional lua
  12. types, you will be better off.
  13. it supports triangular, hexagonal, rectangular, and
  14. parallelogram map shapes.
  15. it supports non-regular hexagons, though it's trickier to get
  16. working in amulet. TODO work on this.
  17. -- NOTE ON ORIENTATION + AMULET
  18. because of the way amulet draws hexagons (amulet essentially
  19. draws a 6-sided circle from a centerpoint, instead of of a
  20. series of lines connecting points), the flat orientation is
  21. default and recommended. other orientations are possible
  22. with am.rotate, but can cause aliasing issues. TODO work on this.
  23. -- RESOURCES USED TO DEVELOP THIS LIBRARY
  24. https://redblobgames.com/grid/hexagons - simply amazing. amit is a god.
  25. http://amulet.xyz/doc - amulet documentation
  26. TODO that place that had the inner circle/outer circle ratio??
  27. ]]
  28. ----- [[ GENERALLY USEFUL FUNCTIONS ]] -----------------------------------------
  29. -- just incase you don't already have a rounding function.
  30. function round(n)
  31. return n % 1 >= 0.5 and math.ceil(n) or math.floor(n)
  32. end
  33. ---- [[ HEX CONSTANTS ]] -------------------------------------------------------
  34. -- all possible vector directions from a given hex by edge
  35. HEX_DIRECTIONS = {{ 1 , 0},
  36. { 1 , -1},
  37. { 0 , -1},
  38. {-1 , 0},
  39. {-1 , 1},
  40. { 0 , 1}}
  41. -- HEX UTILITY FUNCTIONS -------------------------------------------------------
  42. function hex_round(s, t)
  43. rs = round(s)
  44. rt = round(t)
  45. rz = round(-s - t)
  46. sdelta = math.abs(rs - s)
  47. tdelta = math.abs(rt - t)
  48. zdelta = math.abs(rz - (-s - t))
  49. if sdelta > tdelta and sdelta > zdelta then
  50. rs = -rt - rz
  51. elseif tdelta > zdelta then
  52. rt = -rs - rz
  53. else
  54. rz = -rs - rt
  55. end
  56. return {rs, rt}
  57. end
  58. ----- [[ LAYOUT, ORIENTATION & COORDINATE CONVERSION ]] -----------------------
  59. -- forward & inverse matrices used for the flat orientation.
  60. FLAT_ORIENTATION = {3.0/2.0, 0.0, 3.0^0.5/2.0, 3.0^0.5,
  61. 2.0/3.0, 0.0, -1.0/3.0 , 3.0^0.5/3.0}
  62. -- forward & inverse matrices used for the pointy orientation.
  63. POINTY_ORIENTATION = {3.0^0.5, 3.0^0.5/2.0, 0.0, 3.0/2.0,
  64. 3.0^0.5/3.0, -1.0/3.0, 0.0, 2.0/3.0}
  65. -- layout.
  66. function layout_init(origin, size, orientation)
  67. return {origin = origin or {0, 0},
  68. size = size or {11, 11},
  69. orientation = orientation or FLAT_ORIENTATION}
  70. end
  71. -- hex to screen
  72. function hex_to_pixel(s, t, layout)
  73. M = layout.orientation
  74. x = (M[1] * s + M[2] * t) * layout.size[1]
  75. y = (M[3] * s + M[4] * t) * layout.size[2]
  76. return {x + layout.origin[1], y + layout.origin[2]}
  77. end
  78. -- screen to hex
  79. function pixel_to_hex(x, y, layout)
  80. M = layout.orientation
  81. px = {(x - layout.origin[1]) / layout.size[1],
  82. (y - layout.origin[2]) / layout.size[2]}
  83. s = M[5] * px[1] + M[6] * px[2]
  84. t = M[7] * px[1] + M[8] * px[2]
  85. return hex_round(s, t)
  86. end
  87. ----- [[ MAP STORAGE & RETRIEVAL ]] --------------------------------------------
  88. --[[ _init functions return a table of tables;
  89. a map of points in a chosen shape and specified layout.
  90. the shape, as well as the layout used is stored in a metatable
  91. for reuse.
  92. ]]
  93. -- returns parallelogram-shaped map.
  94. function map_parallelogram_init(layout, width, height)
  95. map = {}
  96. setmetatable(map, {__index={layout=layout, shape=parallelogram}})
  97. for s = 0, width do
  98. for t = 0, height do
  99. table.insert(map, hex_to_pixel(s, t, layout))
  100. end
  101. end
  102. return map
  103. end
  104. -- returns triangular map.
  105. function map_triangular_init(layout, size)
  106. map = {}
  107. setmetatable(map, {__index={layout=layout, shape=triangular}})
  108. for s = 0, size do
  109. for t = size - s, size do
  110. table.insert(map, hex_to_pixel(s, t, layout))
  111. end
  112. end
  113. return map
  114. end
  115. -- returns hexagonal map. length of map is radius * 2 + 1
  116. function map_hexagonal_init(layout, radius)
  117. map = {}
  118. setmetatable(map, {__index={layout=layout, 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(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. setmetatable(map, {__index={layout=layout, shape=rectangular}})
  132. for s = 0, width do
  133. soffset = math.floor(s/2)
  134. for t = -soffset, height - soffset do
  135. table.insert(map, hex_to_pixel(s, t, layout))
  136. end
  137. end
  138. return map
  139. end
  140. -- places single hex into map table, if it is not already present.
  141. function map_store(map)
  142. end
  143. -- retrieves single hex from map table, if it is present.
  144. function map_retrieve(map)
  145. end