添加role 删除多余地图文件

This commit is contained in:
2024-08-23 10:35:15 +08:00
parent a97f6bfa80
commit e0431b6fad
55 changed files with 2323 additions and 3343 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,13 @@
{
"ver": "1.1.50",
"importer": "prefab",
"imported": true,
"uuid": "a9ece743-4b57-4605-b051-83ca9ed79bf7",
"files": [
".json"
],
"subMetas": {},
"userData": {
"syncNodeName": "role"
}
}

View File

@@ -2,7 +2,7 @@
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "d69b1760-afe9-4a23-bc30-01ee0adf48cc",
"uuid": "8ff649a8-071c-4be5-ae3d-22d80291867b",
"files": [],
"subMetas": {},
"userData": {}

View File

@@ -2,7 +2,7 @@
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "fbb8e89e-e776-48a5-bad2-bfbbd08cff18",
"uuid": "1c56e8f6-c810-4a25-a499-ae1b39579a83",
"files": [],
"subMetas": {},
"userData": {}

View File

@@ -2,7 +2,7 @@
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "524f315a-8ec1-44fd-95a9-555f0a57a113",
"uuid": "307a4494-1b3f-43d7-a489-8ab3c92bdb76",
"files": [],
"subMetas": {},
"userData": {}

View File

@@ -2,10 +2,8 @@
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "a0091b9b-c39d-45b0-bcec-3f5a5c6258bf",
"uuid": "e2701b2d-48ad-478f-9f91-2dfdcc897ffb",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
"userData": {}
}

View File

@@ -2,10 +2,8 @@
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "6b00edff-eb4a-4dcb-af47-ad707888c9b8",
"uuid": "6bd906b8-b499-4ef5-90e5-1c73bd5d2ceb",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
"userData": {}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "ce8e182a-d776-4361-9de5-cde2246c65a2",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,68 @@
/*
* @Author: dgflash
* @Date: 2021-11-18 17:47:56
* @LastEditors: dgflash
* @LastEditTime: 2022-08-04 15:43:04
*/
import { instantiate, Node, Prefab, tween, Vec3,Label,resources ,SpriteAtlas,Sprite,v3} from "cc";
import { UICallbacks } from "../../../../extensions/oops-plugin-framework/assets/core/gui/layer/Defines";
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { UIID } from "../common/config/GameUIConfig";
import { smc } from "../common/SingletonModuleComp";
import { RoleModelComp } from "./RoleModelComp";
import { RoleSpine } from "./RoleSpine";
import { RoleViewComp } from "./RoleViewComp";
import { RoleSet } from "../common/config/RoleSet";
/** 角色实体 */
@ecs.register(`Role`)
export class Role extends ecs.Entity {
// 数据层
RoleModel!: RoleModelComp;
// 视图层
RoleView!: RoleViewComp;
protected init() {
this.addComponents<ecs.Comp>(
RoleModelComp);
}
destroy(): void {
this.remove(RoleViewComp);
super.destroy();
}
/** 加载角色 */
load(pos: Vec3 = Vec3.ZERO,scale:number = 1,uuid:number=101) {
// var path = "game/monster/"+prefab_path;
var path = "game/heros/role";
var prefab: Prefab = oops.res.get(path, Prefab)!;
var node = instantiate(prefab);
var scene = smc.map.MapView.scene;
node.parent = scene.entityLayer!.node!;
// var as = node.getComponent(MonsterSpine);
node.getChildByName("avatar").setScale(node.getChildByName("avatar").scale.x*scale, node.getChildByName("avatar").scale.y, node.getChildByName("avatar").scale.z);
node.setPosition(pos)
// console.log(node.getChildByName("avatar").getChildByName("TNode").getChildByName("bb").getComponent(Sprite))
const url = 'game/heros/player';
resources.load(url, SpriteAtlas, (err: any, atlas) => {
const sprite = node.getChildByName("avatar").getChildByName("TNode").getChildByName("bb").getComponent(Sprite);
sprite.spriteFrame = atlas.getSpriteFrame(RoleSet[uuid].path);
});
this.hero_init(uuid,node)
oops.message.dispatchEvent("hero_load",this)
}
hero_init(uuid:number=1001,node:Node,pos:Vec3=v3(0,0,0)){
var rv = node.getComponent(RoleViewComp)!;
this.add(rv);
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "9457fea4-0213-4426-a3ed-5234cc7985dc",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -9,16 +9,16 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ec
/**
*
*/
@ecs.register('HeroModel')
export class HeroModelComp extends ecs.Comp {
@ecs.register('RoleModel')
export class RoleModelComp extends ecs.Comp {
/** 角色编号 */
id: number = -1;
/** 角色名 */
name: string = "Hero";
name: string = "Role";
/** 动画名资源 */
anim: string = "Hero";
anim: string = "Role";
reset() {
this.id = -1;

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "1ae88b75-8890-46c0-a795-faf44c20ff92",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -6,18 +6,18 @@
*/
import { Color, Component, EventTouch, sp, Vec3, _decorator } from "cc";
import { LayerUtil } from "../../../../extensions/oops-plugin-framework/assets/core/utils/LayerUtil";
import { smc } from "../../../script/game/common/SingletonModuleComp";
import HeroSpineAnimator from "./HeroSpineAnimator";
import { smc } from "../common/SingletonModuleComp";
import RoleSpineAnimator from "./RoleSpineAnimator";
const { ccclass, property } = _decorator;
/**
*
*/
@ccclass('HeroSpine')
export class HeroSpine extends Component {
@property({ type: HeroSpineAnimator, tooltip: '动画控制器' })
animator: HeroSpineAnimator = null!;
@ccclass('RoleSpine')
export class RoleSpine extends Component {
@property({ type: RoleSpineAnimator, tooltip: '动画控制器' })
animator: RoleSpineAnimator = null!;
private spine!: sp.Skeleton;
@@ -34,7 +34,7 @@ export class HeroSpine extends Component {
}
setSkin(value: string): void {
console.log("HeroSpine setSkin", value);
console.log("RoleSpine setSkin", value);
this.spine.setSkin(value);
}
play(animName: string, loop: boolean): void {

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "de8f3803-ed59-466e-b93b-f1e3e587113d",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -14,13 +14,13 @@ const { ccclass, property, requireComponent, disallowMultiple } = _decorator;
@ccclass
@disallowMultiple
@requireComponent(sp.Skeleton)
export default class HeroSpineAnimator extends Component {
export default class RoleSpineAnimator extends Component {
private animName: string = "move";
private loop: boolean = true;
private spine!: sp.Skeleton;
start() {
this.spine = this.getComponent(sp.Skeleton)!;
// console.log("HeroSpineAnimator start");
// console.log("RoleSpineAnimator start");
this.playAnimation(this.animName, this.loop);
}
@@ -44,9 +44,9 @@ export default class HeroSpineAnimator extends Component {
* @param loop
*/
protected playAnimation(animName: string, loop: boolean) {
// console.log("HeroSpineAnimator playAnimation");
// console.log("RoleSpineAnimator playAnimation");
if (animName) {
// console.log("HeroSpineAnimator playAnimation animName", animName);
// console.log("RoleSpineAnimator playAnimation animName", animName);
this.animName = animName;
this.loop = loop;
this.spine.setAnimation(0, this.animName, this.loop);

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "7238526c-ee07-4d38-be30-ec2a4a5359c4",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,117 @@
/*
* @Author: dgflash
* @Date: 2021-11-18 17:42:59
* @LastEditors: dgflash
* @LastEditTime: 2022-08-17 12:36:18
*/
import { Vec3, v3,_decorator ,Collider2D,Contact2DType,IPhysics2DContact,Material,Sprite,ProgressBar} from "cc";
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
import { RoleSpine } from "./RoleSpine";
import {BoxSet} from "../common/config/BoxSet"
import { smc } from "../common/SingletonModuleComp";
import { SkillCom } from "../skills/SkillCom";
const { ccclass, property } = _decorator;
/** 角色显示组件 */
@ccclass('RoleViewComp') // 定义为 Cocos Creator 组件
@ecs.register('RoleView', false) // 定义为 ECS 组件
export class RoleViewComp extends CCComp {
@property(Material)
hitFlashMaterial: Material;
orginalFlashMaterial: Material;
sprite: Sprite;
/** 角色动画 */
as: RoleSpine = null!;
/** 角色属性 */
hp: number = 1000;
hp_max:number = 1000;
power: number = 0;
stop_cd:number = 0;
atk_cd:number = 0;
atk:number = 2;
onLoad() {
this.as = this.getComponent(RoleSpine);
}
start () {
this.sprite = this.node.getChildByName("avatar").getChildByName("TNode").getChildByName("bb").getComponent(Sprite);
this.orginalFlashMaterial = this.sprite.getRenderMaterial(0);
console.log("Role view start")
let collider = this.getComponent(Collider2D);
if (collider) {
collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
}
}
onBeginContact (selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
if(otherCollider.tag==BoxSet.SKILL_TAG){
if(selfCollider.group != otherCollider.group){
let skill = otherCollider.node.getComponent(SkillCom)!;
// console.log('onPostSolve',skill);
this.in_atked();
if(this.hp <= 0 ){
return
}
this.hp_change(skill.atk);
}
}
}
onEndContact (selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
}
onPreSolve (selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
if(selfCollider.group != otherCollider.group&&otherCollider.tag != BoxSet.ATK_RANGE){
}
}
onPostSolve (selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
if(selfCollider.group == otherCollider.group){
// console.log('monster view group 相同');
}else{
// console.log('monster onPostSolve'+selfCollider.group+"|"+otherCollider.group);
}
}
update(dt: number){
}
reset() {
this.node.destroy();
}
in_atked() {
this.sprite.setSharedMaterial(this.hitFlashMaterial, 0);
this.scheduleOnce(() => {
this.sprite.setSharedMaterial(this.orginalFlashMaterial, 0);
}, 0.1);
}
hp_change(hp: number){
this.hp -= hp;
if(this.hp > this.hp_max){
this.hp = this.hp_max;
}
let hp_progress= this.hp/this.hp_max;
this.node.getChildByName("hp").getComponent(ProgressBar)!.progress = hp_progress;
if(this.hp <= 0){
console.log("dead");
}
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "b8b21b3c-dd6b-466b-8bdf-010481a9c576",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,25 @@
/*
* @Author: dgflash
* @Date: 2021-11-23 15:28:39
* @LastEditors: dgflash
* @LastEditTime: 2022-01-26 16:42:00
*/
export const RoleType = {
1: "前排",
2: "后排",
}
export const RoleSet ={
101:{uuid:"101", name:'魔法师', path:"101",atk:6,atk_cd:2, hp:30, power:50, speed:150,skill:{ }},
102:{uuid:"102", name:'魔法师', path:"102",atk:6,atk_cd:2, hp:30, power:50, speed:150,skill:{ }},
103:{uuid:"103", name:'魔法师', path:"103",atk:6,atk_cd:2, hp:30, power:50, speed:150,skill:{ }},
104:{uuid:"104", name:'魔法师', path:"104",atk:6,atk_cd:2, hp:30, power:50, speed:150,skill:{ }},
105:{uuid:"105", name:'魔法师', path:"105",atk:6,atk_cd:2, hp:30, power:50, speed:150,skill:{ }},
106:{uuid:"106", name:'魔法师', path:"106",atk:6,atk_cd:2, hp:30, power:50, speed:150,skill:{ }},
107:{uuid:"107", name:'魔法师', path:"107",atk:6,atk_cd:2, hp:30, power:50, speed:150,skill:{ }},
108:{uuid:"108", name:'魔法师', path:"108",atk:6,atk_cd:2, hp:30, power:50, speed:150,skill:{ }},
109:{uuid:"109", name:'魔法师', path:"109",atk:6,atk_cd:2, hp:30, power:50, speed:150,skill:{ }},
110:{uuid:"110", name:'魔法师', path:"110",atk:6,atk_cd:2, hp:30, power:50, speed:150,skill:{ }},
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "bde4950f-acae-4c3e-a6a7-39248c34613d",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -5,12 +5,11 @@ import { smc } from "../../common/SingletonModuleComp";
import { BoxSet } from "../../common/config/BoxSet";
import { Hero } from "../../monster/Hero";
import { Monster } from "../../monster/Monster";
// import MapRoadUtils from "./map/road/MapRoadUtils";
import { MapViewScene } from "./MapViewScene";
import { Timer } from "../../../../../extensions/oops-plugin-framework/assets/core/common/timer/Timer";
import { oops } from "../../../../../extensions/oops-plugin-framework/assets/core/Oops";
import { CardSet } from "../../common/config/CardSet";
import { Role } from "../../Role/Role";
const { ccclass, property } = _decorator;
@ccclass('MapViewComp')
@@ -43,7 +42,8 @@ export class MapViewComp extends CCComp {
this.load_role()
}
load_role(){
let role = ecs.getEntity<Role>(Role);
role.load()
}
load_data(){
// let heros = oops.res.get("config/game/heros")

View File

@@ -1,7 +1,5 @@
import { Camera, CCBoolean, Component, EventTouch, Node, screen, Size, Texture2D, UITransform, Vec2, Vec3, view, _decorator } from "cc";
import { oops } from "../../../../../extensions/oops-plugin-framework/assets/core/Oops";
import MapData from "./map/base/MapData";
import { MapLoadModel } from "./map/base/MapLoadModel";
import EntityLayer from "./map/layer/EntityLayer";
import SkillLayer from "./map/layer/SkillLayer";
import MapLayer from "./map/layer/MapLayer";
@@ -64,7 +62,7 @@ export class MapViewScene extends Component {
}
public init(mapData: MapData, bgTex: Texture2D, mapLoadModel: MapLoadModel = 1) {
public init() {
}

View File

@@ -1,12 +0,0 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "b0f6dc85-a76e-4bdf-a11c-d1b518f80db5",
"files": [],
"subMetas": {},
"userData": {
"compressionType": {},
"isRemoteBundle": {}
}
}

View File

@@ -1,16 +0,0 @@
import { MapType } from "./MapType";
export default class MapData {
public name: string = "";
public bgName: string = "";
public type: MapType = MapType.angle45;
public mapWidth: number = 0;
public mapHeight: number = 0;
public nodeWidth: number = 0;
public nodeHeight: number = 0;
public roadDataArr: number[][] = [];
//public row:number = 0;
//public col:number = 0;
public mapItems: object[] = [];
}

View File

@@ -1,14 +0,0 @@
/**
* 地图加载模式
*/
export enum MapLoadModel {
/**
* 单张地图加载
*/
single = 0,
/**
* 分切片加载
*/
slices = 1,
}

View File

@@ -1,11 +0,0 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "2f328b5a-8e30-4411-a6d1-997689a315a7",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -1,74 +0,0 @@
import { MapType } from "./MapType";
import { MapLoadModel } from "./MapLoadModel";
import { Texture2D } from "cc";
/**
* 地图参数
*/
export default class MapParams {
/**
* 地图名称
*/
public name: string = "";
/**
* 底图资源名称
*/
public bgName: string = "";
/**
* 地图类型
*/
public mapType: MapType = MapType.angle45;
/**
* 地图宽
*/
public mapWidth: number = 750;
/**
* 地图高
*/
public mapHeight: number = 1600;
/**
* 地图单元格宽
*/
public ceilWidth: number = 75;
/**
* 地图单元格高
*/
public ceilHeight: number = 75;
/**
* 地图视野宽
*/
public viewWidth: number = 750;
/**
* 地图视野高
*/
public viewHeight: number = 1334;
/**
* 地图切片宽
*/
public sliceWidth: number = 256;
/**
* 地图切片高
*/
public sliceHeight: number = 256;
/**
* 底图加载模式,是单张还是切片加载
*/
public mapLoadModel: MapLoadModel = MapLoadModel.single;
/**
* 地图底图
*/
public bgTex: Texture2D | null = null;
}

View File

@@ -1,6 +0,0 @@
export enum MapType {
angle45 = 0,
angle90 = 1,
honeycomb = 2,
}

View File

@@ -1,11 +0,0 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "967a1a19-a1dd-4241-81d7-a92f041c19e9",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -26,12 +26,13 @@ export default class EntityLayer extends Component {
}
protected start(): void {
console.log("EntityLayer start",this)
// console.log("EntityLayer start",this)
}
public clear() {
this.node.children.forEach(n => {
});
}
}

View File

@@ -2,8 +2,6 @@ import { Component, Layers, Node, Sprite, SpriteFrame, Texture2D, UITransform, V
import { oops } from '../../../../../../../extensions/oops-plugin-framework/assets/core/Oops';
import { LayerUtil } from '../../../../../../../extensions/oops-plugin-framework/assets/core/utils/LayerUtil';
import { smc } from '../../../../common/SingletonModuleComp';
import { MapLoadModel } from '../base/MapLoadModel';
import MapParams from '../base/MapParams';
const { ccclass, property } = _decorator;
@@ -19,7 +17,7 @@ export default class MapLayer extends Component {
@property(Sprite)
private bgImg: Sprite | null = null;
public init(mapParams: MapParams): void {
public init(): void {
this.getComponent(UITransform)!.width = this.width;
this.getComponent(UITransform)!.height = this.height;
}

View File

@@ -47,7 +47,7 @@ export default class SkillLayer extends Component {
}
start(){
console.log("SkillLayer start")
// console.log("SkillLayer start")
}
public clear() {

View File

@@ -1,12 +0,0 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "76609af6-ff56-411b-a2e5-b6a6027fb037",
"files": [],
"subMetas": {},
"userData": {
"compressionType": {},
"isRemoteBundle": {}
}
}

View File

@@ -1,613 +0,0 @@
import RoadNode from "./RoadNode";
import IRoadSeeker from "./IRoadSeeker";
import BinaryTreeNode from "./BinaryTreeNode";
/**
* A*寻路算法
* @author 落日故人 QQ 583051842
*
*/
export default class AStarRoadSeeker implements IRoadSeeker {
/**
* 横向移动一个格子的代价
*/
private COST_STRAIGHT: number = 10;
/**
* 斜向移动一个格子的代价
*/
private COST_DIAGONAL: number = 14;
/**
* 最大搜寻步骤数,超过这个值时表示找不到目标
*/
private maxStep: number = 15000;
/**
* 开启列表
*/
private _openlist: Array<RoadNode>;
/**
*关闭列表
*/
private _closelist: Array<RoadNode>;
/**
* 二叉堆存储结构
*/
private _binaryTreeNode: BinaryTreeNode = new BinaryTreeNode();
/**
*开始节点
*/
private _startNode: RoadNode;
/**
*当前检索节点
*/
private _currentNode: RoadNode;
/**
*目标节点
*/
private _targetNode: RoadNode;
/**
*地图路点数据
*/
private _roadNodes: { [key: number]: RoadNode };
/**
*用于检索一个节点周围8个点的向量数组
*/
private _round: number[][] = [[0, -1], [1, -1], [1, 0], [1, 1], [0, 1], [-1, 1], [-1, 0], [-1, -1]]
private handle: number = -1;
/**
* 是否优化路径
*/
private optimize: boolean = true;
public constructor(roadNodes: { [key: string]: RoadNode }) {
this._roadNodes = roadNodes;
}
/**
*寻路入口方法
* @param startNode
* @param targetNode
* @return
*
*/
public seekPath(startNode: RoadNode, targetNode: RoadNode): Array<RoadNode> {
this._startNode = startNode;
this._currentNode = startNode;
this._targetNode = targetNode;
if (!this._startNode || !this._targetNode)
return [];
if (this._targetNode.value == 1) {
console.log("目标不可达到:");
return [];
}
this._startNode.g = 0; //重置起始节点的g值
this._startNode.resetTree(); //清除起始节点原有的二叉堆关联关系
this._binaryTreeNode.refleshTag(); //刷新二叉堆tag用于后面判断是不是属于当前次的寻路
//this._binaryTreeNode.addTreeNode(this._startNode); //把起始节点设置为二叉堆结构的根节点
var step: number = 0;
while (true) {
if (step > this.maxStep) {
// console.log("没找到目标计算步骤为:", step);
return [];
}
step++;
this.searchRoundNodes(this._currentNode);
if (this._binaryTreeNode.isTreeNull()) //二叉堆树里已经没有任何可搜寻的点了,则寻路结束,每找到目标
{
// console.log("没找到目标计算步骤为:", step);
return [];
}
this._currentNode = this._binaryTreeNode.getMin_F_Node();
if (this._currentNode == this._targetNode) {
// console.log("找到目标计算步骤为:", step);
return this.getPath();
}
else {
this._binaryTreeNode.setRoadNodeInCloseList(this._currentNode);//打入关闭列表标记
}
}
return [];
}
/**
*寻路入口方法 如果没有寻到目标,则返回离目标最近的路径
* @param startNode
* @param targetNode
* @return
*
*/
public seekPath2(startNode: RoadNode, targetNode: RoadNode): Array<RoadNode> {
this._startNode = startNode;
this._currentNode = startNode;
this._targetNode = targetNode;
if (!this._startNode || !this._targetNode)
return [];
var newMaxStep: number = this.maxStep;
if (!this.isPassNode(this._targetNode)) {
//如果不能直达目标,最大寻路步骤 = 为两点间的预估距离的2倍
newMaxStep = (Math.abs(this._targetNode.cx - this._startNode.cx) + Math.abs(this._targetNode.cy - this._startNode.cy)) * 2;
if (newMaxStep > this.maxStep) {
newMaxStep = this.maxStep;
}
}
this._startNode.g = 0; //重置起始节点的g值
this._startNode.resetTree(); //清除起始节点原有的二叉堆关联关系
this._binaryTreeNode.refleshTag(); //刷新二叉堆tag用于后面判断是不是属于当前次的寻路
//this._binaryTreeNode.addTreeNode(this._startNode); //把起始节点设置为二叉堆结构的根节点
var step: number = 0;
var closestNode: RoadNode = null; //距离目标最近的路点
while (true) {
if (step > newMaxStep) {
// console.log("没找到目标计算步骤为:", step);
return this.seekPath(startNode, closestNode);
}
step++;
this.searchRoundNodes(this._currentNode);
if (this._binaryTreeNode.isTreeNull()) //二叉堆树里已经没有任何可搜寻的点了,则寻路结束,没找到目标
{
// console.log("没找到目标计算步骤为:", step);
return this.seekPath(startNode, closestNode);
}
this._currentNode = this._binaryTreeNode.getMin_F_Node();
if (closestNode == null) {
closestNode = this._currentNode;
}
else {
if (this._currentNode.h < closestNode.h) {
closestNode = this._currentNode;
}
}
if (this._currentNode == this._targetNode) {
// console.log("找到目标计算步骤为:", step);
return this.getPath();
}
else {
this._binaryTreeNode.setRoadNodeInCloseList(this._currentNode);//打入关闭列表标记
}
}
return this.seekPath(startNode, closestNode);
}
/**
* 对路节点进行排序
* @param node1
* @param node2
*/
private sortNode(node1: RoadNode, node2: RoadNode) {
if (node1.f < node2.f) {
return -1;
}
else if (node1.f > node2.f) {
return 1;
}
return 0;
}
/**
* 获得最终寻路到的所有路点
* @return
*
*/
private getPath(): Array<RoadNode> {
var nodeArr: Array<RoadNode> = [];
var node: RoadNode = this._targetNode;
while (node != this._startNode) {
nodeArr.unshift(node);
node = node.parent;
}
nodeArr.unshift(this._startNode);
if (!this.optimize) {
return nodeArr;
}
//第一阶段优化: 对横,竖,正斜进行优化
//把多个节点连在一起的,横向或者斜向的一连串点,除两边的点保留
for (var i: number = 1; i < nodeArr.length - 1; i++) {
var preNode: RoadNode = nodeArr[i - 1] as RoadNode;
var midNode: RoadNode = nodeArr[i] as RoadNode;
var nextNode: RoadNode = nodeArr[i + 1] as RoadNode;
var bool1: Boolean = midNode.cx == preNode.cx && midNode.cx == nextNode.cx;
var bool2: Boolean = midNode.cy == preNode.cy && midNode.cy == nextNode.cy;
var bool3: Boolean = ((midNode.cx - preNode.cx) / (midNode.cy - preNode.cy)) * ((nextNode.cx - midNode.cx) / (nextNode.cy - midNode.cy)) == 1
if (bool1 || bool2 || bool3) {
nodeArr.splice(i, 1)
i--;
}
}
//return nodeArr;
//第二阶段优化:对不在横,竖,正斜的格子进行优化
for (var i: number = 0; i < nodeArr.length - 2; i++) {
var startNode: RoadNode = nodeArr[i] as RoadNode;
var optimizeNode: RoadNode = null;
//优先从尾部对比,如果能直达就把中间多余的路点删掉
for (var j: number = nodeArr.length - 1; j > i + 1; j--) {
var targetNode: RoadNode = nodeArr[j] as RoadNode;
//在第一阶段优已经优化过横,竖,正斜了,所以再出现是肯定不能优化的,可以忽略
if (startNode.cx == targetNode.cx || startNode.cy == targetNode.cy || Math.abs(targetNode.cx - startNode.cx) == Math.abs(targetNode.cy - startNode.cy)) {
continue;
}
if (this.isArriveBetweenTwoNodes(startNode, targetNode)) {
optimizeNode = targetNode;
break;
}
}
if (optimizeNode) {
var optimizeLen: number = j - i - 1;
nodeArr.splice(i + 1, optimizeLen);
}
}
return nodeArr;
}
/**
* 两点之间是否可到达
*/
private isArriveBetweenTwoNodes(startNode: RoadNode, targetNode: RoadNode): boolean {
if (startNode == targetNode) {
return false;
}
var disX: number = Math.abs(targetNode.cx - startNode.cx);
var disY: number = Math.abs(targetNode.cy - startNode.cy);
var dirX = 0;
if (targetNode.cx > startNode.cx) {
dirX = 1;
}
else if (targetNode.cx < startNode.cx) {
dirX = -1;
}
var dirY = 0;
if (targetNode.cy > startNode.cy) {
dirY = 1;
}
else if (targetNode.cy < startNode.cy) {
dirY = -1;
}
var rx: number = 0;
var ry: number = 0;
var intNum: number = 0;
var decimal: number = 0;
if (disX > disY) {
var rate: number = disY / disX;
for (var i = 0; i < disX; i++) {
ry = startNode.cy + i * dirY * rate;
intNum = Math.floor(ry);
decimal = ry % 1;
var cx1: number = startNode.cx + i * dirX;
var cy1: number = decimal <= 0.5 ? intNum : intNum + 1;
ry = startNode.cy + (i + 1) * dirY * rate;
intNum = Math.floor(ry);
decimal = ry % 1;
var cx2: number = startNode.cx + (i + 1) * dirX;
var cy2: number = decimal <= 0.5 ? intNum : intNum + 1;
var node1: RoadNode = this._roadNodes[cx1 + "_" + cy1] as RoadNode;
var node2: RoadNode = this._roadNodes[cx2 + "_" + cy2] as RoadNode;
//cc.log(i + " :: " + node1.cy," yy ",startNode.cy + i * rate,ry % 1);
if (!this.isCrossAtAdjacentNodes(node1, node2)) {
return false;
}
}
} else {
var rate: number = disX / disY;
for (var i = 0; i < disY; i++) {
rx = i * dirX * rate;
intNum = dirX > 0 ? Math.floor(startNode.cx + rx) : Math.ceil(startNode.cx + rx);
decimal = Math.abs(rx % 1);
var cx1: number = decimal <= 0.5 ? intNum : intNum + 1 * dirX;
var cy1: number = startNode.cy + i * dirY;
rx = (i + 1) * dirX * rate;
intNum = dirX > 0 ? Math.floor(startNode.cx + rx) : Math.ceil(startNode.cx + rx);
decimal = Math.abs(rx % 1);
var cx2: number = decimal <= 0.5 ? intNum : intNum + 1 * dirX;
var cy2: number = startNode.cy + (i + 1) * dirY;
var node1: RoadNode = this._roadNodes[cx1 + "_" + cy1] as RoadNode;
var node2: RoadNode = this._roadNodes[cx2 + "_" + cy2] as RoadNode;
if (!this.isCrossAtAdjacentNodes(node1, node2)) {
return false;
}
}
}
return true;
}
/**
* 判断两个相邻的点是否可通过
* @param node1
* @param node2
*/
private isCrossAtAdjacentNodes(node1: RoadNode, node2: RoadNode): boolean {
if (node1 == node2) {
return false;
}
//两个点只要有一个点不能通过就不能通过
if (!this.isPassNode(node1) || !this.isPassNode(node2)) {
return false;
}
var dirX = node2.cx - node1.cx;
var dirY = node2.cy - node1.cy
//如果不是相邻的两个点 则不能通过
if (Math.abs(dirX) > 1 || Math.abs(dirY) > 1) {
return false;
}
//如果相邻的点是在同一行,或者同一列,则判定为可通过
if ((node1.cx == node2.cx) || (node1.cy == node2.cy)) {
return true;
}
//只剩对角情况了
if (
this.isPassNode(this._roadNodes[node1.cx + "_" + (node1.cy + dirY)]) &&
this.isPassNode(this._roadNodes[(node1.cx + dirX) + "_" + node1.cy])
) {
return true;
}
return false;
}
/**
* 是否是可通过的点
* @param node
*/
private isPassNode(node: RoadNode): boolean {
if (!node || node.value == 1) {
return false;
}
return true;
}
/**
*测试寻路步骤
* @param startNode
* @param targetNode
* @return
*
*/
public testSeekPathStep(startNode: RoadNode, targetNode: RoadNode, callback: Function, target: any, time: number = 100): void {
this._startNode = startNode;
this._currentNode = startNode;
this._targetNode = targetNode;
if (this._targetNode.value == 1)
return;
this._startNode.g = 0; //重置起始节点的g值
this._startNode.resetTree(); //清除起始节点原有的二叉堆关联关系
this._binaryTreeNode.refleshTag(); //刷新二叉堆tag用于后面判断是不是属于当前次的寻路
//this._binaryTreeNode.addTreeNode(this._startNode); //把起始节点设置为二叉堆结构的根节点
this._closelist = [];
var step: number = 0;
clearInterval(this.handle);
this.handle = setInterval(() => {
if (step > this.maxStep) {
// console.log("没找到目标计算步骤为:", step);
clearInterval(this.handle);
return;
}
step++;
this.searchRoundNodes(this._currentNode);
if (this._binaryTreeNode.isTreeNull()) //二叉堆树里已经没有任何可搜寻的点了,则寻路结束,每找到目标
{
// console.log("没找到目标计算步骤为:", step);
clearInterval(this.handle);
return;
}
this._currentNode = this._binaryTreeNode.getMin_F_Node();
if (this._currentNode == this._targetNode) {
// console.log("找到目标计算步骤为:", step);
clearInterval(this.handle);
this._openlist = this._binaryTreeNode.getOpenList();
callback.apply(target, [this._startNode, this._targetNode, this._currentNode, this._openlist, this._closelist, this.getPath()]);
}
else {
this._binaryTreeNode.setRoadNodeInCloseList(this._currentNode);//打入关闭列表标记
this._openlist = this._binaryTreeNode.getOpenList();
this._closelist.push(this._currentNode);
callback.apply(target, [this._startNode, this._targetNode, this._currentNode, this._openlist, this._closelist, null]);
}
}, time);
}
/**
*查找一个节点周围可通过的点
* @param node
* @return
*
*/
private searchRoundNodes(node: RoadNode): void {
for (var i: number = 0; i < this._round.length; i++) {
var cx: number = node.cx + this._round[i][0];
var cy: number = node.cy + this._round[i][1];
var node2: RoadNode = this._roadNodes[cx + "_" + cy] as RoadNode
if (node2 != null && node2 != this._startNode && node2.value != 1 && !this.isInCloseList(node2) && !this.inInCorner(node2)) {
this.setNodeF(node2);
}
}
}
/**
*设置节点的F值
* @param node
*
*/
public setNodeF(node: RoadNode): void {
var g: number;
if (node.cx == this._currentNode.cx || node.cy == this._currentNode.cy) {
g = this._currentNode.g + this.COST_STRAIGHT;
}
else {
g = this._currentNode.g + this.COST_DIAGONAL;
}
if (this.isInOpenList(node)) {
if (g < node.g) {
node.g = g;
node.parent = this._currentNode;
node.h = (Math.abs(this._targetNode.cx - node.cx) + Math.abs(this._targetNode.cy - node.cy)) * this.COST_STRAIGHT;
node.f = node.g + node.h;
//节点的g值已经改变把节点先从二堆叉树结构中删除再重新添加进二堆叉树
this._binaryTreeNode.removeTreeNode(node);
this._binaryTreeNode.addTreeNode(node);
}
}
else {
node.g = g;
this._binaryTreeNode.setRoadNodeInOpenList(node);//给节点打入开放列表的标志
node.resetTree();
node.parent = this._currentNode;
node.h = (Math.abs(this._targetNode.cx - node.cx) + Math.abs(this._targetNode.cy - node.cy)) * this.COST_STRAIGHT;
node.f = node.g + node.h;
this._binaryTreeNode.addTreeNode(node);
}
}
/**
*节点是否在开启列表
* @param node
* @return
*/
private isInOpenList(node: RoadNode): Boolean {
return this._binaryTreeNode.isInOpenList(node);
}
/**
* 节点是否在关闭列表
* @param node
* @returns
*/
private isInCloseList(node: RoadNode): Boolean {
return this._binaryTreeNode.isInCloseList(node);
}
/**
*节点是否在拐角处
* @return
*
*/
private inInCorner(node: RoadNode): Boolean {
if (node.cx == this._currentNode.cx || node.cy == this._currentNode.cy) {
return false;
}
var node1: RoadNode = this._roadNodes[this._currentNode.cx + "_" + node.cy] as RoadNode;
var node2: RoadNode = this._roadNodes[node.cx + "_" + this._currentNode.cy] as RoadNode;
if (this.isPassNode(node1) && this.isPassNode(node2)) {
return false;
}
return true;
}
public dispose(): void {
this._roadNodes = null;
this._round = null;
}
}

View File

@@ -1,11 +0,0 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "a3a19dc4-7645-485a-80e0-b49fdb062b00",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -1,836 +0,0 @@
import BinaryTreeNode from "./BinaryTreeNode";
import IRoadSeeker from "./IRoadSeeker";
import RoadNode from "./RoadNode";
/**
* 六边形 A*寻路算法
* @author 落日故人 QQ 583051842
*
*/
export default class AstarHoneycombRoadSeeker implements IRoadSeeker {
/**
* 横向移动一个格子的代价
*/
private COST_STRAIGHT: number = 10;
/**
* 斜向移动一个格子的代价
*/
private COST_DIAGONAL: number = 10;
/**
* 最大搜寻步骤数,超过这个值时表示找不到目标
*/
private maxStep: number = 15000;
/**
* 开启列表
*/
private _openlist: Array<RoadNode>;
/**
*关闭列表
*/
private _closelist: Array<RoadNode>;
/**
* 二叉堆存储结构
*/
private _binaryTreeNode: BinaryTreeNode = new BinaryTreeNode();
/**
*开始节点
*/
private _startNode: RoadNode;
/**
*当前检索节点
*/
private _currentNode: RoadNode;
/**
*目标节点
*/
private _targetNode: RoadNode;
/**
*地图路点数据
*/
private _roadNodes: { [key: number]: RoadNode };
/**
*用于检索一个节点周围6个点的向量数组 格子列数为偶数时使用
*/
private _round1: number[][] = [[0, -1], [1, -1], [1, 0], [0, 1], [-1, 0], [-1, -1]];
/**
*用于检索一个节点周围6个点的向量数组 格子列数为奇数时使用
*/
private _round2: number[][] = [[0, -1], [1, 0], [1, 1], [0, 1], [-1, 1], [-1, 0]];
private handle: number = -1;
/**
* 是否优化路径
*/
private optimize: boolean = true;
public constructor(roadNodes: { [key: string]: RoadNode }) {
this._roadNodes = roadNodes;
}
/**
*寻路入口方法
* @param startNode
* @param targetNode
* @return
*
*/
public seekPath(startNode: RoadNode, targetNode: RoadNode): Array<RoadNode> {
this._startNode = startNode;
this._currentNode = startNode;
this._targetNode = targetNode;
if (!this._startNode || !this._targetNode)
return [];
if (this._targetNode.value == 1) {
console.log("目标不可达到:");
return [];
}
this._startNode.g = 0; //重置起始节点的g值
this._startNode.resetTree(); //清除起始节点原有的二叉堆关联关系
this._binaryTreeNode.refleshTag(); //刷新二叉堆tag用于后面判断是不是属于当前次的寻路
//this._binaryTreeNode.addTreeNode(this._startNode); //把起始节点设置为二叉堆结构的根节点
var step: number = 0;
while (true) {
if (step > this.maxStep) {
console.log("没找到目标计算步骤为:", step);
return [];
}
step++;
this.searchRoundNodes(this._currentNode);
if (this._binaryTreeNode.isTreeNull()) //二叉堆树里已经没有任何可搜寻的点了,则寻路结束,每找到目标
{
console.log("没找到目标计算步骤为:", step);
return [];
}
this._currentNode = this._binaryTreeNode.getMin_F_Node();
if (this._currentNode == this._targetNode) {
console.log("找到目标计算步骤为:", step);
return this.getPath();
}
else {
this._binaryTreeNode.setRoadNodeInCloseList(this._currentNode);//打入关闭列表标记
}
}
return [];
}
/**
*寻路入口方法 如果没有寻到目标,则返回离目标最近的路径
* @param startNode
* @param targetNode
* @return
*
*/
public seekPath2(startNode: RoadNode, targetNode: RoadNode): Array<RoadNode> {
this._startNode = startNode;
this._currentNode = startNode;
this._targetNode = targetNode;
if (!this._startNode || !this._targetNode)
return [];
var newMaxStep: number = this.maxStep;
if (!this.isPassNode(this._targetNode)) {
//如果不能直达目标,最大寻路步骤 = 为两点间的预估距离的2倍
newMaxStep = (Math.abs(this._targetNode.cx - this._startNode.cx) + Math.abs(this._targetNode.cy - this._startNode.cy)) * 2;
if (newMaxStep > this.maxStep) {
newMaxStep = this.maxStep;
}
}
this._startNode.g = 0; //重置起始节点的g值
this._startNode.resetTree(); //清除起始节点原有的二叉堆关联关系
this._binaryTreeNode.refleshTag(); //刷新二叉堆tag用于后面判断是不是属于当前次的寻路
//this._binaryTreeNode.addTreeNode(this._startNode); //把起始节点设置为二叉堆结构的根节点
var step: number = 0;
var closestNode: RoadNode = null; //距离目标最近的路点
while (true) {
if (step > newMaxStep) {
console.log("没找到目标计算步骤为:", step);
return this.seekPath(startNode, closestNode);
}
step++;
this.searchRoundNodes(this._currentNode);
if (this._binaryTreeNode.isTreeNull()) { //二叉堆树里已经没有任何可搜寻的点了,则寻路结束,没找到目标
console.log("没找到目标计算步骤为:", step);
return this.seekPath(startNode, closestNode);
}
this._currentNode = this._binaryTreeNode.getMin_F_Node();
if (closestNode == null) {
closestNode = this._currentNode;
}
else {
if (this._currentNode.h < closestNode.h) {
closestNode = this._currentNode;
}
}
if (this._currentNode == this._targetNode) {
console.log("找到目标计算步骤为:", step);
return this.getPath();
}
else {
this._binaryTreeNode.setRoadNodeInCloseList(this._currentNode);//打入关闭列表标记
}
}
return this.seekPath(startNode, closestNode);
}
/**
* 对路节点进行排序
* @param node1
* @param node2
*/
private sortNode(node1: RoadNode, node2: RoadNode) {
if (node1.f < node2.f) {
return -1;
}
else if (node1.f > node2.f) {
return 1;
}
return 0;
}
/*private getPath():Array<RoadNode>
{
var nodeArr:Array<RoadNode> = [];
var node:RoadNode = this._targetNode;
while(node != this._startNode)
{
nodeArr.unshift(node);
node = node.parent;
}
nodeArr.unshift(this._startNode);
if(!this.optimize)
{
return nodeArr;
}
//把多个节点连在一起的,横向或者斜向的一连串点,除两边的点保留
var preNode:RoadNode;
var midNode:RoadNode;
var nextNode:RoadNode;
for(var i:number = 1 ; i < nodeArr.length - 1 ; i++)
{
preNode = nodeArr[i - 1] as RoadNode;
midNode = nodeArr[i] as RoadNode;
nextNode = nodeArr[i + 1] as RoadNode;
var bool:Boolean = false;
var otherNode:RoadNode = null;
if(Math.abs(nextNode.cx - preNode.cx) == 2 && preNode.cy == nextNode.cy)
{
if(midNode.cx % 2 == 0)
{
if(midNode.cy == preNode.cy)
{
otherNode = this._roadNodes[midNode.cx + "_" + (midNode.cy + 1)] as RoadNode
}else
{
otherNode = this._roadNodes[midNode.cx + "_" + (midNode.cy - 1)] as RoadNode
}
}else
{
if(midNode.cy == preNode.cy)
{
otherNode = this._roadNodes[midNode.cx + "_" + (midNode.cy - 1)] as RoadNode
}else
{
otherNode = this._roadNodes[midNode.cx + "_" + (midNode.cy + 1)] as RoadNode
}
}
}
if(otherNode)
bool = otherNode.value != 1 ? true : false;
if(bool)
{
nodeArr.splice(i,1)
i--;
}
}
for(i = 1 ; i < nodeArr.length - 1 ; i++)
{
preNode = nodeArr[i - 1] as RoadNode;
midNode = nodeArr[i] as RoadNode;
nextNode = nodeArr[i + 1] as RoadNode;
var bool1:Boolean = midNode.cx == preNode.cx && midNode.cx == nextNode.cx;
var bool2:Boolean = (midNode.cy == preNode.cy && midNode.cy == nextNode.cy) && ((preNode.cx % 2 == midNode.cx % 2 && midNode.cx % 2 == nextNode.cx % 2) );
var bool3:Boolean = preNode.cy - Math.floor(preNode.cx / 2) == midNode.cy - Math.floor(midNode.cx / 2) && midNode.cy - Math.floor(midNode.cx / 2) == nextNode.cy - Math.floor(nextNode.cx / 2);
var bool4:Boolean = preNode.cy + Math.ceil(preNode.cx / 2) == midNode.cy + Math.ceil(midNode.cx / 2) && midNode.cy + Math.ceil(midNode.cx / 2) == nextNode.cy + Math.ceil(nextNode.cx / 2);
if(bool1 || bool2 || bool3 || bool4)
{
nodeArr.splice(i,1)
i--;
}
}
return nodeArr
}*/
/**
*获得最终寻路到的所有路点
* @return
*
*/
private getPath(): Array<RoadNode> {
var nodeArr: Array<RoadNode> = [];
var node: RoadNode = this._targetNode;
while (node != this._startNode) {
nodeArr.unshift(node);
node = node.parent;
}
nodeArr.unshift(this._startNode);
if (!this.optimize) {
return nodeArr;
}
//把多个节点连在一起的,横向或者斜向的一连串点,除两边的点保留
var preNode: RoadNode;
var midNode: RoadNode;
var nextNode: RoadNode;
var preHpos: HoneyPoint;
var midHpos: HoneyPoint;
var nextHpos: HoneyPoint;
//var hround:number[][] = [[-1,-1],[-1,0],[0,1],[1,1],[1,0],[0,-1]];
//var hround2:number[][] = [[-2,-1],[-1,1],[1,2],[2,1],[1,-1],[-1,-2]];
//第一阶段优化: 对横,竖,正斜进行优化
for (i = 1; i < nodeArr.length - 1; i++) {
preNode = nodeArr[i - 1] as RoadNode;
midNode = nodeArr[i] as RoadNode;
nextNode = nodeArr[i + 1] as RoadNode;
preHpos = this.getHoneyPoint(preNode);
midHpos = this.getHoneyPoint(midNode);
nextHpos = this.getHoneyPoint(nextNode);
var bool1: Boolean = midNode.cx == preNode.cx && midNode.cx == nextNode.cx;
var bool2: Boolean = (midNode.cy == preNode.cy && midNode.cy == nextNode.cy) && ((preNode.cx % 2 == midNode.cx % 2 && midNode.cx % 2 == nextNode.cx % 2));
var bool3: Boolean = preHpos.hx == midHpos.hx && midHpos.hx == nextHpos.hx;
var bool4: Boolean = preHpos.hy == midHpos.hy && midHpos.hy == nextHpos.hy;
if (bool1 || bool2 || bool3 || bool4) {
nodeArr.splice(i, 1)
i--;
}
}
//第二阶段优化:对不在横,竖,正斜的格子进行优化
for (var i: number = 0; i < nodeArr.length - 2; i++) {
var startNode: RoadNode = nodeArr[i] as RoadNode;
var optimizeNode: RoadNode = null;
//优先从尾部对比,如果能直达就把中间多余的路点删掉
for (var j: number = nodeArr.length - 1; j > i + 1; j--) {
var targetNode: RoadNode = nodeArr[j] as RoadNode;
if (this.isArriveBetweenTwoNodes(this.getHoneyPoint(startNode), this.getHoneyPoint(targetNode))) {
optimizeNode = targetNode;
break;
}
}
if (optimizeNode) {
var optimizeLen: number = j - i - 1;
nodeArr.splice(i + 1, optimizeLen);
}
}
return nodeArr
}
/**
* 两点之间是否可到达
*/
private isArriveBetweenTwoNodes(startPoint: HoneyPoint, targetPoint: HoneyPoint): boolean {
if (startPoint.hx == targetPoint.hx && startPoint.hy == targetPoint.hy) {
return false;
}
var disX: number = Math.abs(targetPoint.hx - startPoint.hx);
var disY: number = Math.abs(targetPoint.hy - startPoint.hy);
var dirX = 0;
if (targetPoint.hx > startPoint.hx) {
dirX = 1;
}
else if (targetPoint.hx < startPoint.hx) {
dirX = -1;
}
var dirY = 0;
if (targetPoint.hy > startPoint.hy) {
dirY = 1;
}
else if (targetPoint.hy < startPoint.hy) {
dirY = -1;
}
var rx: number = 0;
var ry: number = 0;
var intNum: number = 0;
var decimal: number = 0;
if (disX > disY) {
var rate: number = disY / disX;
for (var i = 0; i < disX; i += 2) {
ry = i * dirY * rate;
intNum = dirY > 0 ? Math.floor(startPoint.hy + ry) : Math.ceil(startPoint.hy + ry);
decimal = Math.abs(ry % 1);
var hpoint1: HoneyPoint = new HoneyPoint();
hpoint1.hx = startPoint.hx + i * dirX;
hpoint1.hy = decimal <= 0.5 ? intNum : intNum + 1 * dirY;
//cc.log(i + " :: " ,hpoint1.hx, hpoint1.hy," yy ",startPoint.hy + i * dirY * rate,ry % 1,rate,intNum,decimal,dirY,ry);
ry = (i + 1) * dirY * rate;
intNum = dirY > 0 ? Math.floor(startPoint.hy + ry) : Math.ceil(startPoint.hy + ry);
decimal = Math.abs(ry % 1);
var hpoint2: HoneyPoint = new HoneyPoint();
hpoint2.hx = startPoint.hx + (i + 1) * dirX;
hpoint2.hy = decimal <= 0.5 ? intNum : intNum + 1 * dirY;
ry = (i + 2) * dirY * rate;
intNum = dirY > 0 ? Math.floor(startPoint.hy + ry) : Math.ceil(startPoint.hy + ry);
decimal = Math.abs(ry % 1);
var hpoint3: HoneyPoint = new HoneyPoint();
hpoint3.hx = startPoint.hx + (i + 2) * dirX;
hpoint3.hy = decimal <= 0.5 ? intNum : intNum + 1 * dirY;
if (!this.isCrossAtAdjacentNodes(startPoint, targetPoint, hpoint1, hpoint2, hpoint3)) {
return false;
}
}
}
else {
var rate: number = disX / disY;
for (var i = 0; i < disY; i += 2) {
rx = i * dirX * rate;
intNum = dirX > 0 ? Math.floor(startPoint.hx + rx) : Math.ceil(startPoint.hx + rx);
decimal = Math.abs(rx % 1);
var hpoint1: HoneyPoint = new HoneyPoint();
hpoint1.hx = decimal <= 0.5 ? intNum : intNum + 1 * dirX;
hpoint1.hy = startPoint.hy + i * dirY;
rx = (i + 1) * dirX * rate;
intNum = dirX > 0 ? Math.floor(startPoint.hx + rx) : Math.ceil(startPoint.hx + rx);
decimal = Math.abs(rx % 1);
var hpoint2: HoneyPoint = new HoneyPoint();
hpoint2.hx = decimal <= 0.5 ? intNum : intNum + 1 * dirX;
hpoint2.hy = startPoint.hy + (i + 1) * dirY;
rx = (i + 2) * dirX * rate;
intNum = dirX > 0 ? Math.floor(startPoint.hx + rx) : Math.ceil(startPoint.hx + rx);
decimal = Math.abs(rx % 1);
var hpoint3: HoneyPoint = new HoneyPoint();
hpoint3.hx = decimal <= 0.5 ? intNum : intNum + 1 * dirX;
hpoint3.hy = startPoint.hy + (i + 2) * dirY;
if (!this.isCrossAtAdjacentNodes(startPoint, targetPoint, hpoint1, hpoint2, hpoint3)) {
return false;
}
}
}
return true;
}
/**
* 判断三个相邻的点是否可通过
* @param node1
* @param node2
*/
private isCrossAtAdjacentNodes(startPoint: HoneyPoint, targetPoint: HoneyPoint, hpoint1: HoneyPoint, hpoint2: HoneyPoint, hpoint3: HoneyPoint): boolean {
var node1: RoadNode = this.getNodeByHoneyPoint(hpoint1.hx, hpoint1.hy);
var node2: RoadNode = this.getNodeByHoneyPoint(hpoint2.hx, hpoint2.hy);
var node3: RoadNode = this.getNodeByHoneyPoint(hpoint3.hx, hpoint3.hy); // 节点3主要用做路径方向的判断
if (node1 == node2) {
return false;
}
//前两个点只要有一个点不能通过就不能通过节点3只做方向向导不用考虑是否可通过和是否存在
if (!this.isPassNode(node1) || !this.isPassNode(node2)) {
return false;
}
var dirX1: number = hpoint1.hx - hpoint2.hx;
var dirY1: number = hpoint1.hy - hpoint2.hy;
var dirX2: number = hpoint3.hx - hpoint2.hx;
var dirY2: number = hpoint3.hy - hpoint2.hy;
//hround:number[][] = [[-1,-1],[-1,0],[0,1],[1,1],[1,0],[0,-1]]; //相邻点向量
//[-1,1] [1,-1] //特殊相邻点向量
//如果不是相邻的两个点 则不能通过
if ((Math.abs(dirX1) > 1 || Math.abs(dirY1) > 1) || (Math.abs(dirX2) > 1 || Math.abs(dirY2) > 1)) {
return false;
}
//特殊相邻点 特殊对待
if (dirX1 == -dirY1) { //如果第一个点和第二个点是特殊相邻点
if (dirX1 == -1) {
if (!this.isPassNode(this.getNodeByHoneyPoint(hpoint2.hx - 1, hpoint2.hy)) || !this.isPassNode(this.getNodeByHoneyPoint(hpoint2.hx, hpoint2.hy + 1))) {
return false;
}
}
else {
if (!this.isPassNode(this.getNodeByHoneyPoint(hpoint2.hx + 1, hpoint2.hy)) || !this.isPassNode(this.getNodeByHoneyPoint(hpoint2.hx, hpoint2.hy - 1))) {
return false;
}
}
}
//第一个点和第二个点已经可通过,如果第二个点是终点,那么可直达
if (hpoint2.hx == targetPoint.hx && hpoint2.hy == targetPoint.hy) {
return true;
}
//特殊相邻点 特殊对待
if (dirX2 == -dirY2) { //如果第二个点和第三个点是特殊相邻点
if (dirX2 == -1) {
if (!this.isPassNode(this.getNodeByHoneyPoint(hpoint2.hx - 1, hpoint2.hy)) || !this.isPassNode(this.getNodeByHoneyPoint(hpoint2.hx, hpoint2.hy + 1))) {
return false;
}
}
else {
if (!this.isPassNode(this.getNodeByHoneyPoint(hpoint2.hx + 1, hpoint2.hy)) || !this.isPassNode(this.getNodeByHoneyPoint(hpoint2.hx, hpoint2.hy - 1))) {
return false;
}
}
}
//如果相邻的点和目标点在同一直线
if (hpoint1.hx == hpoint2.hx && hpoint2.hx == hpoint3.hx) {
return true;
}
//var hround2:number[][] = [[-2,-1],[-1,1],[1,2],[2,1],[1,-1],[-1,-2]];
if (this.isPassNode(this.getNodeByHoneyPoint(hpoint2.hx + (dirX1 + dirX2), hpoint2.hy + (dirY1 + dirY2)))) {
return true;
}
return false;
}
/**
* 获得六边形格子坐标(以正斜角和反斜角为标准的坐标)
* @param node
*/
public getHoneyPoint(node: RoadNode): HoneyPoint {
var hx: number = node.cy + Math.ceil(node.cx / 2); //设置反斜角为x坐标
var hy: number = node.cy - Math.floor(node.cx / 2); //设置正斜角为y坐标
return new HoneyPoint(hx, hy);
}
public getNodeByHoneyPoint(hx: number, hy: number): RoadNode {
var cx: number = hx - hy; //研究出来的
var cy: number = Math.floor((hx - hy) / 2) + hy; //研究出来的
return this._roadNodes[cx + "_" + cy] as RoadNode;
}
/**
* 获得一个点周围指定方向相邻的一个点
* @param node 制定的点
* @param roundIndex 0是下然后顺时针5右下
*/
public getRoundNodeByIndex(node: RoadNode, roundIndex: number): RoadNode {
if (!node) {
return null;
}
roundIndex = roundIndex % 6;
var round: number[][];
node.cx % 2 == 0 ? round = this._round1 : round = this._round2;
var cx: number = node.cx + round[roundIndex][0];
var cy: number = node.cy + round[roundIndex][1];
return this._roadNodes[cx + "_" + cy] as RoadNode;
}
/**
* 获得一个点周围所有的相邻点
* @param node
*/
public getRoundNodes(node: RoadNode): RoadNode[] {
var round: number[][];
node.cx % 2 == 0 ? round = this._round1 : round = this._round2;
var nodeArr: RoadNode[] = [];
for (var i: number = 0; i < round.length; i++) {
var cx: number = node.cx + round[i][0];
var cy: number = node.cy + round[i][1];
var node2: RoadNode = this._roadNodes[cx + "_" + cy] as RoadNode;
nodeArr.push(node2);
}
return nodeArr;
}
/**
* 是否是可通过的点
* @param node
*/
private isPassNode(node: RoadNode): boolean {
if (!node || node.value == 1) {
return false;
}
return true;
}
/**
*测试寻路步骤
* @param startNode
* @param targetNode
* @return
*
*/
public testSeekPathStep(startNode: RoadNode, targetNode: RoadNode, callback: Function, target: any, time: number = 100): void {
this._startNode = startNode;
this._currentNode = startNode;
this._targetNode = targetNode;
if (this._targetNode.value == 1)
return;
this._startNode.g = 0; //重置起始节点的g值
this._startNode.resetTree(); //清除起始节点原有的二叉堆关联关系
this._binaryTreeNode.refleshTag(); //刷新二叉堆tag用于后面判断是不是属于当前次的寻路
//this._binaryTreeNode.addTreeNode(this._startNode); //把起始节点设置为二叉堆结构的根节点
this._closelist = [];
var step: number = 0;
clearInterval(this.handle);
this.handle = setInterval(() => {
if (step > this.maxStep) {
console.log("没找到目标计算步骤为:", step);
clearInterval(this.handle);
return;
}
step++;
this.searchRoundNodes(this._currentNode);
if (this._binaryTreeNode.isTreeNull()) //二叉堆树里已经没有任何可搜寻的点了,则寻路结束,每找到目标
{
console.log("没找到目标计算步骤为:", step);
clearInterval(this.handle);
return;
}
this._currentNode = this._binaryTreeNode.getMin_F_Node();
if (this._currentNode == this._targetNode) {
console.log("找到目标计算步骤为:", step);
clearInterval(this.handle);
this._openlist = this._binaryTreeNode.getOpenList();
callback.apply(target, [this._startNode, this._targetNode, this._currentNode, this._openlist, this._closelist, this.getPath()]);
} else {
this._binaryTreeNode.setRoadNodeInCloseList(this._currentNode);//打入关闭列表标记
this._openlist = this._binaryTreeNode.getOpenList();
this._closelist.push(this._currentNode);
callback.apply(target, [this._startNode, this._targetNode, this._currentNode, this._openlist, this._closelist, null]);
}
}, time);
}
/**
*查找一个节点周围可通过的点
* @param node
* @return
*
*/
private searchRoundNodes(node: RoadNode): void {
var round: number[][];
node.cx % 2 == 0 ? round = this._round1 : round = this._round2;
for (var i: number = 0; i < round.length; i++) {
var cx: number = node.cx + round[i][0];
var cy: number = node.cy + round[i][1];
var node2: RoadNode = this._roadNodes[cx + "_" + cy] as RoadNode;
if (node2 != null && node2 != this._startNode && node2.value != 1 && !this.isInCloseList(node2)) {
this.setNodeF(node2);
}
}
}
/**
*设置节点的F值
* @param node
*
*/
public setNodeF(node: RoadNode): void {
var g: number;
if (node.cx == this._currentNode.cx || node.cy == this._currentNode.cy) {
g = this._currentNode.g + this.COST_STRAIGHT;
} else {
g = this._currentNode.g + this.COST_DIAGONAL;
}
if (this.isInOpenList(node)) {
if (g < node.g) {
node.g = g;
node.parent = this._currentNode;
node.h = (Math.abs(this._targetNode.cx - node.cx) + Math.abs(this._targetNode.cy - node.cy)) * this.COST_STRAIGHT;
node.f = node.g + node.h;
//节点的g值已经改变把节点先从二堆叉树结构中删除再重新添加进二堆叉树
this._binaryTreeNode.removeTreeNode(node);
this._binaryTreeNode.addTreeNode(node);
}
} else {
node.g = g;
this._binaryTreeNode.setRoadNodeInOpenList(node);//给节点打入开放列表的标志
node.resetTree();
node.parent = this._currentNode;
node.h = (Math.abs(this._targetNode.cx - node.cx) + Math.abs(this._targetNode.cy - node.cy)) * this.COST_STRAIGHT;
node.f = node.g + node.h;
this._binaryTreeNode.addTreeNode(node);
}
}
/**
*节点是否在开启列表
* @param node
* @return
*
*/
private isInOpenList(node: RoadNode): Boolean {
return this._binaryTreeNode.isInOpenList(node);
}
/**
* 节点是否在关闭列表
* @param node
* @returns
*/
private isInCloseList(node: RoadNode): Boolean {
return this._binaryTreeNode.isInCloseList(node);
}
public dispose(): void {
this._roadNodes = null;
this._round1 = null;
this._round2 = null;
}
}
/**
* 六边形格子坐标(以正斜角和反斜角为标准的坐标)
*/
class HoneyPoint {
public hx: number = 0;
public hy: number = 0;
constructor(x: number = 0, y: number = 0) {
this.hx = x;
this.hy = y;
}
}

View File

@@ -1,11 +0,0 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "470f8a32-bf7c-4747-bd7d-07042bbc389e",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -1,252 +0,0 @@
import RoadNode from "./RoadNode";
/**
* 二堆叉结构存储
*/
export default class BinaryTreeNode {
/**
* 当前寻路标记,用于标记节点是否属于当前次寻路运算
*/
public seekTag: number = 0;
/**
* 开启列表根节点
*/
public openNode: RoadNode = null;
/**
* 计数当次寻路的运算代价(用于测试数据)
*/
public count: number = 0;
/**
* 刷新寻路tag标记用于标记当前是哪次的寻路
*/
public refleshTag() {
this.openNode = null;
this.count = 0;
this.seekTag++;
if (this.seekTag > 1000000000) {
this.seekTag = 0;
}
}
/**
* 二叉堆树是否为空,即没有任何节点加入
* @returns
*/
public isTreeNull() {
return this.openNode == null;
}
/**
* 把节点添加进二叉堆里
* @param roadNode 要添加的节点
* @param head 从哪个节点位置开始添加
* @returns
*/
public addTreeNode(roadNode: RoadNode, head: RoadNode = null) {
this.count++; //计数统计运算代价
if (head == null) {
if (this.openNode == null) //如果开启节点为空,则拿首次加二叉堆的节点作为开启节点
{
this.openNode = roadNode;
//console.log(this.count,"add root ",roadNode.f,roadNode.toString());
return;
} else //如果开启节点存在头节点为null,默认把开启节点用于头节点
{
head = this.openNode;
}
}
if (roadNode.f >= head.f) {
if (head.right == null) {
head.right = roadNode;
roadNode.treeParent = head;
//console.log(this.count,"add right ",roadNode.f,roadNode.toString());
} else {
this.addTreeNode(roadNode, head.right);
}
} else {
if (head.left == null) {
head.left = roadNode;
roadNode.treeParent = head;
//console.log(this.count,"add left ",roadNode.f,roadNode.toString());
} else {
this.addTreeNode(roadNode, head.left);
}
}
}
/**
* 删除树节点
* @param roadNode 要删除的节点
*/
public removeTreeNode(roadNode: RoadNode) {
this.count++; //计数统计运算代价
if (roadNode.treeParent == null && roadNode.left == null && roadNode.right == null) //节点不在树结构中
{
return;
}
if (roadNode.treeParent == null) //如果是根节点,优先把左子节点转换成根节点,左子节点不存在,则把右子节点转换成根节点
{
if (roadNode.left) {
this.openNode = roadNode.left;
roadNode.left.treeParent = null;
if (roadNode.right) {
roadNode.right.treeParent = null;
this.addTreeNode(roadNode.right, this.openNode);
}
} else if (roadNode.right) //如果没有左节点,只有右节点
{
this.openNode = roadNode.right;
roadNode.right.treeParent = null;
}
} else {
if (roadNode.treeParent.left == roadNode) //如果是左子节点
{
if (roadNode.right) {
roadNode.treeParent.left = roadNode.right;
roadNode.right.treeParent = roadNode.treeParent;
if (roadNode.left) {
roadNode.left.treeParent = null;
this.addTreeNode(roadNode.left, roadNode.right)
}
} else {
roadNode.treeParent.left = roadNode.left;
if (roadNode.left) {
roadNode.left.treeParent = roadNode.treeParent;
}
}
} else if (roadNode.treeParent.right == roadNode) //如果是右子节点
{
if (roadNode.left) {
roadNode.treeParent.right = roadNode.left;
roadNode.left.treeParent = roadNode.treeParent;
if (roadNode.right) {
roadNode.right.treeParent = null;
this.addTreeNode(roadNode.right, roadNode.left)
}
} else {
roadNode.treeParent.right = roadNode.right;
if (roadNode.right) {
roadNode.right.treeParent = roadNode.treeParent;
}
}
}
}
roadNode.resetTree();
}
/**
* 从二叉堆结构里快速查找除f值最小的路节点
* @param head 搜索的起始节点
* @returns
*/
public getMin_F_Node(head: RoadNode = null): RoadNode {
this.count++; //计数统计运算代价
if (head == null) {
if (this.openNode == null) {
return null;
} else {
head = this.openNode; //如果头节点为null并且开启节点不为空则头节点默认使用开启节点
}
}
if (head.left == null) {
var minNode: RoadNode = head;
if (head.treeParent == null) {
this.openNode = head.right;
if (this.openNode) {
this.openNode.treeParent = null;
}
} else {
head.treeParent.left = head.right;
if (head.right) {
head.right.treeParent = head.treeParent;
}
}
return minNode;
} else {
return this.getMin_F_Node(head.left);
}
}
/**
* 把节点加入开启列表,即打入开启列表标志
* @param node
*/
public setRoadNodeInOpenList(node: RoadNode) {
node.openTag = this.seekTag; //给节点打入开放列表的标志
node.closeTag = 0; //关闭列表标志关闭
}
/**
* 把节点加入关闭列表,即打入关闭列表标志
* @param node
*/
public setRoadNodeInCloseList(node: RoadNode) {
node.openTag = 0; //开放列表标志关闭
node.closeTag = this.seekTag; //给节点打入关闭列表的标志
}
/**
* 节点是否在开启列表
* @param node
* @returns
*/
public isInOpenList(node: RoadNode): Boolean {
return node.openTag == this.seekTag;
}
/**
* 节点是否在关闭列表
* @param node
* @returns
*/
public isInCloseList(node: RoadNode): Boolean {
return node.closeTag == this.seekTag;
}
public getOpenList(): RoadNode[] {
var openList: RoadNode[] = []
this.seachTree(this.openNode, openList);
return openList;
}
private seachTree(head: RoadNode, openList: RoadNode[]) {
if (head == null) {
return;
}
openList.push(head);
if (head.left) {
this.seachTree(head.left, openList);
}
if (head.right) {
this.seachTree(head.right, openList);
}
}
}

View File

@@ -1,36 +0,0 @@
import RoadNode from "./RoadNode";
/**
* 寻路接口
* @author 落日故人 QQ 583051842
*
*/
export default interface IRoadSeeker {
/**
*寻路入口方法
* @param startNode
* @param targetNode
* @return
*
*/
seekPath(startNode: RoadNode, targetNode: RoadNode): Array<RoadNode>;
/**
*寻路入口方法 如果没有寻到目标,则返回离目标最近的路径
* @param startNode
* @param targetNode
* @return
*
*/
seekPath2(startNode: RoadNode, targetNode: RoadNode): Array<RoadNode>;
/**
*测试寻路步骤
* @param startNode
* @param targetNode
* @return
*
*/
testSeekPathStep(startNode: RoadNode, targetNode: RoadNode, callback: Function, target: any, time: number): void;
}

View File

@@ -1,11 +0,0 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "e4f3fe84-cffc-40ca-ac1a-e0d853f234d8",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -1,974 +0,0 @@
import { MapType } from "../base/MapType";
import Point from "./Point";
import RoadNode from "./RoadNode";
export default class MapRoadUtils {
private static _instance: MapRoadUtils;
public static get instance(): MapRoadUtils {
if (this._instance == null) {
this._instance = new MapRoadUtils();
}
return this._instance;
}
/**
* 地图宽度
*/
private _mapWidth: number;
/**
*地图高度
*/
private _mapHeight: number;
/**
*地图一共分成几行
*/
private _row: number;
/**
*地图一共分成几列
*/
private _col: number;
/**
*地图路点单元格宽
*/
private _nodeWidth: number;
/**
*地图路点单元格高
*/
private _nodeHeight: number;
/**
*地图路点单元宽的一半
*/
private _halfNodeWidth: number;
/**
*地图路点单元高的一半
*/
private _halfNodeHeight: number;
private _mapType: number;
private _mapRoad: IMapRoad;
public updateMapInfo(mapWidth: number, mapHeight: number, nodeWidth: number, nodeHeight: number, mapType: MapType): void {
this._mapWidth = mapWidth;
this._mapHeight = mapHeight;
this._nodeWidth = nodeWidth;
this._nodeHeight = nodeHeight;
this._halfNodeWidth = Math.floor(this._nodeWidth / 2);
this._halfNodeHeight = Math.floor(this._nodeHeight / 2);
this._mapType = mapType;
switch (this._mapType) {
case MapType.angle45:
this._col = Math.ceil(mapWidth / this._nodeWidth);
this._row = Math.ceil(mapHeight / this._nodeHeight) * 2;
this._mapRoad = new MapRoad45Angle(this._row, this._col, this._nodeWidth, this._nodeHeight, this._halfNodeWidth, this._halfNodeHeight); break;
case MapType.angle90:
this._col = Math.ceil(mapWidth / this._nodeWidth);
this._row = Math.ceil(mapHeight / this._nodeHeight);
this._mapRoad = new MapRoad90Angle(this._row, this._col, this._nodeWidth, this._nodeHeight, this._halfNodeWidth, this._halfNodeHeight); break;
case MapType.honeycomb:
//this._nodeHeight = (this._nodeWidth / 2) * 1.732;
this._col = Math.ceil((this._mapWidth - this._nodeWidth / 4) / (this._nodeWidth / 4 * 6)) * 2;
this._row = Math.ceil((this._mapHeight - this._nodeHeight / 2) / this._nodeHeight);
this._mapRoad = new MapRoadHoneycomb(this._row, this._col, this._nodeWidth, this._nodeHeight, this._halfNodeWidth, this._halfNodeHeight); break;
}
// console.log("c r", this._col, this._row);
}
/**
*根据地图平面像素坐标获得路节点
* @param x
* @param y
* @return
*
*/
public getNodeByPixel(x: number, y: number): RoadNode {
if (this._mapRoad) {
return this._mapRoad.getNodeByPixel(x, y);
}
return new RoadNode();
}
/**
*根据路点平面坐标点获得路节点
* @param px
* @param py
* @return
*
*/
public getNodeByDerect(dx: number, dy: number): RoadNode {
if (this._mapRoad) {
return this._mapRoad.getNodeByDerect(dx, dy);
}
return new RoadNode();
}
/**
*根据路点场景世界坐标获得路节点
* @param wx
* @param wy
* @return
*
*/
public getNodeByWorldPoint(wx: number, wy: number): RoadNode {
if (this._mapRoad) {
return this._mapRoad.getNodeByWorldPoint(wx, wy);
}
return new RoadNode();
}
/**
*根据像素坐标得到场景世界坐标
* @param x
* @param y
* @return
*
*/
public getWorldPointByPixel(x: number, y: number): Point {
if (this._mapRoad) {
return this._mapRoad.getWorldPointByPixel(x, y);
}
return new Point();
}
/**
*根据世界坐标获得像素坐标
* @param cx
* @param cy
* @return
*
*/
public getPixelByWorldPoint(cx: number, cy: number): Point {
if (this._mapRoad) {
return this._mapRoad.getPixelByWorldPoint(cx, cy);
}
return new Point();
}
/**
*根据像素坐标获得网格平面坐标
* @param x
* @param y
* @return
*
*/
public getDerectByPixel(x: number, y: number): Point {
if (this._mapRoad) {
return this._mapRoad.getDerectByPixel(x, y);
}
return new Point();
}
/**
*根据世界坐标获得网格平面坐标
* @param cx
* @param cy
* @return
*
*/
public getDerectByWorldPoint(cx: number, cy: number): Point {
if (this._mapRoad) {
return this._mapRoad.getDerectByWorldPoint(cx, cy);
}
return new Point();
}
/**
*根据网格平面坐标获得世界坐标
* @param dx
* @param dy
* @return
*
*/
/* public getWorldPointByDerect(dx:number,dy:number):Point
{
var cx:number = (dy + dx) / 2;
var cy:number = (dy - dx) / 2 + col - 1;
return new Point(cx,cy);
}*/
public getPixelByDerect(dx: number, dy: number): Point {
if (this._mapRoad) {
return this._mapRoad.getPixelByDerect(dx, dy);
}
return new Point();
}
public get mapWidth(): number {
return this._mapWidth;
}
public get mapHeight(): number {
return this._mapHeight;
}
public get nodeWidth(): number {
return this._nodeWidth;
}
public get nodeHeight(): number {
return this._nodeHeight;
}
public get row(): number {
return this._row;
}
public get col(): number {
return this._col;
}
public get halfNodeWidth(): number {
return this._halfNodeWidth;
}
public get halfNodeHeight(): number {
return this._halfNodeHeight;
}
/**
*地图类型 0:斜45度等视角地图, 1:90度角平面地图
*/
public get mapType(): number {
return this._mapType;
}
}
/**
*地图路点处理接口
* @author Administrator
*
*/
interface IMapRoad {
/**
*根据地图平面像素坐标获得路节点
* @param x
* @param y
* @return
*
*/
getNodeByPixel(x: number, y: number): RoadNode;
/**
*根据路点平面坐标点获得路节点
* @param px
* @param py
* @return
*
*/
getNodeByDerect(dx: number, dy: number): RoadNode;
/**
*根据路点场景世界坐标获得路节点
* @param wx
* @param wy
* @return
*
*/
getNodeByWorldPoint(wx: number, wy: number): RoadNode;
/**
*根据像素坐标得到场景世界坐标
* @param x
* @param y
* @return
*
*/
getWorldPointByPixel(x: number, y: number): Point;
/**
*根据世界坐标获得像素坐标
* @param cx
* @param cy
* @return
*
*/
getPixelByWorldPoint(cx: number, cy: number): Point;
/**
*根据像素坐标获得网格平面坐标
* @param x
* @param y
* @return
*
*/
getDerectByPixel(x: number, y: number): Point;
/**
*根据世界坐标获得网格平面坐标
* @param cx
* @param cy
* @return
*
*/
getDerectByWorldPoint(cx: number, cy: number): Point;
/**
*根据网格平面坐标获得像素坐标
* @param dx
* @param dy
* @return
*
*/
getPixelByDerect(dx: number, dy: number): Point;
}
/**
*45度等视角地图路点处理接口实现
* @author Administrator
*
*/
class MapRoad45Angle implements IMapRoad {
/**
*地图一共分成几行
*/
private _row: number;
/**
*地图一共分成几列
*/
private _col: number;
/**
*地图路点单元格宽
*/
private _nodeWidth: number;
/**
*地图路点单元格高
*/
private _nodeHeight: number;
/**
*地图路点单元宽的一半
*/
private _halfNodeWidth: number;
/**
*地图路点单元高的一半
*/
private _halfNodeHeight: number;
public constructor(row: number, col: number, nodeWidth: number, nodeHeight: number, halfNodeWidth: number, halfNodeHeight: number) {
this._row = row;
this._col = col;
this._nodeWidth = nodeWidth;
this._nodeHeight = nodeHeight;
this._halfNodeWidth = halfNodeWidth;
this._halfNodeHeight = halfNodeHeight;
}
/**
*根据地图平面像素坐标获得路节点
* @param x
* @param y
* @return
*
*/
public getNodeByPixel(x: number, y: number): RoadNode {
var wPoint: Point = this.getWorldPointByPixel(x, y);
var fPoint: Point = this.getPixelByWorldPoint(wPoint.x, wPoint.y);
var dPoint: Point = this.getDerectByPixel(x, y);
var node: RoadNode = new RoadNode();
node.cx = wPoint.x;
node.cy = wPoint.y;
node.px = fPoint.x;
node.py = fPoint.y;
node.dx = dPoint.x;
node.dy = dPoint.y;
return node;
}
/**
*根据路点平面坐标点获得路节点
* @param px
* @param py
* @return
*
*/
public getNodeByDerect(dx: number, dy: number): RoadNode {
var fPoint: Point = this.getPixelByDerect(dx, dy);
var wPoint: Point = this.getWorldPointByPixel(fPoint.x, fPoint.y);
var node: RoadNode = new RoadNode();
node.cx = wPoint.x;
node.cy = wPoint.y;
node.px = fPoint.x;
node.py = fPoint.y;
node.dx = dx;
node.dy = dy;
return node;
}
/**
*根据路点场景世界坐标获得路节点
* @param wx
* @param wy
* @return
*
*/
public getNodeByWorldPoint(wx: number, wy: number): RoadNode {
var point: Point = this.getPixelByWorldPoint(wx, wy)
return this.getNodeByPixel(point.x, point.y);
}
/**
*根据像素坐标得到场景世界坐标
* @param x
* @param y
* @return
*
*/
public getWorldPointByPixel(x: number, y: number): Point {
var cx: number = Math.ceil(x / this._nodeWidth - 0.5 + y / this._nodeHeight) - 1;
var cy: number = (this._col - 1) - Math.ceil(x / this._nodeWidth - 0.5 - y / this._nodeHeight);
return new Point(cx, cy);
}
/**
*根据世界坐标获得像素坐标
* @param cx
* @param cy
* @return
*
*/
public getPixelByWorldPoint(cx: number, cy: number): Point {
var x: number = Math.floor((cx + 1 - (cy - (this._col - 1))) * this._halfNodeWidth);
var y: number = Math.floor((cx + 1 + (cy - (this._col - 1))) * this._halfNodeHeight);
return new Point(x, y);
}
/**
*根据像素坐标获得网格平面坐标
* @param x
* @param y
* @return
*
*/
public getDerectByPixel(x: number, y: number): Point {
var worldPoint: Point = this.getWorldPointByPixel(x, y);
var pixelPoint: Point = this.getPixelByWorldPoint(worldPoint.x, worldPoint.y);
var dx: number = Math.floor(pixelPoint.x / this._nodeWidth) - (pixelPoint.x % this._nodeWidth == 0 ? 1 : 0);
var dy: number = Math.floor(pixelPoint.y / this._halfNodeHeight) - 1;
return new Point(dx, dy);
}
/**
*根据世界坐标获得网格平面坐标
* @param cx
* @param cy
* @return
*
*/
public getDerectByWorldPoint(cx: number, cy: number): Point {
var dx: number = Math.floor((cx - (cy - (this._col - 1))) / 2);
var dy: number = cx + (cy - (this._col - 1));
return new Point(dx, dy);
}
/**
*根据网格平面坐标获得像素坐标
* @param dx
* @param dy
* @return
*
*/
public getPixelByDerect(dx: number, dy: number): Point {
var x: number = Math.floor((dx + dy % 2) * this._nodeWidth + (1 - dy % 2) * this._halfNodeWidth);
var y: number = Math.floor((dy + 1) * this._halfNodeHeight);
return new Point(x, y);
}
}
/**
*90度平面地图路点处理接口实现
* @author Administrator
*
*/
class MapRoad90Angle implements IMapRoad {
/**
*地图一共分成几行
*/
private _row: number;
/**
*地图一共分成几列
*/
private _col: number;
/**
*地图路点单元格宽
*/
private _nodeWidth: number;
/**
*地图路点单元格高
*/
private _nodeHeight: number;
/**
*地图路点单元宽的一半
*/
private _halfNodeWidth: number;
/**
*地图路点单元高的一半
*/
private _halfNodeHeight: number;
public constructor(row: number, col: number, nodeWidth: number, nodeHeight: number, halfNodeWidth: number, halfNodeHeight: number) {
this._row = row;
this._col = col;
this._nodeWidth = nodeWidth;
this._nodeHeight = nodeHeight;
this._halfNodeWidth = halfNodeWidth;
this._halfNodeHeight = halfNodeHeight;
}
/**
*根据地图平面像素坐标获得路节点
* @param x
* @param y
* @return
*
*/
public getNodeByPixel(x: number, y: number): RoadNode {
var wPoint: Point = this.getWorldPointByPixel(x, y);
var fPoint: Point = this.getPixelByWorldPoint(wPoint.x, wPoint.y);
var dPoint: Point = this.getDerectByPixel(x, y);
var node: RoadNode = new RoadNode();
node.cx = wPoint.x;
node.cy = wPoint.y;
node.px = fPoint.x;
node.py = fPoint.y;
node.dx = dPoint.x;
node.dy = dPoint.y;
return node;
}
/**
*根据路点平面坐标点获得路节点
* @param px
* @param py
* @return
*
*/
public getNodeByDerect(dx: number, dy: number): RoadNode {
var fPoint: Point = this.getPixelByDerect(dx, dy);
var wPoint: Point = this.getWorldPointByPixel(fPoint.x, fPoint.y);
var node: RoadNode = new RoadNode();
node.cx = wPoint.x;
node.cy = wPoint.y;
node.px = fPoint.x;
node.py = fPoint.y;
node.dx = dx;
node.dy = dy;
return node;
}
/**
*根据路点场景世界坐标获得路节点
* @param wx
* @param wy
* @return
*
*/
public getNodeByWorldPoint(wx: number, wy: number): RoadNode {
var point: Point = this.getPixelByWorldPoint(wx, wy)
return this.getNodeByPixel(point.x, point.y);
}
/**
*根据像素坐标得到场景世界坐标
* @param x
* @param y
* @return
*
*/
public getWorldPointByPixel(x: number, y: number): Point {
var cx: number = Math.floor(x / this._nodeWidth);
var cy: number = Math.floor(y / this._nodeHeight);
return new Point(cx, cy);
}
/**
*根据世界坐标获得像素坐标
* @param cx
* @param cy
* @return
*
*/
public getPixelByWorldPoint(cx: number, cy: number): Point {
var x: number = Math.floor((cx + 1) * this._nodeWidth - this._halfNodeWidth);
var y: number = Math.floor((cy + 1) * this._nodeHeight - this._halfNodeHeight);
return new Point(x, y);
}
/**
*根据像素坐标获得网格平面坐标
* @param x
* @param y
* @return
*
*/
public getDerectByPixel(x: number, y: number): Point {
var dx: number = Math.floor(x / this._nodeWidth);
var dy: number = Math.floor(y / this._nodeHeight);
return new Point(dx, dy);
}
/**
*根据世界坐标获得网格平面坐标 90度地图的世界坐标和网格坐标相同
* @param cx
* @param cy
* @return
*
*/
public getDerectByWorldPoint(cx: number, cy: number): Point {
return new Point(cx, cy);
}
/**
*根据网格平面坐标获得像素坐标
* @param dx
* @param dy
* @return
*
*/
public getPixelByDerect(dx: number, dy: number): Point {
var x: number = Math.floor((dx + 1) * this._nodeWidth - this._halfNodeWidth);
var y: number = Math.floor((dy + 1) * this._nodeHeight - this._halfNodeHeight);
return new Point(x, y);
}
}
/**
*蜂巢式(即正六边形)地图路点处理接口实现
* @author Administrator
*
*/
class MapRoadHoneycomb implements IMapRoad {
/**
*地图一共分成几行
*/
private _row: number;
/**
*地图一共分成几列
*/
private _col: number;
/**
*地图路点单元格宽
*/
private _nodeWidth: number;
/**
*地图路点单元格高
*/
private _nodeHeight: number;
/**
*地图路点单元宽的一半
*/
private _halfNodeWidth: number;
/**
*地图路点单元高的一半
*/
private _halfNodeHeight: number;
/**
* 六边形直径的4分之一
*/
private _nwDiv4: number;
/**
* 六边形直径的半径
*/
private _radius: number;
/**
* 六边形宽高的tan值正六边形为1.732
*/
private _proportion = 1.732;
/**
*蜂巢式(即正六边形)地图路点处理
* @param row
* @param col
* @param nodeWidth
* @param nodeHeight
* @param halfNodeWidth
* @param halfNodeHeight
*
*/
public constructor(row: number, col: number, nodeWidth: number, nodeHeight: number, halfNodeWidth: number, halfNodeHeight: number) {
this._row = row;
this._col = col;
this._nodeWidth = nodeWidth;
//this._nodeHeight = (this._nodeWidth / 2) * 1.732;
this._nodeHeight = nodeHeight;
this._halfNodeWidth = halfNodeWidth;
this._halfNodeHeight = halfNodeHeight;
this._nwDiv4 = this._nodeWidth / 4;
this._radius = this._nwDiv4 * 4;
this._proportion = this._nodeHeight * 2 / this._nodeWidth;
}
/**
*根据地图平面像素坐标获得路节点
* @param x
* @param y
* @return
*
*/
public getNodeByPixel(x: number, y: number): RoadNode {
var wPoint: Point = this.getWorldPointByPixel(x, y);
var fPoint: Point = this.getPixelByWorldPoint(wPoint.x, wPoint.y);
//var dPoint:Point = getDerectByPixel(x,y);
var node: RoadNode = new RoadNode();
node.cx = wPoint.x;
node.cy = wPoint.y;
node.px = fPoint.x;
node.py = fPoint.y;
node.dx = wPoint.x;
node.dy = wPoint.y;
return node;
}
/**
*根据路点平面坐标点获得路节点
* @param px
* @param py
* @return
*
*/
public getNodeByDerect(dx: number, dy: number): RoadNode {
var fPoint: Point = this.getPixelByDerect(dx, dy);
//var wPoint:Point = getWorldPointByPixel(fPoint.x,fPoint.y);
var node: RoadNode = new RoadNode();
node.cx = dx;
node.cy = dy;
node.px = fPoint.x;
node.py = fPoint.y;
node.dx = dx;
node.dy = dy;
return node;
}
/**
*根据路点场景世界坐标获得路节点
* @param wx
* @param wy
* @return
*
*/
public getNodeByWorldPoint(wx: number, wy: number): RoadNode {
var point: Point = this.getPixelByWorldPoint(wx, wy)
return this.getNodeByPixel(point.x, point.y);
}
/**
*根据像素坐标得到场景世界坐标
* @param x
* @param y
* @return
*
*/
public getWorldPointByPixel(x: number, y: number): Point {
var nwDiv4Index: number = Math.floor(x / this._nwDiv4); //六边形的外切矩形竖方向均等分成4分所有的六边形外切矩形连在一起形成一个个4分之一矩形宽的区域nwDiv4Index就是该区域的索引
var col: number = Math.floor(nwDiv4Index / 3); //取得临时六边形横轴的索引,根据不同的情况可能会变
var row: number; //六边形纵轴的索引
var cx: number;
var cy: number;
if ((nwDiv4Index - 1) % 6 == 0 || (nwDiv4Index - 2) % 6 == 0) {
row = Math.floor(y / this._nodeHeight);
cx = col;
cy = row;
}
else if ((nwDiv4Index - 4) % 6 == 0 || (nwDiv4Index - 5) % 6 == 0) {
if (y < this._nodeHeight / 2) {
row = -1;
} else {
row = Math.floor((y - this._nodeHeight / 2) / this._nodeHeight);
}
cx = col;
cy = row
}
else {
if (col % 2 == 0) {
//(x - 1,y - 1) (x - 1,y)
row = Math.floor(y / this._nodeHeight);
if (this.testPointInHoneycomb(col, row, x, y)) {
cx = col;
cy = row;
}
else if (this.testPointInHoneycomb(col - 1, row - 1, x, y)) {
cx = col - 1;
cy = row - 1;
}
else {
cx = col - 1;
cy = row;
}
}
else {
//(x - 1,y) (x - 1,y + 1)
if (y < this._nodeHeight / 2) {
row = -1;
} else {
row = Math.floor((y - this._nodeHeight / 2) / this._nodeHeight);
}
if (this.testPointInHoneycomb(col, row, x, y)) {
cx = col;
cy = row;
}
else if (this.testPointInHoneycomb(col - 1, row, x, y)) {
cx = col - 1;
cy = row;
}
else {
cx = col - 1;
cy = row + 1;
}
}
}
return new Point(cx, cy);
}
private testPointInHoneycomb(col: number, row: number, px: number, py: number): Boolean {
var a: number = this._nwDiv4 * 2;
var point: Point = this.getPixelByWorldPoint(col, row);
var absX: number = Math.abs(px - point.x);
var absY: number = Math.abs(py - point.y);
//return a-absX >= absY/(1.732);
return a - absX >= absY / this._proportion;
}
/**
*根据世界坐标获得像素坐标
* @param cx
* @param cy
* @return
*
*/
public getPixelByWorldPoint(cx: number, cy: number): Point {
var x: number = Math.floor((2 + 3 * cx) / 4 * this._nodeWidth);
var y: number = Math.floor((cy + 1 / 2 * (1 + (cx % 2))) * this._nodeHeight);
return new Point(x, y);
}
/**
*根据像素坐标获得网格平面坐标
* @param x
* @param y
* @return
*
*/
public getDerectByPixel(x: number, y: number): Point {
return this.getWorldPointByPixel(x, y);
}
/**
*根据世界坐标获得网格平面坐标 90度地图的世界坐标和网格坐标相同
* @param cx
* @param cy
* @return
*
*/
public getDerectByWorldPoint(cx: number, cy: number): Point {
return new Point(cx, cy);
}
/**
*根据网格平面坐标获得像素坐标
* @param dx
* @param dy
* @return
*
*/
public getPixelByDerect(dx: number, dy: number): Point {
var x: number = (2 + 3 * dx) / 4 * this._nodeWidth;
var y: number = (dy + 1 / 2 * (1 + (dx % 2))) * this._nodeHeight;
return new Point(x, y);
}
}

View File

@@ -1,11 +0,0 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "38983af0-c3cc-42a2-bd83-49e6b001f888",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -1,9 +0,0 @@
export default class Point {
public x: number = 0;
public y: number = 0;
public constructor(x: number = 0, y: number = 0) {
this.x = x;
this.y = y;
}
}

View File

@@ -1,11 +0,0 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "520e470b-8810-4f2d-8444-cd2446965b49",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -1,186 +0,0 @@
export default class RoadNode {
private _px: number;//像素坐标x轴
private _py: number;//像素坐标y轴
private _cx: number;//世界坐标x轴
private _cy: number;//世界坐标y轴
private _dx: number;//直角坐标x轴
private _dy: number;//直角坐标y轴
private _value: number = 0;//节点的值
private _f: number = 0; //路点的f值
private _g: number = 0; //路点的g值
private _h: number = 0; //路点的h值
private _parent: RoadNode = null; //路点的父节点
//-------------二堆叉存储结构-----------------
private _treeParent: RoadNode = null; //二堆叉结构的父节点
private _left: RoadNode = null; //二堆叉结构的左子节点
private _right: RoadNode = null; //二堆叉结构的右子节点
private _openTag: number = 0; //是否在开启列表标记
private _closeTag: number = 0; //是否在关闭列表标记
/**
* 重置二叉堆存储信息
*/
public resetTree() {
this._treeParent = null;
this._left = null;
this._right = null;
}
public toString(): String {
return "路点像素坐标:(" + this._px + "," + this._py + "), " +
"路点世界坐标:(" + this._cx + "," + this._cy + "), " +
"路点平面直角坐标:(" + this._dx + "," + this._dy + ")";
}
public get px(): number {
return this._px;
}
public set px(value: number) {
this._px = value;
}
public get py(): number {
return this._py;
}
public set py(value: number) {
this._py = value;
}
public get cx(): number {
return this._cx;
}
public set cx(value: number) {
this._cx = value;
}
public get cy(): number {
return this._cy;
}
public set cy(value: number) {
this._cy = value;
}
public get dx(): number {
return this._dx;
}
public set dx(value: number) {
this._dx = value;
}
public get dy(): number {
return this._dy;
}
public set dy(value: number) {
this._dy = value;
}
public get value(): number {
return this._value;
}
public set value(val: number) {
this._value = val;
}
public get f(): number {
return this._f;
}
public set f(value: number) {
this._f = value;
}
public get g(): number {
return this._g;
}
public set g(value: number) {
this._g = value;
}
public get h(): number {
return this._h;
}
public set h(value: number) {
this._h = value;
}
public get parent(): RoadNode {
return this._parent;
}
public set parent(value: RoadNode) {
this._parent = value;
}
//-------------二堆叉存储结构-----------------
/**
* 二堆叉结构的父节点
*/
public get treeParent(): RoadNode {
return this._treeParent;
}
public set treeParent(value: RoadNode) {
this._treeParent = value;
}
/**
* 二堆叉结构的左子节点
*/
public get left(): RoadNode {
return this._left;
}
public set left(value: RoadNode) {
this._left = value;
}
/**
* 二堆叉结构的右子节点
*/
public get right(): RoadNode {
return this._right;
}
public set right(value: RoadNode) {
this._right = value;
}
/**
* 是否在开启列表标记
*/
public get openTag(): number {
return this._openTag;
}
public set openTag(value: number) {
this._openTag = value;
}
/**
* 是否在关闭列表标记
*/
public get closeTag(): number {
return this._closeTag;
}
public set closeTag(value: number) {
this._closeTag = value;
}
}

View File

@@ -1,11 +0,0 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "a55696bb-2934-4388-a1af-182ab13401ef",
"files": [],
"subMetas": {},
"userData": {
"simulateGlobals": []
}
}

View File

@@ -1,18 +0,0 @@
/*
* @Author: dgflash
* @Date: 2021-08-09 16:43:23
* @LastEditTime: 2021-08-09 18:32:54
* @LastEditors: Please set LastEditors
* @Description: 地形类型
* @FilePath: \Game\assets\script\core\libs\map\road\RoadType.ts
*/
export enum RoadType {
/** 标准路 */
Road = 0,
/** 障碍物 */
Obstacle = 1,
/** 班透明路 */
RoadTransparent = 2,
/** 隐藏点 */
Hidden = 3
}

View File

@@ -76,7 +76,7 @@ export class MonsterViewComp extends CCComp {
onLoad() {
this.as = this.getComponent(MonsterSpine);
// PhysicsSystem2D.instance.debugDrawFlags = EPhysics2DDrawFlags.Aabb
PhysicsSystem2D.instance.debugDrawFlags = EPhysics2DDrawFlags.Aabb
// | EPhysics2DDrawFlags.Pair
// |EPhysics2DDrawFlags.CenterOfMass
// |EPhysics2DDrawFlags.Joint
@@ -106,10 +106,6 @@ export class MonsterViewComp extends CCComp {
}
onBeginContact (selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
}
onEndContact (selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
if(otherCollider.tag==BoxSet.SKILL_TAG &&selfCollider.tag!=BoxSet.SKILL_TAG){
if(selfCollider.group != otherCollider.group){
let skill = otherCollider.node.getComponent(SkillCom)!;
@@ -121,6 +117,10 @@ export class MonsterViewComp extends CCComp {
this.hp_change(skill.atk);
}
}
}
onEndContact (selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
}
onPreSolve (selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
if(selfCollider.group != otherCollider.group&&otherCollider.tag != BoxSet.ATK_RANGE){
@@ -220,7 +220,7 @@ export class MonsterViewComp extends CCComp {
let dis = SkillSet[skill_uuid].dis;
let atk = SkillSet[skill_uuid].atk+this.atk;
let sp_name = SkillSet[skill_uuid].sp_name;
skill.load(pos,speed,dis,scale,this.node,sp_name,0);
skill.load(pos,speed,dis,scale,this.node,sp_name,atk);
}
in_act(dt: number) {

View File

@@ -1,58 +0,0 @@
/*
* @Author: dgflash
* @Date: 2021-11-18 17:47:56
* @LastEditors: dgflash
* @LastEditTime: 2022-08-04 15:43:04
*/
import { instantiate, Node, Prefab, tween, Vec3,Label } from "cc";
import { UICallbacks } from "../../../../extensions/oops-plugin-framework/assets/core/gui/layer/Defines";
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { UIID } from "../common/config/GameUIConfig";
import { smc } from "../common/SingletonModuleComp";
import { HeroModelComp } from "./HeroModelComp";
import { HeroSpine } from "./HeroSpine";
import { HeroViewComp } from "./HeroViewComp";
/** 角色实体 */
@ecs.register(`Hero`)
export class Hero extends ecs.Entity {
// 数据层
HeroModel!: HeroModelComp;
// 视图层
HeroView!: HeroViewComp;
protected init() {
this.addComponents<ecs.Comp>(
HeroModelComp);
}
destroy(): void {
this.remove(HeroViewComp);
super.destroy();
}
/** 加载角色 */
load(pos: Vec3 = Vec3.ZERO,profession:string = "war") {
var path = "game/heros/"+profession;
var prefab: Prefab = oops.res.get(path, Prefab)!;
var node = instantiate(prefab);
let label =node.getChildByName("top").getChildByName("lab_name")
label.getComponent(Label)!.string = profession;
var scene = smc.map.MapView.scene;
node.parent = scene.entityLayer!.node!;
var as = node.getComponent(HeroSpine);
node.setPosition(pos)
node.setScale(1, 1, 1);
var mv = node.getComponent(HeroViewComp)!;
mv.speed=smc.heros[0].speed;
this.add(mv);
//移除全局列表
// console.log(ecs.query(ecs.allOf(HeroViewComp)))
}
}

View File

@@ -1 +0,0 @@
{"ver":"4.0.23","importer":"typescript","imported":true,"uuid":"984e9949-2b16-4e46-bb30-6ac00a2a838e","files":[],"subMetas":{},"userData":{}}

View File

@@ -1 +0,0 @@
{"ver":"4.0.23","importer":"typescript","imported":true,"uuid":"0ce59d56-a495-4b95-9405-a8a85d47a439","files":[],"subMetas":{},"userData":{}}

View File

@@ -1 +0,0 @@
{"ver":"4.0.23","importer":"typescript","imported":true,"uuid":"c66b3a64-90df-4454-b232-a18b05baed20","files":[],"subMetas":{},"userData":{}}

View File

@@ -1 +0,0 @@
{"ver":"4.0.23","importer":"typescript","imported":true,"uuid":"4f84982c-c68b-4950-b521-892438804b1a","files":[],"subMetas":{},"userData":{}}

View File

@@ -1,90 +0,0 @@
/*
* @Author: dgflash
* @Date: 2021-11-18 17:42:59
* @LastEditors: dgflash
* @LastEditTime: 2022-08-17 12:36:18
*/
import { Vec3, v3,_decorator ,Collider2D,Contact2DType,PhysicsSystem2D,IPhysics2DContact,EPhysics2DDrawFlags} from "cc";
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
import { HeroSpine } from "./HeroSpine";
import {BoxSet} from "../common/config/BoxSet"
import { smc } from "../common/SingletonModuleComp";
const { ccclass, property } = _decorator;
/** 角色显示组件 */
@ccclass('HeroViewComp') // 定义为 Cocos Creator 组件
@ecs.register('HeroView', false) // 定义为 ECS 组件
export class HeroViewComp extends CCComp {
/** 角色动画 */
as: HeroSpine = null!;
/** 角色控制器 */
speed: number = 100;
Tpos: Vec3 = v3(0,-60,0);
start () {
// 注册单个碰撞体的回调函数
// console.log('MonsterViewComp start');
let collider = this.getComponent(Collider2D);
if (collider) {
// console.log('hero collider',collider);
collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
}
// 注册全局碰撞回调函数
if (PhysicsSystem2D.instance) {
// console.log('PhysicsSystem2D.instance');
PhysicsSystem2D.instance.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
}
}
onBeginContact (selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
// 只在两个碰撞体开始接触时被调用一次
// console.log('hero Contact,selfCollider',selfCollider);
switch (otherCollider.group) {
case BoxSet.MONSTER:
// console.log('hero coolider MONSTER ');
break;
case BoxSet.MONSTER_SKILL:
// console.log('hero coolider MONSTER skill');
break;
default:
break;
}
}
/** 视图层逻辑代码分离演示 */
onLoad() {
this.as = this.getComponent(HeroSpine);
}
update(dt: number){
if(this.node.position.x < 360){
this.move(dt);
}
if(this.node.position.x > 360){
smc.heros_in = smc.heros_in.filter(element => element.eid !== this.ent.eid);
this.node.destroy();
}
this.update_pos();
}
move(dt: number){
this.node.setPosition(this.node.position.x+dt*this.speed, this.node.position.y, this.node.position.z);
}
update_pos(){
smc.heros_in.forEach(element => {
if(element.eid == this.ent.eid){
element.pos_x = this.node.position.x;
}
});
// console.log('smc.heros_in',smc.heros_in);
}
reset() {
this.node.destroy();
}
}

View File

@@ -1 +0,0 @@
{"ver":"4.0.23","importer":"typescript","imported":true,"uuid":"ffc9ef3c-4de8-4996-abe0-296d8956dcfe","files":[],"subMetas":{},"userData":{}}