A*寻路TS实现

const {ccclass, property} = cc._decorator;

@ccclass
export default class Helloworld extends cc.Component {

@property(cc.Prefab)
blockPb: cc.Prefab = null;

@property(cc.Node)
DITU: cc.Node = null;

@property
openList:any [] = null;

@property
closeList:any [] = null;

@property
blockMap:any = null;

@property
startPoint:any = null;

@property
endPoint:any = null;

onLoad(){
    this.openList = [];
    this.closeList = []
    this.blockMap = {};
    this.initMap();
    this.setStartAndEnd(2,7,14,5);
}

initMap(){
    for(let i=1; i<=15; ++i){
        for(let j=1; j<=15; ++j){
            let block = cc.instantiate(this.blockPb);
            let pos = cc.v2((j-1)*40,(i-1)*40)
            this.DITU.addChild(block);
            block.setPosition(pos);
            this.blockMap[j+"#"+i] = block;
        }
    }
}

setStartAndEnd(sx: number,sy: number,ex: number,ey: number){
    this.startPoint = cc.v2(sx,sy)
    this.endPoint = cc.v2(ex,ey)
    this.blockMap[sx+"#"+sy].getComponent("Block").setColor(new cc.Color(0,255,0))
    this.blockMap[ex+"#"+ey].getComponent("Block").setColor(new cc.Color(0,255,255))  
}

isInRange(target:cc.Vec2, p: cc.Vec2, ignoreCorner?: boolean){
    if(p.x > 0 && p.x <=15 && p.y>0 && p.y <= 15){//在地图内
        if(Math.abs(target.x-p.x)==1&&Math.abs(target.y-p.y)==1){//是否忽略斜对角
            return ignoreCorner;
        }
        return true;
    }
    return false;
}

findPath(){
    this.openList.push(this.startPoint);//把起点加入开放列表
    while(this.openList.length!=0){
        let curPoint = this.getMinF();//从开放列表中返回F值最小的节点
        this.pushInClose(curPoint);//加入closelist
        let arr = this.getAllNearBlock(curPoint);//找出这个节点相邻的节点
        for(let i=0; i<arr.length; ++i){
            let p = arr[i];
            let block = this.blockMap[p.x+"#"+p.y].getComponent("Block")
            if(block.pass && !this.isInclude(p)){//不存在与openlist
                let block = this.blockMap[p.x+"#"+p.y].getComponent("Block")
                this.openList.push(p);
                 //从新计算FGH
                block.G = (Math.abs(curPoint.x-p.x) + Math.abs(curPoint.y-p.y))== 1 ? 10 : 14;
                block.H = (Math.abs(this.endPoint.x-p.x) + Math.abs(this.endPoint.y-p.y) - 1)*10;
                block.F = block.G+block.H;
                block.father = curPoint;
            }
            else if(block.pass && this.isInclude(p)){//已经存在于openList
                let tempG = (Math.abs(curPoint.x-p.x) + Math.abs(curPoint.y-p.y))== 1 ? 10 : 14;
                if(tempG < block.G){//小于原先的G值
                    block.G = tempG;
                    block.father = curPoint;
                    block.F = block.G+block.H;
                }
            }
            let target = this.isInclude(this.endPoint);
            if(target) return target;
        }
        
    }
  
    return null;
   
}

drawPath(){
    let tagert = this.findPath();
    let path = [];
    while(tagert){
        path.push(tagert)
        let block = this.blockMap[tagert.x+"#"+tagert.y].getComponent("Block");
        block.setColor(new cc.Color(0,255,0));
        tagert = block.father;
    }
    this.openList.length = 0;
    this.closeList.length = 0;
}

pushInClose(p:cc.Vec2){
    //移除openlist
    for(let i=0; i<this.openList.length; ++i){
        let point = this.openList[i];
        if(point.x == p.x && point.y == p.y){
            this.openList.splice(i,1);
            break;
        }
    }
    this.closeList.push(p);
}

//得到所有相邻的节点并且加入到开放列表
getAllNearBlock(point: cc.Vec2){
    let arr = []
    for(let i=-1;i<=1;++i){
        for(let j=-1; j<=1; ++j){
            let p = cc.v2(point.x+i,point.y+j);
            if(i==0&&j==0) continue;
            if(this.isInRange(point,p,false) && !this.isInClose(p)) arr.push(p);
        }
    }
    return arr;
}

isInClose(p: cc.Vec2): cc.Vec2 {

    for(let i=0; i<this.closeList.length; ++i){
        if(p.x == this.closeList[i].x && p.y == this.closeList[i].y) return p;
    }
    return null;  
}

isInclude(p:cc.Vec2){
    for(let i=0; i<this.openList.length; ++i){
        if(p.x == this.openList[i].x && p.y == this.openList[i].y) return p;
    }
    return null;
}

//得到最小F值的方块
getMinF(){
    if(this.openList.length!=0){
        let resP = this.openList[0];
        let rersB = this.blockMap[resP.x+"#"+resP.y].getComponent("Block");
        this.openList.forEach(point => {
            let block = this.blockMap[point.x+"#"+point.y].getComponent("Block");
            if(block.F < rersB.F){
                rersB = block;
                resP = point;
            }
        });
        return resP;
    }
    return null;
}

}

const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {

@property
F: number = 0;

@property
G: number = 0;

@property
H: number = 0;

@property
pass: boolean = true;

@property
father:any = null;
// LIFE-CYCLE CALLBACKS:

onLoad () {
    this.node.on("touchend",this.jam,this)
}

jam(){
    this.node.color = new cc.Color(100,100,100);
    this.pass = false;
}

setColor(color){
    this.node.color = color;
}

getF(){
    this.F = this.G + this.H;
   return this.F;
}


// update (dt) {}

}

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
A*寻路算法是一种启发式搜索算法,用于在图形(如地图)中找到从起点到终点的最短路径。以下是一个基本的A*寻路算法实现,其中使用了一个优先队列来存储待扩展的节点。 ``` class Node: def __init__(self, x, y): self.x = x self.y = y self.g = 0 self.h = 0 self.f = 0 self.parent = None def __eq__(self, other): return self.x == other.x and self.y == other.y def __lt__(self, other): return self.f < other.f def astar(maze, start, end): # 初始化起点和终点节点 start_node = Node(start[0], start[1]) end_node = Node(end[0], end[1]) # 创建开放列表和关闭列表 open_list = [] closed_list = [] # 将起点加入开放列表 open_list.append(start_node) # 开始寻路循环 while len(open_list) > 0: # 从开放列表中找到f值最小的节点 current_node = min(open_list) open_list.remove(current_node) closed_list.append(current_node) # 判断是否到达终点节点 if current_node == end_node: path = [] while current_node is not None: path.append((current_node.x, current_node.y)) current_node = current_node.parent return path[::-1] # 获取当前节点相邻的节点 children = [] for new_pos in [(0, -1), (0, 1), (-1, 0), (1, 0)]: node_pos = (current_node.x + new_pos[0], current_node.y + new_pos[1]) # 确保节点在迷宫范围内 if node_pos[0] > (len(maze) - 1) or node_pos[0] < 0 or node_pos[1] > (len(maze[0]) - 1) or node_pos[1] < 0: continue # 确保节点不是障碍物 if maze[node_pos[0]][node_pos[1]] != 0: continue # 创建新节点并计算f值 new_node = Node(node_pos[0], node_pos[1]) new_node.parent = current_node new_node.g = current_node.g + 1 new_node.h = ((new_node.x - end_node.x) ** 2) + ((new_node.y - end_node.y) ** 2) new_node.f = new_node.g + new_node.h children.append(new_node) # 将子节点加入开放列表 for child in children: if child in closed_list: continue for open_node in open_list: if child == open_node and child.g > open_node.g: continue open_list.append(child) # 未找到路径 return None ``` 在上述实现中,Node类表示一个节点,其中包含节点的坐标、g值、h值和f值,以及指向父节点的指针。astar函数接受一个迷宫(表示障碍物和可行路径)以及起点和终点的坐标,并返回从起点到终点的最短路径。该函数使用一个优先队列来存储待扩展的节点,并在每次迭代中找到f值最小的节点进行扩展。在扩展节点时,该函数会计算每个相邻节点的f值,并将它们添加到开放列表中。如果找到终点节点,则该函数会回溯父节点以计算最短路径。如果未找到路径,则该函数返回None。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值