这是成品,可以看到黑色的方块会自动躲避红色的方块
这是项目结构,每个方块的尺寸都为25*25
新建三个脚本文件role.ts Map.ts obstacle.ts
//Map.ts
const { ccclass, property } = cc._decorator;
export interface Pos {
x: number,
y: number,
f?: number
}
@ccclass
export default class NewClass extends cc.Component {
//障碍物位置信息
obstaclePos: Pos[] = []
//role节点
role: cc.Node = null
onLoad() {
this.role = this.node.getChildByName('role')
this.node.on(cc.Node.EventType.MOUSE_DOWN, this.updateDestination, this)
}
//鼠标按下更新目的地位置
updateDestination(event: cc.Event.EventTouch) {
let pos: cc.Vec2 = event.getLocation();
pos = this.node.convertToNodeSpaceAR(pos);
let isOb = false;
if (this.obstaclePos.length != 0) {
for (let i = 0; i < this.obstaclePos.length; i++) {
if (this.obstaclePos[i].x != Math.round(pos.x / 25) * 25 || this.obstaclePos[i].y != Math.round(pos.y / 25) * 25) {
continue;
}
isOb = true;
}
}
if (!isOb) {
let roleJs = this.role.getComponent('role');
//初始化
roleJs.destination = { x: Math.round(pos.x / 25) * 25, y: Math.round(pos.y / 25) * 25 };
roleJs.alreayRoad = []
roleJs.begin = { x: this.role.x, y: this.role.y }
roleJs.alreayRoad.push({ x: this.role.x, y: this.role.y })
}
}
}
接着是障碍物脚本
const { ccclass, property } = cc._decorator;
import Map, { Pos } from './Map';
@ccclass
export default class NewClass extends cc.Component {
//地图脚本
mapTs: Map = null
//地图节点
mapNode: cc.Node = null
onLoad() {
this.mapTs = this.node.parent.getComponent('Map');
this.mapNode = this.node.parent
this.setObstaclePos()
}
//障碍物位置信息,存进地图脚本里
setObstaclePos() {
let targetPos: Pos[] = this.mapTs.obstaclePos;
targetPos.push({ x: this.node.x, y: this.node.y });
}
start() {
}
update(dt) {
}
}
然后挂载到角色身上的脚本
import { Pos } from "./Map";
const { ccclass, property } = cc._decorator;
@ccclass
export default class NewClass extends cc.Component {
//目的地位置
destination: Pos = null
//起点方格
begin: Pos = null
//已经走过的路径
alreayRoad: Pos[] = [];
//计数一秒
onLoad() {
}
start() {
}
update(dt) {
if (this.destination && this.begin && (this.destination.x != this.begin.x || this.destination.y != this.begin.y)) {
this.filterObstacle(this.begin)
this.node.x = this.begin.x;
this.node.y = this.begin.y;
}
if (this.destination&&this.begin&&this.destination.x == this.begin.x && this.destination.y == this.begin.y) {
this.alreayRoad = []
this.begin = null
}
}
//过滤路径周围障碍物方格
filterObstacle(pos: Pos) {
//起点周围的八个格子
let list: Pos[] = [{ x: pos.x + 25, y: pos.y, f: 10 + (Math.abs(pos.x + 25 - this.destination.x) / 25 + Math.abs(pos.y - this.destination.y) / 25) * 10 },
{ x: pos.x - 25, y: pos.y, f: 10 + (Math.abs(pos.x - 25 - this.destination.x) / 25 + Math.abs(pos.y - this.destination.y) / 25) * 10 },
{ x: pos.x, y: pos.y + 25, f: 10 + (Math.abs(pos.x - this.destination.x) / 25 + Math.abs(pos.y + 25 - this.destination.y) / 25) * 10 },
{ x: pos.x, y: pos.y - 25, f: 10 + (Math.abs(pos.x - this.destination.x) / 25 + Math.abs(pos.y - 25 - this.destination.y) / 25) * 10 },
{ x: pos.x + 25, y: pos.y + 25, f: 14 + (Math.abs(pos.x + 25 - this.destination.x) / 25 + Math.abs(pos.y + 25 - this.destination.y) / 25) * 10 },
{ x: pos.x + 25, y: pos.y - 25, f: 14 + (Math.abs(pos.x + 25 - this.destination.x) / 25 + Math.abs(pos.y - 25 - this.destination.y) / 25) * 10 },
{ x: pos.x - 25, y: pos.y - 25, f: 14 + (Math.abs(pos.x - 25 - this.destination.x) / 25 + Math.abs(pos.y - 25 - this.destination.y) / 25) * 10 },
{ x: pos.x - 25, y: pos.y + 25, f: 14 + (Math.abs(pos.x - 25 - this.destination.x) / 25 + Math.abs(pos.y + 25 - this.destination.y) / 25) * 10 }];
//获取障碍物位置数组
let obstaclePosList = this.node.parent.getComponent('Map').obstaclePos
//过滤完障碍物的数组
let filterObList: Pos[] = []
//过滤障碍物
for (let i = 0; i < list.length; i++) {
let isOb =false
for (let j = 0; j < obstaclePosList.length; j++) {
if (list[i].x != obstaclePosList[j].x||list[i].y != obstaclePosList[j].y) {
continue;
}
isOb = true;
break;
}
if (!isOb) {
filterObList.push(list[i])
}
}
//过滤已经走过的路径
let lastList:Pos[] = []
for (let i = 0; i < filterObList.length; i++) {
let isOb = false
for (let j = 0; j < this.alreayRoad.length; j++) {
if (filterObList[i].x != this.alreayRoad[j].x || filterObList[i].y != this.alreayRoad[j].y) {
continue;
}
isOb = true;
break;
}
if (!isOb) {
lastList.push(filterObList[i])
}
}
let min = lastList[0].f
let minIndex = 0
for (let i = 0; i < lastList.length; i++) {
if (lastList[i].f <= min) {
min = lastList[i].f
minIndex = i
}
}
this.alreayRoad.push(lastList[minIndex])
this.begin = lastList[minIndex]
}
}

