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.

182 lines
5.3 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. require"hex"
  2. require"util"
  3. require"sprites"
  4. --[[============================================================================
  5. ----- COLOR CONSTANTS -----
  6. ============================================================================]]--
  7. local EIGENGRAU = vec4(0.08, 0.08, 0.11, 1)
  8. -- Ethan Schoonover Solarized Colorscheme
  9. local BASE03 = vec4(0 , 0.16, 0.21, 1)
  10. local BASE02 = vec4(0.02, 0.21, 0.25, 1)
  11. local BASE01 = vec4(0.34, 0.43, 0.45, 1)
  12. local BASE00 = vec4(0.39, 0.48, 0.51, 1)
  13. local BASE0 = vec4(0.51, 0.58, 0.58, 1)
  14. local BASE1 = vec4(0.57, 0.63, 0.63, 1)
  15. local BASE2 = vec4(0.93, 0.90, 0.83, 1)
  16. local BASE3 = vec4(0.99, 0.96, 0.89, 1)
  17. local YELLOW = vec4(0.70, 0.53, 0 , 1)
  18. local ORANGE = vec4(0.79, 0.29, 0.08, 1)
  19. local RED = vec4(0.86, 0.19, 0.18, 1)
  20. local MAGENTA = vec4(0.82, 0.21, 0.50, 1)
  21. local VIOLET = vec4(0.42, 0.44, 0.76, 1)
  22. local BLUE = vec4(0.14, 0.54, 0.82, 1)
  23. local CYAN = vec4(0.16, 0.63, 0.59, 1)
  24. local GREEN = vec4(0.52, 0.60, 0 , 1)
  25. am.ascii_color_map =
  26. {
  27. E = EIGENGRAU,
  28. K = BASE03,
  29. k = BASE02,
  30. L = BASE01,
  31. l = BASE00,
  32. s = BASE0,
  33. S = BASE1,
  34. w = BASE2,
  35. W = BASE3,
  36. y = YELLOW,
  37. o = ORANGE,
  38. r = RED,
  39. m = MAGENTA,
  40. v = VIOLET,
  41. b = BLUE,
  42. c = CYAN,
  43. g = GREEN
  44. }
  45. --[[============================================================================
  46. ----- SETUP -----
  47. ============================================================================]]--
  48. local win = am.window
  49. { -- base resolution = 3/4 * WXGA standard 16:10
  50. width = 1280 * 3/4, -- 960px
  51. height = 800 * 3/4, -- 600px
  52. clear_color = BASE03
  53. }
  54. local map = rectangular_map(45, 31)
  55. local layout = layout(vec2(-268, win.top - 10))
  56. --[[============================================================================
  57. ----- SCENE GRAPH / NODES -----
  58. ============================================================================]]--
  59. local panel; local world; local game --[[
  60. panel
  61. |
  62. +------> game ------> win.scene
  63. |
  64. world
  65. ]]--
  66. local backdrop; local menu; local title --[[
  67. backdrop
  68. |
  69. +------> title ------> win.scene
  70. |
  71. menu
  72. --[[============================================================================
  73. ----- FUNCTIONS -----
  74. ============================================================================]]--
  75. function keep_time()
  76. local offset = am.current_time()
  77. world:action(function()
  78. world:remove("time")
  79. local time_str = string.format("%.2f", am.current_time() - offset)
  80. world:append(
  81. am.translate(-374, win.top - 10)
  82. ^ am.text(time_str):tag"time")
  83. end)
  84. end
  85. -- TODO refactor to something like - poll-mouse or mouse-hover event
  86. function show_coords()
  87. game:action(function()
  88. game:remove("coords")
  89. game:remove("selected")
  90. local hex = pixel_to_cube(win:mouse_position(), layout)
  91. local mouse = cube_to_offset(hex)
  92. -- check mouse is within bounds of game map
  93. if mouse.x > 0 and mouse.x < map.width and
  94. mouse.y > 0 and mouse.y < map.height then
  95. local text = am.text(string.format("%d,%d", mouse.x, mouse.y))
  96. local coords = am.group{
  97. am.translate(win.right - 25, win.top - 10)
  98. ^ am.text(string.format("%d,%d", mouse.x, mouse.y)):tag"coords"}
  99. world:append(coords)
  100. local color = vec4(1)
  101. local pix = cube_to_pixel(hex, layout)
  102. world:append(am.circle(pix, layout.size.x, color, 6):tag"selected")
  103. end
  104. end)
  105. end
  106. function title_init()
  107. backdrop = am.group{}:tag"backdrop"
  108. menu = am.group{}:tag"menu"
  109. title = am.group{menu, backdrop}:tag"title"
  110. end
  111. function game_init()
  112. -- setup nodes
  113. world = am.group{}:tag"world"
  114. panel = am.group{}:tag"panel"
  115. game = am.group{world, panel}:tag"game"
  116. -- render world
  117. world:action(coroutine.create(function()
  118. -- background panel for gui elements
  119. panel:append(am.rect(win.left, win.top, -268, win.bottom):tag"bg")
  120. -- begin map generation
  121. for hex,noise in pairs(map) do
  122. -- determine cell color based on noise
  123. local color = vec4((noise + 1) / 2)
  124. -- determine cell shading mask based on map position
  125. local off = cube_to_offset(hex)
  126. local mask = vec4(0, 0, 0, math.max(((off.x-23)/30)^2,
  127. ((off.y-16)/20)^2))
  128. -- determine hexagon center for drawing
  129. local center = cube_to_pixel(hex, layout)
  130. -- prepend hexagon to screen
  131. world:prepend(am.circle(center, 11, color, 6):tag(tostring(hex)))
  132. am.wait(am.delay(0.01))
  133. -- fade in bg panel
  134. panel"bg".color = BASE03/am.frame_time
  135. end
  136. show_coords() -- mouse-hover events
  137. keep_time() -- scoring
  138. end))
  139. -- make it so
  140. win.scene = game
  141. end
  142. --[[============================================================================
  143. ----- MAIN -----
  144. ============================================================================]]--
  145. game_init()