churchianity
6 years ago
6 changed files with 435 additions and 148 deletions
@ -0,0 +1,164 @@ |
|||||
|
--[[ AXIAL/CUBE COORDINATE SYSTEM FOR AMULET/LUA]] |
||||
|
--[[ |
||||
|
|
||||
|
all hexes in functions are assumed to be amulet vectors. |
||||
|
in amulet, vector arithmetic works already with [ + - * / ] |
||||
|
things like equality and distance are implemented here. |
||||
|
|
||||
|
some algorithms use axial coordinates for hexes: vec2(s, t) |
||||
|
others use cube coordinates: vec3(s, t, z) where s + t + z = 0 |
||||
|
this is for simplicity - many algorithms don't care about the |
||||
|
third coordinate, and if they do, the missing coordinate can |
||||
|
be calculated from the other two. |
||||
|
|
||||
|
-- note on orientation: |
||||
|
because of the way amulet draws hexagons, it's much easier to assume |
||||
|
the user wants to use the flat map. rotation after the fact to |
||||
|
achieve other orienations is probably possible, but might have some |
||||
|
aliasing issues. TODO work on this. |
||||
|
|
||||
|
consequently, I have not implemented stretching. all hexagons are |
||||
|
assumed to be regular. you could implement this yourself by making |
||||
|
layout.size a vec2(sizex, sizey), but you would have to play with |
||||
|
transforms in the amulet library if you wanted to use amulet. |
||||
|
|
||||
|
some of the primary resources used to develop this library: |
||||
|
- https://redblobgames.com/grid/hexagons - simply amazing. |
||||
|
- http://amulet.xyz/doc - amulet documentation |
||||
|
- TODO that place that had the inner circle/outer circle ratio?? |
||||
|
|
||||
|
]] |
||||
|
|
||||
|
-- GENERALLY USEFUL CONSTANTS ------------------------------------------------- |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
-- GENERALLY USEFUL FUNCTIONS -------------------------------------------------- |
||||
|
|
||||
|
function round(n) |
||||
|
return n % 1 >= 0.5 and math.ceil(n) or math.floor(n) |
||||
|
end |
||||
|
|
||||
|
function draw_axes(window, node) |
||||
|
xaxis = am.line(vec2(-window.width / 2, 0) , vec2(window.width / 2, 0)) |
||||
|
yaxis = am.line(vec2(0, -window.height / 2), vec2(0, window.height / 2)) |
||||
|
|
||||
|
node:append(xaxis) |
||||
|
node:append(yaxis) |
||||
|
end |
||||
|
|
||||
|
-- HEX CONSTANTS --------------------------------------------------------------- |
||||
|
|
||||
|
-- all possible vector directions from a given hex by edge |
||||
|
HEX_DIRECTIONS = {vec2( 1 , 0), |
||||
|
vec2( 1 , -1), |
||||
|
vec2( 0 , -1), |
||||
|
vec2(-1 , 0), |
||||
|
vec2(-1 , 1), |
||||
|
vec2( 0 , 1)} |
||||
|
|
||||
|
-- HEX UTILITY FUNCTIONS ------------------------------------------------------- |
||||
|
|
||||
|
function hex_equals(a, b) |
||||
|
return a.s == a.t and b.s == b.t |
||||
|
end |
||||
|
|
||||
|
function hex_nequals(a, b) |
||||
|
return not hex_equals(a, b) |
||||
|
end |
||||
|
|
||||
|
function hex_length(hex) |
||||
|
return ((math.abs(hex.s) + math.abs(hex.t) + math.abs(-hex.s - hex.t)) / 2) |
||||
|
end |
||||
|
|
||||
|
function hex_distance(a, b) |
||||
|
return hex_length(a - b) |
||||
|
end |
||||
|
|
||||
|
function hex_direction(direction) |
||||
|
return HEX_DIRECTIONS[direction] |
||||
|
end |
||||
|
|
||||
|
function hex_neighbour(hex, direction) |
||||
|
return hex + HEX_DIRECTIONS[direction] |
||||
|
end |
||||
|
|
||||
|
function hex_round(hex) |
||||
|
rs = round(hex.s) |
||||
|
rt = round(hex.t) |
||||
|
rz = round(-hex.s + -hex.t) |
||||
|
|
||||
|
sdelta = math.abs(rs - hex.s) |
||||
|
tdelta = math.abs(rt - hex.t) |
||||
|
zdelta = math.abs(rz + hex.s + hex.t) |
||||
|
|
||||
|
if sdelta > tdelta and sdelta > zdelta then |
||||
|
rs = -rt - rz |
||||
|
elseif tdelta > zdelta then |
||||
|
rt = -rs - rz |
||||
|
else |
||||
|
rz = -rs - rt |
||||
|
end |
||||
|
|
||||
|
return vec2(rs, rt) |
||||
|
end |
||||
|
|
||||
|
-- COORDINATE CONVERSION FUNCTIONS --------------------------------------------- |
||||
|
|
||||
|
-- forward & inverse matrices used for coordinate conversion |
||||
|
local M = mat2(3.0/2.0, 0.0, 3.0^0.5/2.0, 3.0^0.5 ) |
||||
|
local W = mat2(2.0/3.0, 0.0, -1.0/3.0 , 3.0^0.5/3.0) |
||||
|
|
||||
|
-- hex to screen |
||||
|
function hex_to_pixel(hex, origin) |
||||
|
|
||||
|
x = (M[1][1] * hex.s + M[1][2] * hex.t) * SIZE |
||||
|
y = (M[2][1] * hex.s + M[2][2] * hex.t) * SIZE |
||||
|
|
||||
|
return vec2(x + origin.x, y + origin.y) |
||||
|
end |
||||
|
|
||||
|
-- screen to hex |
||||
|
function pixel_to_hex(pix, origin) |
||||
|
pix = vec2(pix.x - origin.x) / SIZE, |
||||
|
(pix.y - origin.y) / SIZE |
||||
|
|
||||
|
s = W[1][1] * pix.x + W[1][2] * pix.y |
||||
|
t = W[2][1] * pix.x + W[2][2] * pix.y |
||||
|
|
||||
|
return hex_round(vec2(s, t)) |
||||
|
end |
||||
|
|
||||
|
-- MAP FUNCTIONS --------------------------------------------------------------- |
||||
|
|
||||
|
function hexagonal_map(radius, origin) |
||||
|
for s = -radius, radius do |
||||
|
t1 = math.max(-radius, -s - radius) |
||||
|
t2 = math.min(radius, -s + radius) |
||||
|
|
||||
|
for t = t1, t2 do |
||||
|
|
||||
|
color = vec4(math.random(20, 80) / 100, |
||||
|
math.random(20, 80) / 100, |
||||
|
math.random(20, 80) / 100, |
||||
|
1) |
||||
|
|
||||
|
map:append(am.circle(hex_to_pixel(vec2(s, t)), 24, color, 6)) |
||||
|
end |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
function rectangular_map(width, height, origin) |
||||
|
for s = 0, height do |
||||
|
soffset = math.floor(s / 2) |
||||
|
|
||||
|
for t = -soffset, width - soffset do |
||||
|
|
||||
|
center = hex_to_pixel(vec2(s, t)) |
||||
|
end |
||||
|
end |
||||
|
end |
||||
|
--]] |
||||
|
|
@ -0,0 +1,67 @@ |
|||||
|
----- [[ WARZONE 2 - HEXAGONAL GRID RESOURCE BASED TOWER DEFENSE GAME]] -------- |
||||
|
--[[ author@churchianity.ca |
||||
|
]] |
||||
|
|
||||
|
require "hex" |
||||
|
require "util" |
||||
|
|
||||
|
local win = am.window{ |
||||
|
-- BASE RESOLUTION = 3/4 * WXGA Standard 16:10 |
||||
|
width = 1280 * 3 / 4, -- 960px |
||||
|
height = 800 * 3 / 4, -- 600px |
||||
|
|
||||
|
title = "Warzone 2: Electric Boogaloo"} |
||||
|
|
||||
|
local title = am.group() |
||||
|
local world = am.group() |
||||
|
local layout = hex_layout(vec2(-368, win.bottom)) |
||||
|
local map = hex_rectangular_map(45, 31) |
||||
|
|
||||
|
|
||||
|
|
||||
|
function show_axes() |
||||
|
xaxis = am.line(vec2(win.left, 0), vec2(win.right, 0)) |
||||
|
yaxis = am.line(vec2(0, win.top), vec2(0, win.bottom)) |
||||
|
world:append(am.group{xaxis, yaxis}:tag("axes")) |
||||
|
end |
||||
|
|
||||
|
function world_init() |
||||
|
world:action(coroutine.create(function() |
||||
|
for hex,_ in pairs(map) do |
||||
|
world:append(am.circle(hex_to_pixel(hex, layout), 11, rrgb(1), 6)) |
||||
|
am.wait(am.delay(0.01)) |
||||
|
end |
||||
|
end)) |
||||
|
|
||||
|
end |
||||
|
|
||||
|
function init() |
||||
|
titlemap = am.group() |
||||
|
|
||||
|
for hex,_ in pairs(map) do |
||||
|
titlemap:append(am.rotate(45):tag("titlemap") |
||||
|
^ am.scale(3, 2) |
||||
|
^ am.circle(hex_to_pixel(hex, layout), 11, rrgb(1), 6)) |
||||
|
end |
||||
|
|
||||
|
local line1 = am.text("WARZONE 2") |
||||
|
local line2 = am.text("Electric Boogaloo") |
||||
|
local line3 = am.text("by Nick Hayashi") |
||||
|
local title = am.group{titlemap, |
||||
|
am.translate(0, 150) ^ am.scale(4) ^ line1, |
||||
|
am.translate(0, 100) ^ am.scale(3) ^ line2, |
||||
|
am.translate(0, 60) ^ am.scale(1) ^ line3 |
||||
|
}:action(function() |
||||
|
while true do |
||||
|
titlemap"titlemap".angle = am.frame_time * 4 |
||||
|
end |
||||
|
end) |
||||
|
|
||||
|
|
||||
|
win.scene = title |
||||
|
end |
||||
|
|
||||
|
----- [[ MAIN ]] --------------------------------------------------------------- |
||||
|
|
||||
|
init() |
||||
|
|
@ -0,0 +1,61 @@ |
|||||
|
----- INTRODUCTION [1.1] --------------------------------------------------- |
||||
|
--[[ author@churchianity.ca |
||||
|
|
||||
|
this is a library for using hexagonal grids in amulet/lua. |
||||
|
it is extremely incomplete. the following list of features is |
||||
|
either implemented shoddily, or not at all. |
||||
|
|
||||
|
if you want an actual good resource, go to [1.9]. |
||||
|
|
||||
|
----- COORDINATE SYSTEMS [1.2] ---------------------------------------------- |
||||
|
|
||||
|
* as much coordinate manipulation as possible is done internally. |
||||
|
depending on the task, uses either Axial, Cube, or Doubled coordinates. |
||||
|
|
||||
|
* three different ways of returning and sending coordinates: |
||||
|
|
||||
|
1) amulet vectors |
||||
|
2) lua tables |
||||
|
3) individual coordinate numbers |
||||
|
|
||||
|
so you can use what your graphics library likes best! |
||||
|
|
||||
|
----- MAPS & MAP STORAGE [1.3] ------------------------------------------------- |
||||
|
|
||||
|
some map shapes: parallelogram, rectangular, hexagonal, triangular. (and more) |
||||
|
* storage system based on map shape - see chart: |
||||
|
|
||||
|
________________________________________________________________________ |
||||
|
| SHAPE : MAP STORAGE | |
||||
|
|------------------------------------------------------------------------| |
||||
|
| parallelogram : unordered, hash-like OR ordered, array-like | |
||||
|
| rectangular : unordered, hash-like OR ordered, array-like | |
||||
|
| hexagonal : unordered, hash-like OR ordered, array-like | |
||||
|
| triangular : unordered, hash-like OR ordered, array-like | |
||||
|
| ring : ordered, array-like | |
||||
|
| spiral : ordered, array-like** | |
||||
|
| arbitrary : unordered, hash-like | |
||||
|
|________________________________________________________________________| |
||||
|
** note that a spiral map is just a hexagonal one with a particular order. |
||||
|
|
||||
|
|
||||
|
----- CONVENTIONS AND TERMINOLOGY [1.8] ----------------------------------------- |
||||
|
|
||||
|
because so many different kinds of coordinate pairs, trios |
||||
|
|
||||
|
|
||||
|
----- RESOURCES USED TO DEVELOP THIS LIBRARY, AND FOR WHICH I AM GRATEFUL [1.9] - |
||||
|
|
||||
|
* https://catlikecoding.com/unity/tutorials/hex-map/ |
||||
|
-> unity tutorial for hexagon grids with some useful generalized math. |
||||
|
|
||||
|
* https://youtube.com/watch?v=fNk_zzaMoSs&list=PLZHQObOWTQDPD3MizzM2xVFitgF8hE_ab |
||||
|
-> amazing series on linear algebra by 3Blue1Brown |
||||
|
|
||||
|
* https://redblobgames.com/grid/hexagons |
||||
|
-> now THE resource on hexagonal grids on the internet. |
||||
|
|
||||
|
* http://amulet.xyz/doc |
||||
|
-> amulet documentation. |
||||
|
]] |
||||
|
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue