diff --git a/src/hexyz.lua b/src/hexyz.lua index 5851d49..8ef8eee 100644 --- a/src/hexyz.lua +++ b/src/hexyz.lua @@ -1,9 +1,5 @@ ---[[============================================================================ - ----- GENERALLY USEFUL FUNCTIONS ----- -============================================================================]]-- - --- rounds numbers. would've been cool to have math.round in lua. +-- Rounds Numbers. local function round(n) return n % 1 >= 0.5 and math.ceil(n) or math.floor(n) end @@ -12,35 +8,40 @@ end ----- HEX CONSTANTS AND UTILITY FUNCTIONS ----- ============================================================================]]-- --- all possible vector directions from a given hex by edge -local HEX_DIRECTIONS = {vec2( 0 , 1), - vec2( 1 , 0), - vec2( 1 , -1), - vec2( 0 , -1), - vec2(-1 , 0), - vec2(-1 , 1)} +-- Hex Equality - Meant to Operate on two Amulet Vectors (vec2) +function hex_equals(a, b) return a[1] == b[1] and a[2] == b[2] end +function hex_not_equals(a, b) return not hex_equals(a, b) end + --- return hex vector direction via integer index |direction|. +-- All Possible Vector Directions from a Given Hex by Edge +local HEX_DIRECTIONS = {vec2( 0 , 1), vec2( 1 , 0), vec2( 1 , -1), + vec2( 0 , -1), vec2(-1 , 0), vec2(-1 , 1)} + +-- Return Hex Vector Direction via Integer Index |direction|. function hex_direction(direction) return HEX_DIRECTIONS[(direction % 6) % 6 + 1] end --- return hexagon adjacent to |hex| in integer index |direction|. + +-- Return Hexagon Adjacent to |hex| in Integer Index |direction|. function hex_neighbour(hex, direction) return hex + HEX_DIRECTIONS[(direction % 6) % 6 + 1] end --- return cube coords at location 60deg away to the left; counter-clockwise + +-- Return Hex 60deg away to the Left; Counter-Clockwise function hex_rotate_left(hex) return vec2(hex.x + hex.y, -hex.x) end --- return cube coords at location 60deg away to the right; clockwise + +-- Return Hex 60deg away to the Right; Clockwise function hex_rotate_right(hex) return vec2(-hex.y, hex.x + hex.y) end --- rounds a float coordinate trio |x, y, z| to nearest integer coordinate trio + +-- NOT a General 3D Vector Round - Only Returns a vec2! local function hex_round(x, y, z) local rx = round(x) local ry = round(y) @@ -60,66 +61,66 @@ local function hex_round(x, y, z) return vec2(rx, ry) end ---[[============================================================================ +--[[==========================================================================-- ----- ORIENTATION & LAYOUT ----- ============================================================================]]-- --- forward & inverse matrices used for the flat orientation + +-- Forward & Inverse Matrices used for the Flat Orientation local FLAT = {M = mat2(3.0/2.0, 0.0, 3.0^0.5/2.0, 3.0^0.5 ), W = mat2(2.0/3.0, 0.0, -1.0/3.0 , 3.0^0.5/3.0), - start_angle = 0.0} + angle = 0.0} --- forward & inverse matrices used for the pointy orientation +-- Forward & Inverse Matrices used for the Pointy Orientation local POINTY = {M = mat2(3.0^0.5, 3.0^0.5/2.0, 0.0, 3.0/2.0), W = mat2(3.0^0.5/3.0, -1.0/3.0, 0.0, 2.0/3.0), - start_angle = 0.5} + angle = 0.5} --- stores layout: information that does not pertain to map shape -function layout(origin, size, orientation) - return {origin = origin or vec2(0), - size = size or vec2(11), - orientation = orientation or FLAT} -end --- hex to screen -function hex_to_pixel(hex, layout) - local M = layout.orientation.M +-- Hex to Screen -- Orientation Must be Either POINTY or FLAT +function hex_to_pixel(hex, size, orientation_M) + local M = orientation_M or FLAT.M - local x = (M[1][1] * hex[1] + M[1][2] * hex[2]) * layout.size[1] - local y = (M[2][1] * hex[1] + M[2][2] * hex[2]) * layout.size[2] + local x = (M[1][1] * hex[1] + M[1][2] * hex[2]) * size[1] + local y = (M[2][1] * hex[1] + M[2][2] * hex[2]) * size[2] - return vec2(x + layout.origin[1], y + layout.origin[2]) + return vec2(x, y) end --- screen to hex -function pixel_to_hex(pix, layout) - local W = layout.orientation.W - local pix = (pix - layout.origin) / layout.size +-- Screen to Hex -- Orientation Must be Either POINTY or FLAT +function pixel_to_hex(pix, size, orientation_W) + local W = orientation_W or FLAT.W + + local pix = pix / size - local s = W[1][1] * pix[1] + W[1][2] * pix[2] - local t = W[2][1] * pix[1] + W[2][2] * pix[2] + local x = W[1][1] * pix[1] + W[1][2] * pix[2] + local y = W[2][1] * pix[1] + W[2][2] * pix[2] - return hex_round(s, t, -s - t) + return hex_round(x, y, -x - y) end + -- TODO test, learn am.draw -function hex_corner_offset(corner, layout) - local angle = 2.0 * math.pi * layout.orientation.start_angle + corner / 6 - return vec2(layout.size[1] * math.cos(angle), - layout.size[2] * math.sin(angle)) +function hex_corner_offset(corner, size, orientation_angle) + local angle = 2.0 * math.pi * orientation_angle or FLAT.angle + corner / 6 + return vec2(size[1] * math.cos(angle), + size[2] * math.sin(angle)) end + -- TODO this thing -function hex_corners(hex, layout) +function hex_corners(hex, size, orientation) local corners = {} end --- offset coordinates are prettier to look at + +-- Offset Coordinates are Useful for UI-Implementations function hex_to_offset(hex) return vec2(hex[1], -hex[1] - hex[2] + (hex[1] + (hex[1] % 2)) / 2) end + -- back to cube coordinates function offset_to_hex(off) return vec2(off[1], off[2] - off[1] * (off[1] % 2) / 2) @@ -128,7 +129,7 @@ end --[[============================================================================ ----- MAPS & STORAGE ----- - This means, you are not to draw using the coordinates stored in your map. + You are not to draw using the coordinates stored in your map. You are to draw using the hex_to_pixel of those coordinates. If you wish to draw a hexagon to the screen, you must first use hex_to_pixel @@ -137,23 +138,21 @@ end am.circle with |sides| = 6, or gather the vertices with hex_corners and use am.draw - TODO, haven't used am.draw yet. - Information about the maps' dimensions are stored in a metatable, so you can - retrieve details about maps after they are created. + Maps have metatables containing information about their dimensions, and + seed (if applicable), so you can retrieve information about maps after they + are created. ----- NOISE ----- To simplify terrain generation, unordered, hash-like maps automatically - calculate and store simplex noise as their values. You can modify the nature - of the noise by providing different |frequencies| as a tables of values, for - example: {1, 2, 4, 8} or {1, 0.5, 0.25, 0.125}. These just increase the - complexity of the curvature of the noise. The default is {1}. + calculate and store seeded simplex noise as their values. You can provide + a seed if you wish. The default is a randomized seed. - ----- TODO ----- - make all functions work regardless of layout. as it stands, they kind - of do, just not always nicely. + TODO Pointy Hex testing and support. ============================================================================]]-- --- returns ordered ring-shaped map of |radius| from |center|. + +-- Returns Ordered Ring-Shaped Map of |radius| from |center| function ring_map(center, radius) local map = {} @@ -169,7 +168,8 @@ function ring_map(center, radius) return map end --- returns ordered spiral hexagonal map of |radius| rings from |center|. + +-- Returns Ordered Spiral Hexagonal Map of |radius| Rings from |center| function spiral_map(center, radius) local map = {center} @@ -180,50 +180,52 @@ function spiral_map(center, radius) return map end --- returns unordered parallelogram-shaped map of |width| and |height| with simplex noise + +-- Returns Unordered Parallelogram-Shaped Map of |width| and |height| with Simplex Noise function parallelogram_map(width, height, seed) local seed = seed or math.random(width * height) - -- fill the map local map = {} - for i = 0, width do for j = 0, height do - -- generate noise + -- Calculate Noise local idelta = i / width local jdelta = j / height local noise = 0 - for oct = 1, math.max(width, height) do - noise = noise + 1/4^oct * math.simplex(vec2(idelta + seed * width, jdelta + seed * height) * 2^oct) + for oct = 1, 6 do + local f = 1/4^oct + local l = 2^oct + local pos = vec2(idelta + seed * width, jdelta + seed * height) + noise = noise + f * math.simplex(pos * l) end - - -- straightforward iteration produces a parallelogram - map[vec2(i, j)] = noise + map[vec2(i, j)] = noise -- Straightforward Iteration Produces a Parallelogram end end setmetatable(map, {__index={width=width, height=height, seed=seed}}) return map end --- returns unordered triangular map of |size| with simplex noise + +-- Returns Unordered Triangular Map of |size| with Simplex Noise function triangular_map(size, seed) local seed = seed or math.random(size) - -- fill the map local map = {} - for i = 0, size do for j = size - i, size do - -- generate noise + -- Generate Noise local idelta = i / size local jdelta = j / size local noise = 0 - for oct = 1, size do - noise = noise + 1/3^oct * math.simplex(vec2(idelta + seed * size, jdelta + seed * size) * 2^oct) + for oct = 1, 6 do + local f = 1/3^oct + local l = 2^oct + local pos = vec2(idelta + seed * size, jdelta + seed * size) + noise = noise + f * math.simplex(pos * l) end map[vec2(i, j)] = noise @@ -233,47 +235,61 @@ function triangular_map(size, seed) return map end --- returns unordered hexagonal map of |radius| with simplex noise + +-- Returns Unordered Hexagonal Map of |radius| with Simplex Noise function hexagonal_map(radius, seed) - local seed = seed or math.random(radius * 2) + local seed = seed or math.random(radius * 2 + 1) - -- fill the map local map = {} - for i = -radius, radius do local j1 = math.max(-radius, -i - radius) local j2 = math.min(radius, -i + radius) for j = j1, j2 do - map[vec2(i, j)] = true + + -- Calculate Noise + local idelta = i / radius + local jdelta = j / radius + local noise = 0 + + for oct = 1, 6 do + + local f = 2/3^oct -- NOTE, for some reason, I found 2/3 produces better looking noise maps. As far as I am aware, this is weird. + local l = 2^oct + local pos = vec2(idelta + seed * radius, jdelta + seed * radius) + + noise = noise + f * math.simplex(pos * l) + end + map[vec2(i, j)] = noise end end setmetatable(map, {__index={radius=radius, seed=seed}}) return map end --- returns unordered rectangular map of |width| and |height| with simplex noise + +-- Returns Unordered Rectangular Map of |width| and |height| with Simplex Noise function rectangular_map(width, height, seed) local seed = seed or math.random(width * height) - -- fill the map local map = {} - for i = 0, width do for j = 0, height do - -- generate noise + -- Calculate Noise local idelta = i / width local jdelta = j / height local noise = 0 - for oct = 1, math.max(width, height) do - noise = noise + 2/3^oct * math.simplex(vec2(idelta + seed*width, - jdelta + seed*height - * 2^oct)) - end + for oct = 1, 6 do + + local f = 2/3^oct + local l = 2^oct + local pos = vec2(idelta + seed * width, jdelta + seed * height) - -- store hex in the map paired with its associated noise value + noise = noise + f * math.simplex(pos * l) + end + -- Store Hex in the Map Paired with its Associated Noise Value map[vec2(i, j - math.floor(i/2))] = noise end end @@ -281,22 +297,45 @@ function rectangular_map(width, height, seed) return map end ---[[============================================================================ - ----- PATHFINDING ----- +--[[==========================================================================-- + ----- PATHFINDING ----- ============================================================================]]-- +-- first try +function search(map, start) + local neighbours + for i = 1, 6 do + neighbours[#neighbours + 1] = hex_neighbour(start, i) + end +end ---[[============================================================================ - ----- TESTS ----- -============================================================================]]-- -function test_all() - print("it works trust me") + + +-- +function breadth_first_search(map, start) + local frontier = {start} + + local visited = {start = true} + + while next(frontier) ~= nil do + local current = next(frontier) + local neighbours + for i = 1, 6 do + neighbours[#neighnours + 1] = hex_neighbour(current, i) + end + for _,n in neighbours do + if visited[n] ~= true then + visited[n] = true + end + end + end end + diff --git a/src/main.lua b/src/main.lua index a1fbd1c..43a379b 100644 --- a/src/main.lua +++ b/src/main.lua @@ -4,11 +4,11 @@ require"hexyz" math.randomseed(os.time()) --[[============================================================================ - ----- COLOR CONSTANTS ----- + ----- GLOBALS ----- ============================================================================]]-- -local EIGENGRAU = vec4(0.08, 0.08, 0.11, 1) --- Ethan Schoonover Solarized Colorscheme +-- Ethan Schoonover Solarized Colorscheme w/ Eigengrau +local EIGENGRAU = vec4(0.08, 0.08, 0.11, 1) local BASE03 = vec4(0 , 0.16, 0.21, 1) local BASE02 = vec4(0.02, 0.21, 0.25, 1) local BASE01 = vec4(0.34, 0.43, 0.45, 1) @@ -17,7 +17,7 @@ local BASE0 = vec4(0.51, 0.58, 0.58, 1) local BASE1 = vec4(0.57, 0.63, 0.63, 1) local BASE2 = vec4(0.93, 0.90, 0.83, 1) local BASE3 = vec4(0.99, 0.96, 0.89, 1) -local YELLOW = vec4(0.70, 0.53, 0 , 1) +local YELLOW = vec4(0.70, 0.53, 0, 1) local ORANGE = vec4(0.79, 0.29, 0.08, 1) local RED = vec4(0.86, 0.19, 0.18, 1) local MAGENTA = vec4(0.82, 0.21, 0.50, 1) @@ -26,179 +26,274 @@ local BLUE = vec4(0.14, 0.54, 0.82, 1) local CYAN = vec4(0.16, 0.63, 0.59, 1) local GREEN = vec4(0.52, 0.60, 0 , 1) -table.merge(am.ascii_color_map, -{ - E = EIGENGRAU, - K = BASE03, - k = BASE02, - L = BASE01, - l = BASE00, - s = BASE0, - S = BASE1, - w = BASE2, - W = BASE3, - Y = YELLOW, - O = ORANGE, - R = RED, - M = MAGENTA, - V = VIOLET, - B = BLUE, - C = CYAN, - G = GREEN -}) - -local beetle = -[[ -. . . . . . . . . . . . . . . . . . . -. . . . . . . . . . . . . . . . . . . -. . . . . . . . . y . . . . . . . . . -. . . . . . . . y . y . . . . . . . . -. . . . . . . . y y y . . . . . . . . -. . . . . . . y y . y y . . . . . . . -. . . . . . . y y . y y . . . . . . . -. . . . . . y O y O y O y . . . . . . -. . . . . . o O y o y O o . . . . . . -. . o . . o y o O O O o y o . . o . . -. . . o . o W o O O O o W o . o . . . -. . . . o O o O O O O O o O o . . . . -. . . . o o O O O O O O O o o . . . . -. . . . . . o O O O O O o . . . . . . -. . o o o o O o o o o o O o o o o . . -. . . . . o O O o o o O O o o . . . . -. . . . . o O O O o O O O o . . . . . -. . . . . o O O O o O O O o . . . . . -. . . . . . o O O o O O o . . . . . . -. . . . . o o o O o O o o o . . . . . -. . . o o o . . o O o . . o o o . . . -. . . . . . . . . . . . . . . . . . . -. . . . . . . . . . . . . . . . . . . -]] - ---[[============================================================================ - ----- SETUP ----- -============================================================================]]-- local win = am.window { - -- base resolution = 3/4 * WXGA standard 16:10 - width = 1280 * 3/4, -- 960px - height = 800 * 3/4, -- 600px + -- Base Resolution = 3/4 * WXGA standard 16:10 + width = 1280 * 3/4, -- 960px + height = 800 * 3/4, -- 600px - clear_color = BASE03 + clear_color = EIGENGRAU } -local map = rectangular_map(45, 31) -local layout = layout(vec2(-268, win.bottom)) -local home = hex_to_pixel(vec2(23, 4), layout) +local curtain = am.rect(win.left, win.top, win.right, win.bottom + , vec4(0, 0, 0, 0.7)) -- Color + +--local log = io.open(os.date("log %c.txt"), "w") --[[============================================================================ - ----- FUNCTIONS ----- + ----- ROUTINES ----- ============================================================================]]-- +-- Template for Buttons +function rect_button(text) + return am.group + { + am.rect(-150, -20, 150, 20, vec4(0)):action(am.tween(1, {color=BASE2{a=0.4}})), + am.text(text, vec4(0)):action(am.tween(1, {color=BASE02})) + } +end + + -- +function text_field(tag) + local field = am.text(""):action(function() + + -- Special Cases + if win:key_pressed("backspace") then + field.text = field.text:sub(1, -2) + + elseif win:key_pressed("enter") then + field.text = "" + + -- I Only Use This To Get Seeds At The Moment + elseif win:key_pressed("0") then field.text = field.text .. 0 + elseif win:key_pressed("1") then field.text = field.text .. 1 + elseif win:key_pressed("2") then field.text = field.text .. 2 + elseif win:key_pressed("3") then field.text = field.text .. 3 + elseif win:key_pressed("4") then field.text = field.text .. 4 + elseif win:key_pressed("5") then field.text = field.text .. 5 + elseif win:key_pressed("6") then field.text = field.text .. 6 + elseif win:key_pressed("7") then field.text = field.text .. 7 + elseif win:key_pressed("8") then field.text = field.text .. 8 + elseif win:key_pressed("9") then field.text = field.text .. 9 + end + end) + return field:tag(tag) +end + + +-- Tween Multiple Nodes of the Same Type +function multitween(nodes, time, values) + for _,node in pairs(nodes) do + node:action(am.tween(time, values)) + end +end + + +-- Returns Appropriate Tile Color for Specified Elevation +function color_at(elevation) + if elevation < -0.5 then -- Lowest Elevation : Impassable + return vec4(0.10, 0.30, 0.40, (elevation + 1.2) / 2) + + elseif elevation < 0 then -- Med-Low Elevation : Passable + return vec4(0.10, 0.25, 0.10, (elevation + 1.8) / 2) + + elseif elevation < 0.5 then -- Med-High Elevation : Passable + return vec4(0.25, 0.20, 0.10, (elevation + 1.6) / 2) + + else -- Highest Elevation : Impassable + return vec4(0.15, 0.30, 0.20, (elevation + 1.0) / 2) + end +end + + +-- Handler for Scoring function keep_score() local offset = am.current_time() - world:action(function() - world:remove("time") + win.scene:action(function() + win.scene:remove("time") local time_str = string.format("%.2f", am.current_time() - offset) - world:append( - am.translate(-374, win.top - 10) - ^ am.text(time_str):tag"time") + win.scene:append(am.translate(-374, win.top - 10) + ^ am.text(time_str):tag"time") end) end --- TODO refactor to something like - poll-mouse or mouse-hover event -function show_coords() - world:action(function() - world:remove("coords") - world:remove("selected") - local hex = pixel_to_hex(win:mouse_position(), layout) - local mouse = hex_to_offset(hex) +-- In-Game Pause Menu +function pause() + win.scene:append(curtain:tag"curtain") + win.scene:append(am.group + { + am.rect(-200, 150, 200, -150, BASE03{a=0.9}) + }:tag"menu") - -- check mouse is within bounds of game map - if mouse.x > 0 and mouse.x < map.width and - -mouse.y > 0 and -mouse.y < map.height then -- north is positive + -- Event Handler + win.scene:action(function() - local text = am.text(string.format("%d,%d", mouse.x, mouse.y)) - local coords = am.group{ - am.translate(win.right - 25, win.top - 10) - ^ am.text(string.format("%d,%d", mouse.x,-mouse.y)):tag"coords"} - - world:append(coords) - - local color = vec4(0, 0, 0, 0.2) - local pix = hex_to_pixel(hex, layout) - world:append(am.circle(pix, layout.size.x, color, 6):tag"selected") + -- Back to Main Game + if win:key_pressed("escape") then + win.scene:remove("curtain"); win.scene:remove("menu") + game_action(); return true end end) end --- generate map, no seed means random map -function render_map(seed) - -- setup - world = am.group{}:tag"world" + + + + +-- Returns Node +function draw_(map) + local world = am.group():tag"world" + + for hex,elevation in pairs(map) do + + local off = hex_to_offset(hex) + local mask = vec4(0, 0, 0, math.max(((off.x - 23) / 45) ^ 2, + ((-off.y - 16) / 31) ^ 2)) + + local color = color_at(elevation) - mask + local node = am.circle(hex_to_pixel(hex, vec2(11)), 11, vec4(0), 6) + node:action(am.tween(0.3, {color = color})) -- fade in + + world:append(node:tag(tostring(hex))) -- unique identifier + end + return world +end + + +-- +function ghandler(game) + win.scene:remove("coords"); win.scene:remove("selected") + + -- Pause Game + if win:key_pressed("escape") then + pause(); return true + end + + local hex = pixel_to_hex(win:mouse_position(), vec2(11)) - vec2(10, 10) + local mouse = hex_to_offset(hex) + + -- Check if Mouse is Within Bounds of Game Map + if mouse.x > 0 and mouse.x < map.width and + -mouse.y > 0 and -mouse.y < map.height then -- North is Positive + + local text = am.text(string.format("%d,%d", mouse.x, mouse.y)) + game:append(am.translate(450, 290) ^ text:tag"coords") + + local color = vec4(0, 0, 0, 0.4) + local pix = hex_to_pixel(hex, vec2(11)) + game:append(am.circle(pix, 11, color, 6):tag"selected") + end +end + + +-- Begin Game - From Seed or Random Seed (if ommitted) +function game_init(seed) + local game = am.group() + + game:append(am.rect(win.left, win.top, -268, win.bottom, BASE03)) + + + map = rectangular_map(45, 31, seed) + game:action(ghandler) + win.scene = am.group(am.translate(-268, -300) ^ draw_(map), game) +end - -- render world - world:action(coroutine.create(function() - -- begin map generation - for hex,elevation in pairs(map) do +-- Title Action +function thandler(title) + local mouse = win:mouse_position() - -- determine cell - local color + if mouse.x > -150 and mouse.x < 150 then - -- lowest elevation : impassable - if elevation < -0.5 then - color = vec4(0.10, 0.30, 0.20, (elevation + 1) / 2) + -- Button 1 + if mouse.y > -70 and mouse.y < -30 then - -- med-low elevation : passable - elseif elevation < 0 then - color = vec4(0.10, 0.25, 0.10, (elevation + 1.9) / 2) + title"button1""rect":action(am.tween(0.5, {color = BASE2{a=1}})) - -- med-high elevation : passable - elseif elevation< 0.5 then - color = vec4(0.25, 0.20, 0.10, (elevation + 1.9) / 2) + if win:mouse_pressed("left") then + win.scene:action(am.play(am.sfxr_synth(57784609))) + game_init(map.seed) + return true + end - -- highest elevation : impassable - else - color = vec4(0.10, 0.30, 0.20, (elevation + 1) / 2) + -- Button 2 + elseif mouse.y > -120 and mouse.y < -80 then + + title"button2""rect":action(am.tween(0.5, {color = BASE2{a=1}})) + + if win:mouse_pressed("left") then + win.scene:action(am.play(am.sfxr_synth(91266909))) end - -- subtly shade edges of map. offset coords are easier to work with - local off = hex_to_offset(hex) - local mask = vec4(0, 0, 0, math.max(((off.x - 23) / 45)^2, - ((-off.y - 16) / 31)^2)) - color = color - mask + -- Button 3 + elseif mouse.y > -170 and mouse.y < -130 then - -- determine hexagon center for drawing - local center = hex_to_pixel(hex, layout) + title"button3""rect":action(am.tween(0.5, {color = BASE2{a=1}})) + + if win:mouse_pressed("left") then + local synth_seed = math.random(100000000) + win.scene:action(am.play(am.sfxr_synth(synth_seed))) + print(synth_seed) + end - -- prepend hexagon to screen - world:prepend(am.circle(center, 11, color, 6):tag(tostring(hex))) + -- Button 4 + elseif mouse.y > -220 and mouse.y < -180 then + + title"button4""rect":action(am.tween(0.5, {color = BASE2{a=1}})) + + if win:mouse_pressed("left") then + win.scene:action(am.play(am.sfxr_synth(36002209))) + end + else + multitween({title"button1""rect", title"button2""rect", + title"button3""rect", title"button4""rect"}, + 0.5, {color = BASE2{a=0.4}}) end - -- home base - world:append(am.translate(home) - ^ am.rotate(0):tag"home_rotate" - ^ am.circle(vec2(0), 22, MAGENTA, 5)):tag"home" - - world:append(am.scale(5) ^ am.sprite(beetle)) - - world:action(function() - world"home_rotate".angle = am.frame_time / 5 - end) - show_coords() -- mouse-hover events - keep_score() -- scoring - end)) - win.scene = world -- make it so + else + multitween({title"button1""rect", title"button2""rect", + title"button3""rect", title"button4""rect"}, + 0.5, {color = BASE2{a=0.4}}) + end end ---[[============================================================================ - ----- MAIN ----- -============================================================================]]-- -render_map() +-- Setup and Display Title Screen +function title_init() + local title = am.group() + + title:append(am.translate(0, -50) ^ rect_button("NEW SCENARIO"):tag"button1") + title:append(am.translate(0, -100) ^ rect_button("LOREMIPSUM"):tag"button2") + title:append(am.translate(0, -150) ^ rect_button("FUN BUTTON"):tag"button3") + title:append(am.translate(0, -200) ^ rect_button("SETTINGS"):tag"button4") + + map = hexagonal_map(45) + backdrop = am.scale(1.3) ^ am.rotate(0) ^ draw_(map) + + backdrop:action(function() + backdrop"rotate".angle = am.frame_time / 40 + 45 + end) + + -- Event Handler + title:action(thandler) + + win.scene = am.group(backdrop, title) +end + + +-- Alias +function init() + title_init() +end + +--============================================================================= + ----- Main ----- + + +init() diff --git a/src/sprites.lua b/src/sprites.lua new file mode 100644 index 0000000..8e46d14 --- /dev/null +++ b/src/sprites.lua @@ -0,0 +1,16 @@ + + +settings = +[[ +. +. +. +. +. +. +. +. +]] + + +