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

请求协助:在ThineCometh项目中实现Bresenham算法并统计视线点数量

ThineCometh项目:Bresenham算法实现与远程攻击命中判断方案

需求背景

我在研究Mizizizi开发的ThineCometh项目时,发现项目缺少关键的Bresenham直线算法实现。项目代码里原本有一段注释掉的_draw函数,用于绘制敌人朝向玩家时的视线圆圈(即演示视频中展示的内容)。现在需要实现以下功能:

  • 用Bresenham算法生成敌人到玩家的视线点
  • 统计有效视线点的数量
  • 根据统计结果判断远程攻击是否能命中敌人

具体实现步骤

1. 实现Bresenham直线算法

编写GDScript版本的Bresenham算法,生成敌人与玩家之间的所有像素/网格点,作为视线的基础:

func get_bresenham_points(start: Vector2, end: Vector2) -> Array[Vector2]:
    var points = []
    var x0 = start.x.floor()
    var y0 = start.y.floor()
    var x1 = end.x.floor()
    var y1 = end.y.floor()

    var dx = abs(x1 - x0)
    var dy = abs(y1 - y0)
    var sx = x0 < x1 ? 1 : -1
    var sy = y0 < y1 ? 1 : -1
    var err = dx - dy

    while true:
        points.append(Vector2(x0, y0))
        if x0 == x1 and y0 == y1:
            break
        var e2 = 2 * err
        if e2 > -dy:
            err -= dy
            x0 += sx
        if e2 < dx:
            err += dx
            y0 += sy
    return points

2. 生成并过滤有效视线点

生成视线点后,过滤掉被障碍物遮挡的点,同时统计剩余有效点的数量:

var sight_points: Array[Vector2] = []

func update_sight(player_pos: Vector2):
    # 生成原始视线点
    var raw_points = get_bresenham_points(self.global_position, player_pos)
    sight_points.clear()
    
    # 过滤障碍物(假设障碍物在碰撞层2)
    var obstacle_mask = 1 << 2
    var space_state = get_world_2d().direct_space_state
    
    for point in raw_points:
        var query = PhysicsPointQueryParameters2D.new()
        query.position = point
        query.collision_mask = obstacle_mask
        # 如果该点没有碰撞到障碍物,加入有效视线点
        if space_state.intersect_point(query).empty():
            sight_points.append(point)
    
    # 统计有效视线点数量
    var valid_sight_count = sight_points.size()
    # 此处可根据需求将count用于后续逻辑

3. 恢复并完善_draw函数

取消原注释,让视线点可视化:

func _draw():
    for sp in sight_points:
        draw_circle(sp, 4, Color.red)

4. 远程攻击命中判断逻辑

通过对比有效视线点数量与无遮挡时的理论点数量,判断是否可以命中玩家:

func can_hit_player(player_pos: Vector2) -> bool:
    update_sight(player_pos)
    # 获取无遮挡时的理论视线点总数
    var ideal_point_count = get_bresenham_points(self.global_position, player_pos).size()
    # 若有效点数量等于理论数量,说明无遮挡,可命中
    return sight_points.size() == ideal_point_count

内容的提问来源于stack exchange,提问作者Marcelo João

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 11:25:18