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