itrpg/scripts/isometric_map_layer_holder.gd
2025-03-22 13:20:31 +01:00

263 lines
9.5 KiB
GDScript

extends Node2D
var GRID_SIZE_WIDTH = 30 # play area size x
var GRID_SIZE_LENGTH = 30 # play area size y
var GRID_SIZE_HEIGHT = 30 # play area size z
var TILE_SIZE = 32 # in px
var TILE_SIZE_ISOMETRIC_X = 32 # in px
var TILE_SIZE_ISOMETRIC_Y = 16 # in px
var ROTATION = 0
const MAIN_SOURCE_ID = 0
const BLUE_ISOMETRICTILE_ATLAS_POSITION = Vector2i(0,0)
const RED_ISOMETRICTILE_ATLAS_POSITION = Vector2i(1,0)
const GREEN_ISOMETRICTILE_ATLAS_POSITION = Vector2i(2,0)
const WHITE_ISOMETRICTILE_ATLAS_POSITION = Vector2i(3,0)
const BLACK_ISOMETRICTILE_ATLAS_POSITION = Vector2i(4,0)
const PURPLE_ISOMETRICTILE_ATLAS_POSITION = Vector2i(5,0)
const ORANGE_ISOMETRICTILE_ATLAS_POSITION = Vector2i(6,0)
const OFFSET = 15
func create_debug_map_array():
var _debug_map = []
for x in GRID_SIZE_WIDTH:
var y_array = []
for y in GRID_SIZE_LENGTH:
var z_array = []
for z in GRID_SIZE_HEIGHT:
z_array.append(null)
y_array.append(z_array)
_debug_map.append(y_array)
for z in GRID_SIZE_HEIGHT:
for y in GRID_SIZE_LENGTH:
for x in GRID_SIZE_WIDTH:
var coord_x = x + (-1 * z) + OFFSET
var coord_y = y + (-1 * z) - OFFSET
var visibility = false
var atlas_position = BLUE_ISOMETRICTILE_ATLAS_POSITION
if z == 0:
visibility = true
atlas_position = RED_ISOMETRICTILE_ATLAS_POSITION
if z == 1:
if coord_x > 20 and coord_y > 10:
visibility = true
# print("Variable value: ", coord_x, " ", coord_y, " ", z, " ", visibility)
atlas_position = GREEN_ISOMETRICTILE_ATLAS_POSITION
var tile_data = {
"x": coord_x,
"y": coord_y,
"z": z,
"atlas_position": atlas_position,
"hp": 100,
"armour": 0,
"destroyable": false,
"visibility": visibility,
"unit": null,
"gravity": false
}
_debug_map[x][y][z] = tile_data
return _debug_map
func rotate_map_around_y_axis(rotation_steps = 1):
rotation_steps = rotation_steps % 4
if rotation_steps == 0:
return
# Create a temporary map with the correct dimensions
var temp_map = []
for x in GRID_SIZE_WIDTH:
var y_array = []
for y in GRID_SIZE_LENGTH:
var z_array = []
for z in GRID_SIZE_HEIGHT:
z_array.append(null)
y_array.append(z_array)
temp_map.append(y_array)
# For a y-axis rotation, we need to swap x and z coordinates
# but keep the isometric projection consistent
for x in GRID_SIZE_WIDTH:
for y in GRID_SIZE_LENGTH:
for z in GRID_SIZE_HEIGHT:
if debug_map[x][y][z] == null:
continue
var new_x = 0
var new_z = 0
match rotation_steps:
1: # 90 degrees clockwise around Y axis
new_x = GRID_SIZE_HEIGHT - 1 - z
new_z = x
2: # 180 degrees
new_x = GRID_SIZE_WIDTH - 1 - x
new_z = GRID_SIZE_HEIGHT - 1 - z
3: # 270 degrees
new_x = z
new_z = GRID_SIZE_WIDTH - 1 - x
# Ensure we're within bounds
if new_x >= 0 and new_x < GRID_SIZE_WIDTH and new_z >= 0 and new_z < GRID_SIZE_HEIGHT:
# Copy the tile data
temp_map[new_x][y][new_z] = debug_map[x][y][z].duplicate()
# The crucial part: preserve the visual arrangement by adapting the isometric projection
# We need to recalculate the display coordinates based on the new grid position
var new_coord_x = new_x + (-1 * new_z) + 15
var new_coord_y = y + (-1 * new_z) - 15
temp_map[new_x][y][new_z]["x"] = new_coord_x
temp_map[new_x][y][new_z]["y"] = new_coord_y
temp_map[new_x][y][new_z]["z"] = new_z
# Replace the original map
debug_map = temp_map
print("Map rotated around y-axis by %d steps" % rotation_steps)
func rotate_map_around_x_axis(rotation_steps = 1):
rotation_steps = rotation_steps % 4
if rotation_steps == 0:
return
var temp_map = []
# Initialize temp_map with same structure
for x in GRID_SIZE_WIDTH:
var y_array = []
for y in GRID_SIZE_LENGTH:
var z_array = []
for z in GRID_SIZE_HEIGHT:
z_array.append(null)
y_array.append(z_array)
temp_map.append(y_array)
for x in GRID_SIZE_WIDTH:
for y in GRID_SIZE_LENGTH:
for z in GRID_SIZE_HEIGHT:
if debug_map[x][y][z] == null:
continue
var new_y = 0
var new_z = 0
match rotation_steps:
1: # 90 degrees
new_y = z
new_z = GRID_SIZE_LENGTH - 1 - y
2: # 180 degrees
new_y = GRID_SIZE_LENGTH - 1 - y
new_z = GRID_SIZE_HEIGHT - 1 - z
3: # 270 degrees
new_y = GRID_SIZE_HEIGHT - 1 - z
new_z = y
if new_y >= 0 and new_y < GRID_SIZE_LENGTH and new_z >= 0 and new_z < GRID_SIZE_HEIGHT:
temp_map[x][new_y][new_z] = debug_map[x][y][z].duplicate()
var new_coord_x = x + (-1 * new_z) + OFFSET
var new_coord_y = new_y + (-1 * new_z) - OFFSET
temp_map[x][new_y][new_z]["x"] = new_coord_x
temp_map[x][new_y][new_z]["y"] = new_coord_y
temp_map[x][new_y][new_z]["z"] = new_z
debug_map = temp_map
func rotate_map_around_z_axis(rotation_steps = 1):
rotation_steps = rotation_steps % 4
if rotation_steps == 0:
return
var temp_map = []
# Initialize temp_map with same structure
for x in GRID_SIZE_WIDTH:
var y_array = []
for y in GRID_SIZE_LENGTH:
var z_array = []
for z in GRID_SIZE_HEIGHT:
z_array.append(null)
y_array.append(z_array)
temp_map.append(y_array)
for x in GRID_SIZE_WIDTH:
for y in GRID_SIZE_LENGTH:
for z in GRID_SIZE_HEIGHT:
if debug_map[x][y][z] == null:
continue
var new_x = 0
var new_y = 0
match rotation_steps:
1: # 90 degrees
new_x = y
new_y = GRID_SIZE_WIDTH - 1 - x
2: # 180 degrees
new_x = GRID_SIZE_WIDTH - 1 - x
new_y = GRID_SIZE_LENGTH - 1 - y
3: # 270 degrees
new_x = GRID_SIZE_LENGTH - 1 - y
new_y = x
if new_x >= 0 and new_x < GRID_SIZE_WIDTH and new_y >= 0 and new_y < GRID_SIZE_LENGTH:
temp_map[new_x][new_y][z] = debug_map[x][y][z].duplicate()
var new_coord_x = new_x + (-1 * z) + OFFSET
var new_coord_y = new_y + (-1 * z) - OFFSET
temp_map[new_x][new_y][z]["x"] = new_coord_x
temp_map[new_x][new_y][z]["y"] = new_coord_y
temp_map[new_x][new_y][z]["z"] = z
debug_map = temp_map
var isometric_map_layers = []
func initialize_map_layers():
# Clear any existing layers
for layer in isometric_map_layers:
if is_instance_valid(layer):
layer.queue_free()
isometric_map_layers.clear()
# Create new layers for each height level
for z in GRID_SIZE_HEIGHT:
var new_layer = TileMapLayer.new()
new_layer.set_name("IsometricMapLayer_" + str(z))
new_layer.tile_set = $TileMapLayer.tile_set # Set your tileset
new_layer.z_index = z # Set the z-index to match the layer's height
# Add other TileMap settings as needed
add_child(new_layer)
isometric_map_layers.append(new_layer)
var debug_map = create_debug_map_array()
# Draw the map
func draw_visible_tiles():
for z in GRID_SIZE_HEIGHT:
for y in GRID_SIZE_LENGTH:
for x in GRID_SIZE_WIDTH:
var tile = debug_map[x][y][z]
if tile != null and tile["visibility"]:
# Use the layer that corresponds to the tile's z-value
if z < isometric_map_layers.size():
isometric_map_layers[z].set_cell(
Vector2i(tile["x"], tile["y"]),
MAIN_SOURCE_ID,
tile["atlas_position"]
)
func _ready() -> void:
initialize_map_layers()
rotate_map_around_z_axis(0)
rotate_map_around_y_axis(0)
rotate_map_around_x_axis(0)
draw_visible_tiles()