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.

177 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. ----- WINDOW 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. --[[============================================================================
  55. ============================================================================]]--
  56. local map = rectangular_map(45, 31)
  57. local layout = layout(vec2(-268, win.top - 10))
  58. --[[============================================================================
  59. ----- SCENE GRAPH / NODES -----
  60. ============================================================================]]--
  61. local panel; local world; local game; --[[
  62. panel
  63. |
  64. #------> game ------> win.scene
  65. |
  66. world
  67. --==========================================================================]]--
  68. local backdrop; local menu; local title; --[[
  69. backdrop
  70. |
  71. #------> title ------> win.scene
  72. |
  73. menu
  74. --[[============================================================================
  75. ----- FUNCTIONS -----
  76. ============================================================================]]--
  77. function keep_time()
  78. local offset = am.current_time()
  79. world:action(function()
  80. world:remove("time")
  81. local time_str = string.format("%.2f", am.current_time() - offset)
  82. world:append(
  83. am.translate(-374, win.top - 10)
  84. ^ am.text(time_str):tag"time")
  85. end)
  86. end
  87. -- TODO refactor to something like - poll-mouse or mouse-hover event
  88. function show_coords()
  89. game:action(function()
  90. game:remove("coords")
  91. game:remove("select")
  92. local hex = pixel_to_cube(win:mouse_position(), layout)
  93. local mouse = cube_to_offset(hex)
  94. if mouse.x > 0 and mouse.x < map.width and
  95. mouse.y > 0 and mouse.y < map.height then
  96. local text = am.text(string.format("%d,%d", mouse.x, mouse.y))
  97. local coords = am.group{
  98. am.translate(win.right - 25, win.top - 10)
  99. ^ am.text(string.format("%d,%d", mouse.x, mouse.y)):tag"coords"}
  100. world:append(coords)
  101. local color = vec4(1, 1, 1, 0.2)
  102. local pix = cube_to_pixel(hex, layout)
  103. world:append(am.circle(pix, layout.size.x, color, 6):tag"select")
  104. end
  105. end)
  106. end
  107. function title_init()
  108. backdrop = am.group{}:tag"backdrop"
  109. menu = am.group{}:tag"menu"
  110. title = am.group{menu, backdrop}:tag"title"
  111. end
  112. function game_init()
  113. world = am.group{}:tag"world"
  114. panel = am.group{}:tag"panel"
  115. game = am.group{world, panel}:tag"game"
  116. local hexes = {}
  117. for cube,_ in pairs(map) do
  118. hexes[math.perlin(cube)] = cube_to_pixel(cube, layout)
  119. end
  120. world:action(coroutine.create(function()
  121. panel:append(am.rect(win.left, win.top, -268, win.bottom):tag"bg")
  122. for noise, hex in pairs(hexes) do
  123. local off = cube_to_offset(hex)
  124. local tag = tostring(hex)
  125. -- determine cell shading mask based on map position
  126. local mask = vec4(0, 0, 0, math.max(((off.x-23)/30)^2,
  127. ((off.y-16)/20)^2))
  128. -- determine cell color based on noise
  129. local color = vec4(math.random()) - mask
  130. panel"bg".color = BASE03/am.frame_time
  131. world:prepend(am.circle(hex, 11, color, 6):tag(tag))
  132. am.wait(am.delay(0.01))
  133. end
  134. show_coords()
  135. keep_time()
  136. end))
  137. win.scene = game
  138. end
  139. --[[============================================================================
  140. ----- MAIN -----
  141. ============================================================================]]--
  142. game_init()