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) {}

}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值