146 lines
4.7 KiB
GDScript3
146 lines
4.7 KiB
GDScript3
|
|
extends Node3D
|
||
|
|
|
||
|
|
@onready var hex = $Hexagon
|
||
|
|
@onready var coord_label = $Hexagon/Label3D
|
||
|
|
|
||
|
|
const DIR_N: Vector3 = Vector3(0, 1, -1)
|
||
|
|
const DIR_NE: Vector3 = Vector3(1, 0, -1)
|
||
|
|
const DIR_SE: Vector3 = Vector3(1, -1, 0)
|
||
|
|
const DIR_S: Vector3 = Vector3(0, -1, 1)
|
||
|
|
const DIR_SW: Vector3 = Vector3(-1, 0, 1)
|
||
|
|
const DIR_NW: Vector3 = Vector3(-1, 1, 0)
|
||
|
|
const DIR_ALL: Array[Vector3] = [DIR_N, DIR_NE, DIR_SE, DIR_S, DIR_SW, DIR_NW]
|
||
|
|
|
||
|
|
#const size = Vector2(1, sqrt(3.0)/2.0)
|
||
|
|
|
||
|
|
const size: float = 0.5
|
||
|
|
|
||
|
|
@export var layer_height: float = 0.4
|
||
|
|
|
||
|
|
class CubeCoordinates:
|
||
|
|
var q: float
|
||
|
|
var r: float
|
||
|
|
var s: float
|
||
|
|
|
||
|
|
func _init(_q: float, _r: float, _s: float):
|
||
|
|
q = _q
|
||
|
|
r = _r
|
||
|
|
s = _s
|
||
|
|
|
||
|
|
class AxialCoordinates:
|
||
|
|
var q: float
|
||
|
|
var r: float
|
||
|
|
|
||
|
|
func _init(_q: float, _r: float):
|
||
|
|
q = _q
|
||
|
|
r = _r
|
||
|
|
|
||
|
|
func flat_hex_corner(center: Vector2, size: float, corner_num: int) -> Vector2:
|
||
|
|
var angle_deg: int = 60 * corner_num
|
||
|
|
var angle_rad: float = deg_to_rad(angle_deg)
|
||
|
|
return Vector2(center.x + size * cos(angle_rad), center.y + size * sin(angle_rad))
|
||
|
|
|
||
|
|
func flat_hex_to_world_position(coords: AxialCoordinates) -> Vector2:
|
||
|
|
var x = size * (3.0/2.0 * coords.q)
|
||
|
|
var y = size * (sqrt(3.0)/2.0 * coords.q + sqrt(3.0) * coords.r)
|
||
|
|
return Vector2(x, y)
|
||
|
|
|
||
|
|
#func world_to_hex_tile(world_pos: Vector3) -> Vector2:
|
||
|
|
# var q = (2.0/3.0 * world_pos.x)
|
||
|
|
# var r = (-1.0/3.0 * world_pos.x + sqrt(3.0)/3.0 * world_pos.z)
|
||
|
|
#
|
||
|
|
# return cube_round()
|
||
|
|
#
|
||
|
|
# return
|
||
|
|
|
||
|
|
func world_to_hex_tile(coords: Vector2) -> AxialCoordinates:
|
||
|
|
var q = (2.0/3.0 * coords.x) / size
|
||
|
|
var r = (-1.0/3.0 * coords.x + sqrt(3.0)/3.0 * coords.y) / size
|
||
|
|
return axial_round(AxialCoordinates.new(q, r))
|
||
|
|
|
||
|
|
func axial_to_cube(coords: AxialCoordinates) -> CubeCoordinates:
|
||
|
|
var q = coords.q
|
||
|
|
var r = coords.r
|
||
|
|
var s = -q-r
|
||
|
|
return CubeCoordinates.new(q, r, s)
|
||
|
|
|
||
|
|
func cube_to_axial(coords: CubeCoordinates) -> AxialCoordinates:
|
||
|
|
var q = coords.q
|
||
|
|
var r = coords.r
|
||
|
|
return AxialCoordinates.new(q, r)
|
||
|
|
|
||
|
|
func axial_round(coords: AxialCoordinates) -> AxialCoordinates:
|
||
|
|
return cube_to_axial(cube_round(axial_to_cube(coords)))
|
||
|
|
|
||
|
|
func cube_round(coords: CubeCoordinates) -> CubeCoordinates:
|
||
|
|
var q: float = round(coords.q)
|
||
|
|
var r: float = round(coords.r)
|
||
|
|
var s: float = round(coords.s)
|
||
|
|
|
||
|
|
var q_diff: float = abs(q - coords.q)
|
||
|
|
var r_diff: float = abs(r - coords.r)
|
||
|
|
var s_diff: float = abs(s - coords.s)
|
||
|
|
|
||
|
|
if q_diff > r_diff and q_diff > s_diff:
|
||
|
|
q = -r-s
|
||
|
|
elif r_diff > s_diff:
|
||
|
|
r = -q-s
|
||
|
|
else:
|
||
|
|
s = -q-r
|
||
|
|
|
||
|
|
return CubeCoordinates.new(q, r, s)
|
||
|
|
|
||
|
|
@export var dragging_intersect_plane_normal: Vector3 = Vector3.UP
|
||
|
|
@export var dragging_intersect_plane_distance: float = 0.0
|
||
|
|
|
||
|
|
func get_3d_pos(position2D: Vector2):
|
||
|
|
return Plane(dragging_intersect_plane_normal, dragging_intersect_plane_distance).intersects_ray(get_viewport().get_camera_3d().project_ray_origin(position2D), get_viewport().get_camera_3d().project_ray_normal(position2D))
|
||
|
|
|
||
|
|
func _ready() -> void:
|
||
|
|
pass
|
||
|
|
#for x in range(-0, 1):
|
||
|
|
# for y in range(-0, 10):
|
||
|
|
# var hex_pos = flat_hex_to_world_position(AxialCoordinates.new(x, y))
|
||
|
|
# var new_hex = hex.duplicate()
|
||
|
|
# new_hex.position = Vector3(hex_pos.x, 0.0, hex_pos.y)
|
||
|
|
# var hex_id = world_to_hex_tile(Vector2(hex_pos.x, hex_pos.y))
|
||
|
|
# new_hex.get_node("Label3D").text = "%d, %d" % [hex_id.q, hex_id.r]
|
||
|
|
# add_child(new_hex)
|
||
|
|
|
||
|
|
func spawn_random_tile() -> void:
|
||
|
|
var tile_copy = hex.duplicate()
|
||
|
|
var hex_pos = flat_hex_to_world_position(AxialCoordinates.new(randi_range(-20, 20), randi_range(-20, 20)))
|
||
|
|
|
||
|
|
tile_copy.position = Vector3(hex_pos.x, 20.0, hex_pos.y)
|
||
|
|
var target_pos = Vector3(hex_pos.x, 0.0, hex_pos.y)
|
||
|
|
|
||
|
|
add_child(tile_copy)
|
||
|
|
|
||
|
|
var tween = get_tree().create_tween()
|
||
|
|
tween.tween_property(tile_copy, "position", target_pos, 1.0).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_EXPO)
|
||
|
|
|
||
|
|
func move_tile_to_random_position() -> void:
|
||
|
|
var new_hex_pos = flat_hex_to_world_position(AxialCoordinates.new(randi_range(-20, 20), randi_range(-20, 20)))
|
||
|
|
var sky_new_hex_pos = Vector3(new_hex_pos.x, 20.0, new_hex_pos.y)
|
||
|
|
var ground_new_hex_pos = Vector3(new_hex_pos.x, 0.0, new_hex_pos.y)
|
||
|
|
|
||
|
|
var current_hex_pos = hex.position
|
||
|
|
var sky_current_hex_pos = hex.position + Vector3(0.0, 20.0, 0.0)
|
||
|
|
|
||
|
|
var tween = get_tree().create_tween()
|
||
|
|
tween.tween_property(hex, "position", sky_current_hex_pos, 0.5).set_ease(Tween.EASE_IN).set_trans(Tween.TRANS_EXPO)
|
||
|
|
tween.tween_property(hex, "position", sky_new_hex_pos, 0.0)
|
||
|
|
tween.tween_property(hex, "position", ground_new_hex_pos, 1.0).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_EXPO)
|
||
|
|
|
||
|
|
func _process(delta) -> void:
|
||
|
|
if Input.is_action_just_pressed("ui_accept"):
|
||
|
|
print("yay")
|
||
|
|
spawn_random_tile()
|
||
|
|
|
||
|
|
var pos3d = get_3d_pos(get_viewport().get_mouse_position())
|
||
|
|
return
|
||
|
|
if pos3d:
|
||
|
|
var hex_pos = flat_hex_to_world_position(world_to_hex_tile(Vector2(pos3d.x, pos3d.z)))
|
||
|
|
hex.position = Vector3(hex_pos.x, 0.0, hex_pos.y)
|
||
|
|
coord_label.text = "%d, %d" % [hex_pos.x, hex_pos.y]
|