添加role 删除多余地图文件
This commit is contained in:
2000
assets/resources/game/heros/role.prefab
Normal file
2000
assets/resources/game/heros/role.prefab
Normal file
File diff suppressed because it is too large
Load Diff
13
assets/resources/game/heros/role.prefab.meta
Normal file
13
assets/resources/game/heros/role.prefab.meta
Normal 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"
|
||||
}
|
||||
}
|
||||
@@ -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": {}
|
||||
@@ -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": {}
|
||||
@@ -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": {}
|
||||
@@ -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": {}
|
||||
}
|
||||
@@ -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": {}
|
||||
}
|
||||
9
assets/script/game/Role/PlayerViewComp.ts.meta
Normal file
9
assets/script/game/Role/PlayerViewComp.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "ce8e182a-d776-4361-9de5-cde2246c65a2",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
68
assets/script/game/Role/Role.ts
Normal file
68
assets/script/game/Role/Role.ts
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
9
assets/script/game/Role/Role.ts.meta
Normal file
9
assets/script/game/Role/Role.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "9457fea4-0213-4426-a3ed-5234cc7985dc",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -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;
|
||||
9
assets/script/game/Role/RoleModelComp.ts.meta
Normal file
9
assets/script/game/Role/RoleModelComp.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "1ae88b75-8890-46c0-a795-faf44c20ff92",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* RPG SPINE角色模型
|
||||
*/
|
||||
@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 {
|
||||
9
assets/script/game/Role/RoleSpine.ts.meta
Normal file
9
assets/script/game/Role/RoleSpine.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "de8f3803-ed59-466e-b93b-f1e3e587113d",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -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);
|
||||
9
assets/script/game/Role/RoleSpineAnimator.ts.meta
Normal file
9
assets/script/game/Role/RoleSpineAnimator.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "7238526c-ee07-4d38-be30-ec2a4a5359c4",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
117
assets/script/game/Role/RoleViewComp.ts
Normal file
117
assets/script/game/Role/RoleViewComp.ts
Normal 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");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
9
assets/script/game/Role/RoleViewComp.ts.meta
Normal file
9
assets/script/game/Role/RoleViewComp.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "b8b21b3c-dd6b-466b-8bdf-010481a9c576",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
25
assets/script/game/common/config/RoleSet.ts
Normal file
25
assets/script/game/common/config/RoleSet.ts
Normal 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:{ }},
|
||||
}
|
||||
|
||||
9
assets/script/game/common/config/RoleSet.ts.meta
Normal file
9
assets/script/game/common/config/RoleSet.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "bde4950f-acae-4c3e-a6a7-39248c34613d",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -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")
|
||||
|
||||
@@ -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() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "b0f6dc85-a76e-4bdf-a11c-d1b518f80db5",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"compressionType": {},
|
||||
"isRemoteBundle": {}
|
||||
}
|
||||
}
|
||||
@@ -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[] = [];
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
/**
|
||||
* 地图加载模式
|
||||
*/
|
||||
export enum MapLoadModel {
|
||||
/**
|
||||
* 单张地图加载
|
||||
*/
|
||||
single = 0,
|
||||
|
||||
/**
|
||||
* 分切片加载
|
||||
*/
|
||||
slices = 1,
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "2f328b5a-8e30-4411-a6d1-997689a315a7",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"simulateGlobals": []
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
|
||||
export enum MapType {
|
||||
angle45 = 0,
|
||||
angle90 = 1,
|
||||
honeycomb = 2,
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "967a1a19-a1dd-4241-81d7-a92f041c19e9",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"simulateGlobals": []
|
||||
}
|
||||
}
|
||||
@@ -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 => {
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ export default class SkillLayer extends Component {
|
||||
}
|
||||
|
||||
start(){
|
||||
console.log("SkillLayer start")
|
||||
// console.log("SkillLayer start")
|
||||
}
|
||||
|
||||
public clear() {
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "76609af6-ff56-411b-a2e5-b6a6027fb037",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"compressionType": {},
|
||||
"isRemoteBundle": {}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "a3a19dc4-7645-485a-80e0-b49fdb062b00",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"simulateGlobals": []
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "470f8a32-bf7c-4747-bd7d-07042bbc389e",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"simulateGlobals": []
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "e4f3fe84-cffc-40ca-ac1a-e0d853f234d8",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"simulateGlobals": []
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "38983af0-c3cc-42a2-bd83-49e6b001f888",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"simulateGlobals": []
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "520e470b-8810-4f2d-8444-cd2446965b49",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"simulateGlobals": []
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "a55696bb-2934-4388-a1af-182ab13401ef",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"simulateGlobals": []
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
|
||||
@@ -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)))
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
{"ver":"4.0.23","importer":"typescript","imported":true,"uuid":"984e9949-2b16-4e46-bb30-6ac00a2a838e","files":[],"subMetas":{},"userData":{}}
|
||||
@@ -1 +0,0 @@
|
||||
{"ver":"4.0.23","importer":"typescript","imported":true,"uuid":"0ce59d56-a495-4b95-9405-a8a85d47a439","files":[],"subMetas":{},"userData":{}}
|
||||
@@ -1 +0,0 @@
|
||||
{"ver":"4.0.23","importer":"typescript","imported":true,"uuid":"c66b3a64-90df-4454-b232-a18b05baed20","files":[],"subMetas":{},"userData":{}}
|
||||
@@ -1 +0,0 @@
|
||||
{"ver":"4.0.23","importer":"typescript","imported":true,"uuid":"4f84982c-c68b-4950-b521-892438804b1a","files":[],"subMetas":{},"userData":{}}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
{"ver":"4.0.23","importer":"typescript","imported":true,"uuid":"ffc9ef3c-4de8-4996-abe0-296d8956dcfe","files":[],"subMetas":{},"userData":{}}
|
||||
Reference in New Issue
Block a user