简单四方向a*寻路学习记录7 实现了多个障碍绕行但是绕路

go 复制代码
import { _decorator, Collider2D, Component, Contact2DType, director, IPhysics2DContact, Node } from 'cc';
const { ccclass, property,executeInEditMode } = _decorator;

@ccclass('xiaobingduozhangai')




@executeInEditMode
export class xiaobingduozhangai extends Component {
    juesex:number=null;
    juesey:number=null;
    mubiaox:number=null;
    mubiaoy:number=null;
    shangf:number=0;
    shangg:number=0;

    shangh:number=0;


    zuof:number=0;
    zuoh:number=0;
    zuog:number=0;
    youf:number=0;
    youh:number=0;
    youg:number=0;
    xiaf:number=0;
    xiah:number=0;
    xiag:number=0;
    shangx:number=0;
    shangy:number=0;
    zuox:number=0;
    zuoy:number=0;
    youx:number=0;
    youy:number=0;
    xiax:number=0;
    xiay:number=0;
    zhangaix:number=0;
    zhangaiy:number=0;
    zhangaifangxiang:number=0;


    zuoguox:number=0;
    zuoguoy:number=0;
    neighbors: {x: number, y: number, f: number}[];
    zuoguo: {x: number, y: number}[];
    ditu:[][]=null;
    onLoad(){

        // 监听碰撞事件

      const collider = this.getComponent(Collider2D);
      
      if (collider) {
          collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
          
          
      }
      director.on('gezi_ditu_xiaobing', this.huoquditu, this);
        

      
      
      
      
      
      
      
      
      
      
      
      
      
      
      

      this.neighbors=[];
      this.zuoguo=[];
    }

    
    // 碰撞回调
    onBeginContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
        if(otherCollider.node.name.includes("shantou")){
            this.scheduleOnce(()=>{

                selfCollider.node.destroy();
            },0.7);
        }
    }
    start() {

        director.emit('xiaobing_position_gezi', this.node.worldPosition);
    }

    update(deltaTime: number) {

    }








    huoquditu(ditu:[][]){
        this.ditu=ditu;
       let len=ditu.length;
       console.log(len+"=");

       for(let y=0;y<len;y++){
        for(let x=0;x<ditu[y].length;x++){
            console.log(ditu[y][x]);
            if(ditu[y][x]==1){
                this.mubiaox=x;

                this.mubiaoy=y;

                console.log("/"+this.mubiaox,this.mubiaoy)
            }else if(ditu[y][x]==7){
                this.juesex=x;
                this.juesey=y;
                console.log("/"+this.juesex,this.juesey);
            }else if(ditu[y][x]==11){
                this.zhangaix=x;
                this.zhangaiy=y;
            }
            
        }
           
       }
       //this.jisuanf(this.juesex,this.juesey);
       this.huoqushangxiazuoyou(this.juesex,this.juesey,0);
    }

    jisuannext(x:number,y:number,f:number,g:number){
        
        
        if(f>0){

            //g=g+1;
            this.huoqushangxiazuoyou(x,y,(g+1));
        }


    }

    panduanzhangai(x:number,y:number):boolean{


        if(x>=10||x<0||y>=10||y<0){
            return true
        }
        if(this.ditu[y][x]==11){
            return true;
        }







        return false;


    }
// 添加一个辅助方法
isAlreadyVisited(x: number, y: number): boolean {
    return this.zuoguo.some(point => point.x === x && point.y === y);
}
    huoqushangxiazuoyou(qidianx:number,qidiany:number,g:number){
        










         // 安全阀
    if(g > 200) {
        console.log("❌ 安全阀激活:已走200步,停止递归");
        return;
    }
    
    // 1. 先记录当前点已经访问过
    this.zuoguo.push({x: qidianx, y: qidiany});
    console.log(`🔵 记录起始点 [${qidianx},${qidiany}] 到已访问列表`+"现在是第"+g);
    
    // 2. 计算四个方向的基础值
    const ng = g + 1;
    
    const directions = [
        { 
            name: '上', x: qidianx, y: qidiany - 1, 
            g: ng, h: 0, f: 0, isValid: true 
        },
        { 
            name: '下', x: qidianx, y: qidiany + 1, 
            g: ng, h: 0, f: 0, isValid: true 
        },
        { 
            name: '左', x: qidianx - 1, y: qidiany, 
            g: ng, h: 0, f: 0, isValid: true 
        },
        { 
            name: '右', x: qidianx + 1, y: qidiany, 
            g: ng, h: 0, f: 0, isValid: true 
        }
    ];
    
    // 3. 为每个方向计算h值和f值,并检查有效性
    let validDirections = [];
    for (let dir of directions) {
        // 计算启发值(Manhattan距离)
        dir.h = Math.abs(dir.x - this.mubiaox) + Math.abs(dir.y - this.mubiaoy);
        
        // 边界惩罚
        if (dir.name === '右' && dir.x >= 9) {
            dir.h += 1;
            console.log(`⚠️ 边界惩罚:右边方向 h+=1`);
        }
        
        dir.f = dir.g + dir.h;
        
        // 检查有效性:障碍物或已访问
        const isObstacle = this.panduanzhangai(dir.x, dir.y);
        const isVisited = this.isAlreadyVisited(dir.x, dir.y);
        
        if (isObstacle) {
            console.log(`❌ ${dir.name}方向 [${dir.x},${dir.y}] 是障碍物`);
            dir.isValid = false;
        } else if (isVisited) {
            console.log(`⏭️ ${dir.name}方向 [${dir.x},${dir.y}] 已访问过`);
            dir.isValid = false;
        } else {
            console.log(`✅ ${dir.name}方向 [${dir.x},${dir.y}] g=${dir.g}, h=${dir.h}, f=${dir.f}`);
            dir.isValid = true;
            // 添加到neighbors(开放列表)
            this.neighbors.push({x: dir.x, y: dir.y, f: dir.f});
            validDirections.push(dir);
        }
    }
    
    // 4. 如果没有有效的方向
    if (validDirections.length === 0) {
        console.log("🚫 没有有效的方向可走!");
        
        // 尝试从neighbors中找未访问的替代点
        let bestAlternative = null;
        let minF = Number.MAX_SAFE_INTEGER;
        
        for (let i = 0; i < this.neighbors.length; i++) {
            const neighbor = this.neighbors[i];
            const notVisited = !this.isAlreadyVisited(neighbor.x, neighbor.y);
            if (neighbor.f >= 0 && neighbor.f < minF && notVisited) {
                minF = neighbor.f;
                bestAlternative = neighbor;
            }
        }
        
        if (bestAlternative) {
            console.log(`🔄 从neighbors中选择替代点 [${bestAlternative.x},${bestAlternative.y}] f=${bestAlternative.f}`);
            // 这里是关键:继续递归这个替代点
            this.huoqushangxiazuoyou(bestAlternative.x, bestAlternative.y, g + 1);
        } else {
            console.log("💀 完全无路可走!");
        }
        return;
    }
    
    // 5. 从有效方向中选择f值最小的
    let bestDirection = validDirections[0];
    for (let i = 1; i < validDirections.length; i++) {
        if (validDirections[i].f < bestDirection.f) {
            bestDirection = validDirections[i];
        }
    }
    
    console.log(`📍 选择方向:${bestDirection.name} [${bestDirection.x},${bestDirection.y}] f=${bestDirection.f}`);
    
    // 6. 更新你的directionData(保持原来结构)
    this.shangx = directions[0].x;
    this.shangy = directions[0].y;
    this.shangf = directions[0].isValid ? directions[0].f : -1;
    this.shangg = directions[0].g;
    this.shangh = directions[0].h;
    
    this.xiax = directions[1].x;
    this.xiay = directions[1].y;
    this.xiaf = directions[1].isValid ? directions[1].f : -1;
    this.xiag = directions[1].g;
    this.xiah = directions[1].h;
    
    this.zuox = directions[2].x;
    this.zuoy = directions[2].y;
    this.zuof = directions[2].isValid ? directions[2].f : -1;
    this.zuog = directions[2].g;
    this.zuoh = directions[2].h;
    
    this.youx = directions[3].x;
    this.youy = directions[3].y;
    this.youf = directions[3].isValid ? directions[3].f : -1;
    this.youg = directions[3].g;
    this.youh = directions[3].h;
    
    const directionData = {
        shangf: this.shangf,
        xiaf: this.xiaf,
        zuof: this.zuof,
        youf: this.youf,
        shangx: this.shangx,
        shangy: this.shangy,
        zuox: this.zuox,
        zuoy: this.zuoy,
        youx: this.youx,
        youy: this.youy,
        xiax: this.xiax,
        xiay: this.xiay,
        zuixiaof: bestDirection.f,
        zuixiaofangxiangx: bestDirection.x,
        zuixiaofangxiangy: bestDirection.y,
        mubiaox: this.mubiaox,
        mubiaoy: this.mubiaoy,
        juesex: this.juesex,
        juesey: this.juesey
    };
    
    // 7. 记录要去的点(在发送事件之前)
    this.zuoguo.push({x: bestDirection.x, y: bestDirection.y});
    
    // 8. 发送绘制事件
    director.emit('xiaobing_sxzy_gezi', directionData);
    
    // 9. 检查是否到达目标
    if (bestDirection.x === this.mubiaox && bestDirection.y === this.mubiaoy) {
        console.log("🎯 到达目标!");
        return;
    }
    
    // 10. 继续递归
    console.log(`继续前进到[${bestDirection.x},${bestDirection.y}]`);
    this.huoqushangxiazuoyou(bestDirection.x, bestDirection.y, bestDirection.g);
}
}
相关推荐
西岸行者3 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意3 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码3 天前
嵌入式学习路线
学习
毛小茛3 天前
计算机系统概论——校验码
学习
babe小鑫3 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms3 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下3 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。3 天前
2026.2.25监控学习
学习
im_AMBER3 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J3 天前
从“Hello World“ 开始 C++
c语言·c++·学习