forked from datawhale/whale-town-front
feat:实现32x32网格系统核心功能
- 添加GridSystem类提供网格坐标转换 - 支持世界坐标与网格坐标互转 - 提供位置吸附和距离计算方法 - 包含网格区域和边界检查功能
This commit is contained in:
143
_Core/systems/GridSystem.gd
Normal file
143
_Core/systems/GridSystem.gd
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
# ============================================================================
|
||||||
|
# 网格系统 - GridSystem.gd
|
||||||
|
#
|
||||||
|
# 提供32x32像素的最小网格单元控制,用于规范地图大小和位置计算
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# var grid_pos = GridSystem.world_to_grid(world_position)
|
||||||
|
# var world_pos = GridSystem.grid_to_world(grid_position)
|
||||||
|
# var snapped_pos = GridSystem.snap_to_grid(position)
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
class_name GridSystem
|
||||||
|
extends RefCounted
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# 常量定义
|
||||||
|
# ============================================================================
|
||||||
|
const GRID_SIZE: int = 32 # 网格单元大小 32x32 像素
|
||||||
|
const HALF_GRID_SIZE: float = GRID_SIZE * 0.5 # 网格中心偏移
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# 坐标转换方法
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# 世界坐标转换为网格坐标
|
||||||
|
static func world_to_grid(world_pos: Vector2) -> Vector2i:
|
||||||
|
return Vector2i(
|
||||||
|
int(world_pos.x / GRID_SIZE),
|
||||||
|
int(world_pos.y / GRID_SIZE)
|
||||||
|
)
|
||||||
|
|
||||||
|
# 网格坐标转换为世界坐标(返回网格左上角)
|
||||||
|
static func grid_to_world(grid_pos: Vector2i) -> Vector2:
|
||||||
|
return Vector2(
|
||||||
|
grid_pos.x * GRID_SIZE,
|
||||||
|
grid_pos.y * GRID_SIZE
|
||||||
|
)
|
||||||
|
|
||||||
|
# 网格坐标转换为世界坐标(返回网格中心)
|
||||||
|
static func grid_to_world_center(grid_pos: Vector2i) -> Vector2:
|
||||||
|
return Vector2(
|
||||||
|
grid_pos.x * GRID_SIZE + HALF_GRID_SIZE,
|
||||||
|
grid_pos.y * GRID_SIZE + HALF_GRID_SIZE
|
||||||
|
)
|
||||||
|
|
||||||
|
# 将位置吸附到最近的网格点(左上角)
|
||||||
|
static func snap_to_grid(position: Vector2) -> Vector2:
|
||||||
|
return Vector2(
|
||||||
|
floor(position.x / GRID_SIZE) * GRID_SIZE,
|
||||||
|
floor(position.y / GRID_SIZE) * GRID_SIZE
|
||||||
|
)
|
||||||
|
|
||||||
|
# 将位置吸附到最近的网格中心
|
||||||
|
static func snap_to_grid_center(position: Vector2) -> Vector2:
|
||||||
|
var grid_pos = world_to_grid(position)
|
||||||
|
return grid_to_world_center(grid_pos)
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# 距离和区域计算
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# 计算两个网格坐标之间的曼哈顿距离
|
||||||
|
static func grid_distance_manhattan(grid_pos1: Vector2i, grid_pos2: Vector2i) -> int:
|
||||||
|
return abs(grid_pos1.x - grid_pos2.x) + abs(grid_pos1.y - grid_pos2.y)
|
||||||
|
|
||||||
|
# 计算两个网格坐标之间的欧几里得距离
|
||||||
|
static func grid_distance_euclidean(grid_pos1: Vector2i, grid_pos2: Vector2i) -> float:
|
||||||
|
var diff = grid_pos1 - grid_pos2
|
||||||
|
return sqrt(diff.x * diff.x + diff.y * diff.y)
|
||||||
|
|
||||||
|
# 获取指定网格坐标周围的邻居网格(4方向)
|
||||||
|
static func get_grid_neighbors_4(grid_pos: Vector2i) -> Array[Vector2i]:
|
||||||
|
return [
|
||||||
|
Vector2i(grid_pos.x, grid_pos.y - 1), # 上
|
||||||
|
Vector2i(grid_pos.x + 1, grid_pos.y), # 右
|
||||||
|
Vector2i(grid_pos.x, grid_pos.y + 1), # 下
|
||||||
|
Vector2i(grid_pos.x - 1, grid_pos.y) # 左
|
||||||
|
]
|
||||||
|
|
||||||
|
# 获取指定网格坐标周围的邻居网格(8方向)
|
||||||
|
static func get_grid_neighbors_8(grid_pos: Vector2i) -> Array[Vector2i]:
|
||||||
|
var neighbors: Array[Vector2i] = []
|
||||||
|
for x in range(-1, 2):
|
||||||
|
for y in range(-1, 2):
|
||||||
|
if x == 0 and y == 0:
|
||||||
|
continue
|
||||||
|
neighbors.append(Vector2i(grid_pos.x + x, grid_pos.y + y))
|
||||||
|
return neighbors
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# 区域和边界检查
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# 检查网格坐标是否在指定矩形区域内
|
||||||
|
static func is_grid_in_bounds(grid_pos: Vector2i, min_grid: Vector2i, max_grid: Vector2i) -> bool:
|
||||||
|
return (grid_pos.x >= min_grid.x and grid_pos.x <= max_grid.x and
|
||||||
|
grid_pos.y >= min_grid.y and grid_pos.y <= max_grid.y)
|
||||||
|
|
||||||
|
# 获取矩形区域内的所有网格坐标
|
||||||
|
static func get_grids_in_rect(min_grid: Vector2i, max_grid: Vector2i) -> Array[Vector2i]:
|
||||||
|
var grids: Array[Vector2i] = []
|
||||||
|
for x in range(min_grid.x, max_grid.x + 1):
|
||||||
|
for y in range(min_grid.y, max_grid.y + 1):
|
||||||
|
grids.append(Vector2i(x, y))
|
||||||
|
return grids
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# 地图尺寸规范化
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# 将像素尺寸规范化为网格尺寸的倍数
|
||||||
|
static func normalize_size_to_grid(pixel_size: Vector2i) -> Vector2i:
|
||||||
|
return Vector2i(
|
||||||
|
int(ceil(float(pixel_size.x) / GRID_SIZE)) * GRID_SIZE,
|
||||||
|
int(ceil(float(pixel_size.y) / GRID_SIZE)) * GRID_SIZE
|
||||||
|
)
|
||||||
|
|
||||||
|
# 计算指定像素尺寸需要多少个网格单元
|
||||||
|
static func get_grid_count(pixel_size: Vector2i) -> Vector2i:
|
||||||
|
return Vector2i(
|
||||||
|
int(ceil(float(pixel_size.x) / GRID_SIZE)),
|
||||||
|
int(ceil(float(pixel_size.y) / GRID_SIZE))
|
||||||
|
)
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# 调试和可视化辅助
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# 获取网格的边界矩形(用于调试绘制)
|
||||||
|
static func get_grid_rect(grid_pos: Vector2i) -> Rect2:
|
||||||
|
var world_pos = grid_to_world(grid_pos)
|
||||||
|
return Rect2(world_pos, Vector2(GRID_SIZE, GRID_SIZE))
|
||||||
|
|
||||||
|
# 打印网格信息(调试用)
|
||||||
|
static func print_grid_info(world_pos: Vector2) -> void:
|
||||||
|
var grid_pos = world_to_grid(world_pos)
|
||||||
|
var snapped_pos = snap_to_grid(world_pos)
|
||||||
|
var center_pos = grid_to_world_center(grid_pos)
|
||||||
|
|
||||||
|
print("世界坐标: ", world_pos)
|
||||||
|
print("网格坐标: ", grid_pos)
|
||||||
|
print("吸附位置: ", snapped_pos)
|
||||||
|
print("网格中心: ", center_pos)
|
||||||
1
_Core/systems/GridSystem.gd.uid
Normal file
1
_Core/systems/GridSystem.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://dceqpffgti4jb
|
||||||
Reference in New Issue
Block a user