You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改代码实现六边形瓦片地图中CharacterBody2D的移动?

六边形瓦片地图角色移动实现(Godot 2D)

现有代码是四方向移动逻辑,六边形地图需要适配6个移动方向,下面分两种常见场景给出修改方案:


方案1:格子锁定式移动(战棋类常用)

这种方式下角色会从当前格子直接移动到相邻的可通行格子,适合回合制或战棋游戏。

修改后的代码

extends CharacterBody2D

@export var move_duration: float = 0.3  # 移动到相邻格子的耗时(秒)
@export var tilemap: TileMap  # 拖入场景中的六边形瓦片地图
var target_pos: Vector2? = null  # 目标格子的世界位置

func _input(event):
    # 只有在未移动时响应输入
    if target_pos == null:
        # 适配 odd-r 类型(点向上)的六边形方向偏移
        var dir_offsets = {
            "hex_up": Vector2(0, -1),
            "hex_up_right": Vector2(1, -1),
            "hex_down_right": Vector2(1, 0),
            "hex_down": Vector2(0, 1),
            "hex_down_left": Vector2(-1, 0),
            "hex_up_left": Vector2(-1, -1)
        }

        for action, offset in dir_offsets:
            if event.is_action_pressed(action):
                # 获取当前角色所在的格子坐标
                var current_tile = tilemap.local_to_map(position)
                # 计算目标格子坐标
                var target_tile = current_tile + offset
                # 检查目标格子是否可通行(可根据你的地图规则修改)
                if tilemap.get_cellv(target_tile) != -1:
                    # 转换格子坐标为世界位置(加上瓦片中心偏移)
                    target_pos = tilemap.map_to_local(target_tile) + tilemap.tile_size / 2
                    break

func _physics_process(delta):
    if target_pos != null:
        # 计算移动方向和速度
        var move_dir = (target_pos - position).normalized()
        velocity = move_dir * (tilemap.tile_size.x / move_duration)
        move_and_slide()

        # 到达目标位置后重置状态
        if position.distance_to(target_pos) < 2:
            position = target_pos
            target_pos = null
            velocity = Vector2.ZERO

配置步骤

  1. 打开项目设置 -> 输入映射,添加6个动作:hex_up、hex_up_right、hex_down_right、hex_down、hex_down_left、hex_up_left,分别绑定对应的按键(比如W、E、D、S、A、Q)。
  2. 在场景中选中角色节点,将你的六边形TileMap拖入检查器的tilemap变量槽中。
  3. 可通行判断逻辑可根据需求修改,比如改用图层标记、自定义瓦片属性等。

方案2:自由式六边形方向移动(动作类常用)

这种方式保留类似四方向的自由移动,但限制移动方向为六边形的6个轴向,适合动作类六边形地图游戏。

修改后的代码

extends CharacterBody2D

@export var speed: int = 35
# 适配 odd-r 类型(点向上)的6个方向向量
var hex_dirs = [
    Vector2(0, -1),
    Vector2(1, -1),
    Vector2(1, 0),
    Vector2(0, 1),
    Vector2(-1, 0),
    Vector2(-1, -1)
]

func handleInput():
    var move_dir = Vector2.ZERO
    # 检测6个方向的输入
    if Input.is_action_pressed("hex_up"):
        move_dir += hex_dirs[0]
    if Input.is_action_pressed("hex_up_right"):
        move_dir += hex_dirs[1]
    if Input.is_action_pressed("hex_down_right"):
        move_dir += hex_dirs[2]
    if Input.is_action_pressed("hex_down"):
        move_dir += hex_dirs[3]
    if Input.is_action_pressed("hex_down_left"):
        move_dir += hex_dirs[4]
    if Input.is_action_pressed("hex_up_left"):
        move_dir += hex_dirs[5]

    # 归一化方向,避免多方向同时按下时速度过快
    if move_dir.length() > 0:
        move_dir = move_dir.normalized()
    velocity = move_dir * speed

func _physics_process(delta):
    handleInput()
    move_and_slide()

注意事项

  • 如果你的六边形地图是边向上类型(Offset为odd-q/even-q),需要替换hex_dirs为以下向量:
    var hex_dirs = [
        Vector2(1, 0),
        Vector2(0, -1),
        Vector2(-1, -1),
        Vector2(-1, 0),
        Vector2(0, 1),
        Vector2(1, 1)
    ]
    
  • 同样需要先配置好6个方向的输入映射。

内容的提问来源于stack exchange,提问作者codingbyDEC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 14:17:50