Last active
January 5, 2023 16:07
-
-
Save xenobrain/b652a3ad7f43bd9f501fea3d514d8588 to your computer and use it in GitHub Desktop.
starting point for a hex based game
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
include MatrixFunctions | |
# Math constants | |
K_INV_6 = 1.0 / 6.0 | |
K_2_OVER_3 = 2.0 / 3.0 | |
K_2_PI = Math::PI * 2.0 | |
K_SQRT_3 = Math.sqrt 3.0 | |
K_NEG_1_OVER_3 = -1.0 / 3.0 | |
K_DEG2RAD = Math::PI / 180.0 | |
K_RAD2DEG = 360.0 / (2.0 * Math::PI) | |
K_HALF_SQRT_3 = 0.5 * (Math.sqrt 3.0) | |
K_SQRT_3_OVER_3 = (Math.sqrt 3.0) / 3.0 | |
# Galaxy constants | |
GALAXY_WIDTH = 18 | |
GALAXY_HEIGHT = 12 | |
GALAXY_NUM_STARS = 30 | |
GALAXY_CELL_WIDTH = 25.0 | |
GALAXY_CELL_HEIGHT = 25.0 | |
GALAXY_MAP_SHAPE = :hexagon | |
HALF_GALAXY_WIDTH = GALAXY_WIDTH >> 1 | |
HALF_GALAXY_HEIGHT = GALAXY_HEIGHT >> 1 | |
HALF_GALAXY_CELL_WIDTH = GALAXY_CELL_WIDTH * 0.5 | |
HALF_GALAXY_CELL_HEIGHT = GALAXY_CELL_HEIGHT * 0.5 | |
INV_HALF_GALAXY_CELL_WIDTH = 1.0 / HALF_GALAXY_CELL_WIDTH | |
INV_HALF_GALAXY_CELL_HEIGHT = 1.0 / HALF_GALAXY_CELL_HEIGHT | |
def tick args | |
defaults args | |
render args | |
input args | |
calc args | |
end | |
def defaults args | |
args.grid.origin_center! | |
args.state.galaxy ||= create_galaxy args | |
args.state.camera ||= create_camera args | |
args.state.mouse_x ||= args.inputs.mouse.x | |
args.state.mouse_y ||= args.inputs.mouse.y | |
end | |
def render args | |
render_galaxy args | |
end | |
def input args | |
if args.inputs.mouse.button_left | |
c = find_cell args | |
if c | |
c.vertices.each do |vertex| | |
args.outputs.sprites << { x: args.state.camera.position.x + vertex.x, y: args.state.camera.position.y + vertex.y, w: 20, h: 20, path: 'sprites/circle/blue.png'} | |
end | |
end | |
args.state.camera.position.x += args.inputs.mouse.x - args.state.mouse_x | |
args.state.camera.position.y += args.inputs.mouse.y - args.state.mouse_y | |
end | |
args.state.mouse_x = args.inputs.mouse.x | |
args.state.mouse_y = args.inputs.mouse.y | |
end | |
def calc args | |
end | |
def create_camera args | |
{ position: (vec2 0.0, 0.0) } | |
end | |
def calc_vertices q, r | |
center_x = 1.5 * q * HALF_GALAXY_CELL_WIDTH | |
center_y = (K_HALF_SQRT_3 * q + K_SQRT_3 * r) * HALF_GALAXY_CELL_HEIGHT | |
6.times.map do |index| | |
angle = K_2_PI * index * K_INV_6 | |
offset_x = HALF_GALAXY_CELL_WIDTH * (Math.cos angle) | |
offset_y = HALF_GALAXY_CELL_HEIGHT * (Math.sin angle) | |
vec2 center_x + offset_x, center_y + offset_y | |
end | |
end | |
def create_galaxy args | |
galaxy = {} | |
case GALAXY_MAP_SHAPE | |
when :hexagon | |
radius = [GALAXY_WIDTH, GALAXY_HEIGHT].max >> 1 | |
(-radius..radius).flat_map do |q| | |
([-radius, -(q + radius)].max..[radius, radius - q].min).map do |r| | |
galaxy[[q, r]] = { vertices: (calc_vertices q, r) } | |
end | |
end | |
when :rectangle | |
(-HALF_GALAXY_WIDTH..HALF_GALAXY_WIDTH).each do |q| | |
(-HALF_GALAXY_HEIGHT - (q >> 1)..HALF_GALAXY_HEIGHT - (q >> 1)).each do |r| | |
galaxy[[q, r]] = { vertices: (calc_vertices q, r) } | |
end | |
end | |
end | |
galaxy | |
end | |
def find_cell args | |
x = (args.inputs.mouse.x - args.state.camera.position.x) * INV_HALF_GALAXY_CELL_WIDTH | |
y = (args.inputs.mouse.y - args.state.camera.position.y) * INV_HALF_GALAXY_CELL_HEIGHT | |
q = (K_2_OVER_3 * x).round | |
r = (K_NEG_1_OVER_3 * x + K_SQRT_3_OVER_3 * y).round | |
args.state.galaxy[[q, r]] | |
end | |
def render_galaxy args | |
camera_x = args.state.camera.position.x | |
camera_y = args.state.camera.position.y | |
args.outputs.lines << args.state.galaxy.each_value.map do |cell| | |
cell.vertices.map.with_index do |vertex, index| | |
next_vertex = cell.vertices.at (index + 1) % 6 | |
{ x: camera_x + vertex.x, y: camera_y + vertex.y, x2: camera_x + next_vertex.x, y2: camera_y + next_vertex.y, r: 100, g: 100, b: 100 } | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment