A* (AStar) 寻路

//调用工具类获取路线

        let route = AStarSearch.getRoute(start_point, end_point, this.mapFloor.map_point);

map_point 是所有可走点的集合

import { _decorator, Component, Node, Prefab, instantiate, v3, Vec2 } from 'cc';
import { oops } from "../../../../../extensions/oops-plugin-framework/assets/core/Oops";
import { GameWorld } from "../../../GameWorld";
import { MapFloor, RowColData } from "../../../../Scripts/MapEditor/MapFloor";export class Point {x: number;y: number;constructor(x: number, y: number) {this.x = x;this.y = y;}G: number = 0;   //G = 从起点A,沿着产生的路径,移动到网格上指定方格的移动耗费。H: number = 0;   //H = 从网格上那个方格移动到终点B的预估移动耗费F: number = 0;   //F = G + Hfather: Point = null;   //这个点的上一个点,通过回溯可以找到起点 is_close: boolean = false;   //是否关闭搜索
}export class AStarSearch {static start: Point = null;      //起点static end: Point = null;        //终点static map: Map<string, Point> = null;   //地图pointstatic openSet: Set<Point> = new Set();  //开放队列static pppp: Point = null;       //执行完寻路,它就有值了,除非没找到/*** 获取路线 (此寻路不走斜线)*/static getRoute(start: Point, end: Point, map_point: Map<string, { row: number, col: number }>): Point[] {//清空上次寻路,并赋值this.is_find = false;this.openSet.clear();this.pppp = null;this.start = { ...start };this.end = { ...end };this.map = new Map<string, Point>();map_point.forEach((value, key) => {let point = new Point(value.row, value.col);this.map.set(key, point);});let route = new Array<Point>();let keyStr = this.start.x + "_" + this.start.y;if (!this.map.has(keyStr)) {return route;}this.map.get(keyStr).G = 0;       //起点的G是0//开始寻路try {this.search(this.start);     //内存不够会报错,一般是起点或终点封闭} catch (error) {console.warn("位置不对", error);return route;}if (this.pppp) {this.getFather(this.pppp, route);}return route;}/*** 寻路*/static is_find = false;    //是否已经找到路线static search(point: Point) {if (point.x == this.end.x && point.y == this.end.y) {this.is_find = true;this.pppp = point;return;}let arr = this.getAround(point);arr.forEach(p => {this.setFather(p, point);});//arr按照F排序 从小到大this.openSet = new Set([...this.openSet].sort(this.compare));//递归继续找this.openSet.forEach((pp, index, arr) => {if (pp.is_close) {        //删除没用的this.openSet.delete(pp);}if (!this.is_find) {this.search(pp);}});}/*** 获取周围4个点,上下左右*/static getAround(point: Point) {point.is_close = true;let arr = new Array<Point>();let index: string;let p: Point;//上、下、左、右let aroundPos = [{ x: point.x, y: point.y - 1 },{ x: point.x, y: point.y + 1 },{ x: point.x - 1, y: point.y },{ x: point.x + 1, y: point.y }]aroundPos.forEach(point => {index = point.x + "_" + point.y;p = this.map.get(index);if (p && !p.is_close) {arr.push(p);this.openSet.add(p);}})return arr;}/*** point换父亲,并重新计算G、H、F*/static setFather(son: Point, father: Point) {if (!son.father || son.father.G > father.G) {son.father = father;son.G = son.father.G + 1;son.H = Math.abs(son.x - this.end.x) + Math.abs(son.y - this.end.y);son.F = son.G + son.H;}}/*** 比较器*/static compare(p1: Point, p2: Point) {if (p1.F > p2.F) {return 1;} else {return -1;}}/*** 递归 把祖宗放进route里面*/static getFather(point: Point, route: Array<Point>) {let father = point.father;if (father) {this.getFather(father, route);}route.push(point);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/80181.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度解析动态IP业务核心场景:从技术演进到行业实践

引言&#xff1a;动态IP的技术演进与行业价值 在数字化转型加速的今天&#xff0c;IP地址已从单纯的网络标识演变为支撑数字经济的核心基础设施。动态IP作为灵活高效的地址分配方案&#xff0c;正突破传统认知边界&#xff0c;在网络安全防护、数据价值挖掘、全球业务拓展等领…

MySQL 性能调优:从执行计划到硬件瓶颈

MySQL 性能调优&#xff1a;从执行计划到硬件瓶颈 一、性能调优的宏观视角与核心挑战 在数字化浪潮下&#xff0c;企业数据量呈指数级增长&#xff0c;MySQL 作为主流关系型数据库&#xff0c;面临着巨大的性能压力。某电商平台日均订单量突破千万&#xff0c;高峰期数据库响…

开源数字人框架 AWESOME - DIGITAL - HUMAN:技术革新与行业标杆价值剖析

一、项目核心价值:解锁数字人技术新境界 1. 技术普及:降低准入门槛,推动行业民主化 AWESOME - DIGITAL - HUMAN 项目犹如一场技术春雨,为数字人领域带来了普惠甘霖。它集成了 ASR、LLM、TTS 等关键能力,并提供模块化扩展接口,将原本复杂高深的数字人开发流程,转化为一…

robotframe启动ride.py

我的双击ride.py会自动用pycharm打开&#xff0c;变成代码文件 解决方法&#xff1a;定位到ride.py所在文件夹&#xff08;在anaconda的scripts里面&#xff09;&#xff0c;文件夹上方输入cmd 再输入该命令即可

怎样简单实现不同数据库的表间的 JOIN 运算

数据分析涉及不同业务系统时就要做跨库计算&#xff0c;而表间 JOIN 是最麻烦的&#xff0c;很多数据库都不具备这样的能力&#xff0c;用 Java 取数再计算又太复杂。用 esProc 完成跨库 JOIN 会简单很多。 数据与用例 车辆管理系统&#xff08;DB_Vehicle&#xff09;保存了…

Nacos源码—4.Nacos集群高可用分析三

大纲 6.CAP原则与Raft协议 7.Nacos实现的Raft协议是如何写入数据的 8.Nacos实现的Raft协议是如何选举Leader节点的 9.Nacos实现的Raft协议是如何同步数据的 10.Nacos如何实现Raft协议的简版总结 6.CAP原则与Raft协议 (1)CAP分别指的是什么 (2)什么是分区以及容错 (3)为…

普通IT的股票交易成长史--20250509晚复盘

声明&#xff1a; 本文章的内容只是自己学习的总结&#xff0c;不构成投资建议。价格行为理论学习可参考简介中的几位&#xff0c;感谢他们的无私奉献。 送给自己的话&#xff1a; 仓位就是生命&#xff0c;绝对不能满仓&#xff01;&#xff01;&#xff01;&#xff01;&…

python实现点餐系统

使用python实现点餐系统的增加菜品及价格&#xff0c;删除菜品&#xff0c;查询菜单&#xff0c;点菜以及会员折扣价等功能。 代码&#xff1a; 下面展示一些 内联代码片。 # coding utf-8menu {拍黄瓜: 6, 小炒肉: 28, 西红柿炒蛋: 18, 烤鱼: 30, 红烧肉: 38, 手撕鸡: 45,…

从ellisys空口分析蓝牙耳机回连手机失败案例

问题背景&#xff1a; 前两天同事发现我们现在做的项目&#xff0c;耳机在跟某些特定类型安卓手机&#xff08;尤其是比较新的手机&#xff09;回连会失败&#xff0c;然后我帮他分析了一些log&#xff0c;记录如下&#xff1a; 回连失败所做步骤如下&#xff1a; 手机和耳机…

教育+AI:个性化学习能否颠覆传统课堂?

近年来&#xff0c;人工智能&#xff08;AI&#xff09;技术迅猛发展&#xff0c;逐渐渗透到各行各业&#xff0c;教育领域也不例外。从智能辅导系统到自适应学习平台&#xff0c;AI正在改变传统的教学模式&#xff0c;使个性化学习成为可能。然而&#xff0c;这种变革能否真正…

【C++设计模式之Strategy策略模式】

C设计模式之Strategy策略模式 模式定义核心思想动机(Motivation)结构(Structure)实现步骤1. 定义策略接口&#xff08;基于继承&#xff09;2.实现具体策略3.上下文类(Context)4. 在main中调用 应用场景&#xff08;基于继承&#xff09;1.定义策略接口2.实现具体策略3.上下文类…

Python企业级MySQL数据库开发实战指南

简介 Python与MySQL的完美结合是现代Web应用和数据分析系统的基石,能够创建高效稳定的企业级数据库解决方案。本文将从零开始,全面介绍如何使用Python连接MySQL数据库,设计健壮的表结构,实现CRUD操作,并掌握连接池管理、事务处理、批量操作和防止SQL注入等企业级开发核心…

matlab转python

1 matlab2python开源程序 https://blog.csdn.net/qq_43426078/article/details/123384265 2 网址 转换网址&#xff1a;https://app.codeconvert.ai/code-converter?inputLangMatlab&outputLangPython 文件比较网址&#xff1a;https://www.diffchecker.com/text-comp…

Vue 3 中编译时和运行时的概念区别

文章目录 前言Vue 3 中的编译时 vs 运行时区别模板在编译时转化为渲染函数编译时的优化处理运行时的工作:创建组件实例与渲染流程前言 详细整理 Vue 3 中编译时和运行时的概念区别,并重点解释为什么组件实例是在运行时创建的。 我会结合官方文档、源码分析和社区解释,确保内…

Spring 框架实战:如何实现高效的依赖注入,优化项目结构?

Spring 框架实战&#xff1a;如何实现高效的依赖注入&#xff0c;优化项目结构&#xff1f; 在当今的 Java 开发领域&#xff0c;Spring 框架占据着举足轻重的地位。而依赖注入作为 Spring 的核心概念之一&#xff0c;对于构建高效、灵活且易于维护的项目结构有着关键作用。本…

创建虚拟服务时实现持久连接。

在调度器中配置虚拟服务&#xff0c;实现持久性连接&#xff0c;解决会话保持问题。 -p 【timeout】 -p 300 这5分钟之内调度器会把来自同一个客户端的请求转发到同一个后端服务器。【不管使用的调度算法是什么。】【称为持久性连接。】 作用&#xff1a;将客户端一段时间…

说下RabbitMQ的整体架构

RabbitMQ 是一个基于 AMQP&#xff08;Advanced Message Queuing Protocol&#xff09; 协议的开源消息中间件&#xff0c;RabbitMQ的整体架构围绕消息的生产、路由、存储和消费设计&#xff0c;旨在实现高效、可靠的消息传递&#xff0c;它由多个核心组件协同工作。 核心组件 …

STM32--GPIO

教程 视频 博主教程 STM32系统结构图 GPIO GPIO&#xff08;General Purpose Input/Output&#xff09;是STM32内部的一种外设。 一个STM32芯片内存在多个GPIO外设&#xff0c;每个GPIO外设有16个引脚&#xff1b; 比如GPIOA&#xff1a;PA0~PA15; GPIOB&#xff1a;PB0~…

QUIC协议优化:HTTP_3环境下的超高速异步抓取方案

摘要 随着 QUIC 和 HTTP/3 的普及&#xff0c;基于 UDP 的连接复用与内置加密带来了远超 HTTP/2 的性能提升&#xff0c;可显著降低连接握手与拥塞恢复的开销。本文以爬取知乎热榜数据为目标&#xff0c;提出一种基于 HTTPX aioquic 的异步抓取方案&#xff0c;并结合代理 IP设…

[论文阅读]MCP Guardian: A Security-First Layer for Safeguarding MCP-Based AI System

MCP Guardian: A Security-First Layer for Safeguarding MCP-Based AI System http://arxiv.org/abs/2504.12757 推出了 MCP Guardian&#xff0c;这是一个框架&#xff0c;通过身份验证、速率限制、日志记录、跟踪和 Web 应用程序防火墙 &#xff08;WAF&#xff09; 扫描来…