This commit is contained in:
PC-20230316NUNE\Administrator 2023-10-25 19:19:52 +08:00
parent 5998a96d9e
commit cb70ba12c7
12 changed files with 214 additions and 53 deletions

View File

@ -219,8 +219,8 @@
"_color": { "_color": {
"__type__": "cc.Color", "__type__": "cc.Color",
"r": 255, "r": 255,
"g": 255, "g": 61,
"b": 255, "b": 61,
"a": 255 "a": 255
}, },
"_spriteFrame": { "_spriteFrame": {
@ -425,7 +425,7 @@
"__expectedType__": "sp.SkeletonData" "__expectedType__": "sp.SkeletonData"
}, },
"defaultSkin": "default", "defaultSkin": "default",
"defaultAnimation": "", "defaultAnimation": "walk",
"_premultipliedAlpha": true, "_premultipliedAlpha": true,
"_timeScale": 1, "_timeScale": 1,
"_preCacheMode": 0, "_preCacheMode": 0,

View File

@ -116,8 +116,12 @@ export default class GPVPMode extends GBaseMode{
}); });
return sort[0] return sort[0]
}
//销毁角色数据
killRole(role:GRolePVPEntity){
this.playerRoles.splice(this.playerRoles.indexOf(role),1);
this.enemyRoles.splice(this.enemyRoles.indexOf(role),1);
} }
} }

View File

@ -9,6 +9,20 @@ export default class GObject<T> extends JNGSyncProtoBase<T>{
//当前模式 //当前模式
_mode:GBaseMode; _mode:GBaseMode;
//是否镜像
_isMirror:boolean = false;
get isMirror(){
return this._isMirror;
}
set isMirror(value:boolean){
if(value){
GObject.SetMirror(this);
}else{
GObject.SetMirror(this,false);
}
this._isMirror = value;
}
get mode():GBaseMode{ get mode():GBaseMode{
return this._mode; return this._mode;
} }
@ -28,5 +42,15 @@ export default class GObject<T> extends JNGSyncProtoBase<T>{
return v2(world.x,world.y); return v2(world.x,world.y);
} }
//向后添加距离
getWorldBackLen(add:Vec2){
if(this.isMirror){
return this.v2World.add(add);
}else{
add.y = 0-add.y;
return this.v2World.subtract(add);
}
}
} }

View File

@ -26,6 +26,9 @@ export enum GFSMProcessEnum{
//状态机基类 //状态机基类
export default class GFSMBase{ export default class GFSMBase{
//是否关闭
isClose:boolean = false;
//状态流程图 //状态流程图
process:{[key:number]:GFSMProcessInfo} = {}; process:{[key:number]:GFSMProcessInfo} = {};
@ -38,14 +41,19 @@ export default class GFSMBase{
//状态机刷新 //状态机刷新
onUpdate(dt:number){ onUpdate(dt:number){
if(this.isClose) return;
if(!this.start) this.start = 0; if(!this.start) this.start = 0;
if(!this.current) this.current = 0; if(!this.current) this.current = 0;
//运行流程 //运行流程
this.execute(this.process[this.current],dt); this.execute(this.process[this.current],dt);
} }
close(){
this.isClose = true;
}
//执行流程 //执行流程
execute(process:GFSMProcessInfo,dt:number){ execute(process:GFSMProcessInfo,dt:number){
if(!process) return; if(!process) return;

View File

@ -1,3 +1,4 @@
import GRoleUtil from "../../../util/GRoleUtil";
import GRoleBase from "../../role/GRoleBase"; import GRoleBase from "../../role/GRoleBase";
import GRolePVPEntity from "../../role/PVP/GRolePVPEntity"; import GRolePVPEntity from "../../role/PVP/GRolePVPEntity";
import GFSMBattle from "../base/GFSMBattle/GFSMBattle"; import GFSMBattle from "../base/GFSMBattle/GFSMBattle";
@ -6,11 +7,13 @@ import GFSMBattle from "../base/GFSMBattle/GFSMBattle";
//PVP 状态机 //PVP 状态机
export default class GFSMPVP extends GFSMBattle{ export default class GFSMPVP extends GFSMBattle{
player:GRolePVPEntity; get player(): GRolePVPEntity {
return super.player as GRolePVPEntity;
}
constructor(player:GRolePVPEntity){ constructor(player:GRolePVPEntity){
super(player); super(player);
this.player = player; this._player = GRoleUtil.get(player);
} }
//寻敌 //寻敌

View File

@ -1,6 +1,7 @@
import { Vec2 } from "cc"; import { Vec2 } from "cc";
import GRoleBase from "../../../role/GRoleBase"; import GRoleBase from "../../../role/GRoleBase";
import GFSMBase, { GFSMProcessEnum, GFSMProcessInfo, GFSMProcessMode } from "../../GFSMBase"; import GFSMBase, { GFSMProcessEnum, GFSMProcessInfo, GFSMProcessMode } from "../../GFSMBase";
import GRoleUtil from "../../../../util/GRoleUtil";
//流程枚举 //流程枚举
@ -17,7 +18,20 @@ enum ProcessEnum {
export default abstract class GFSMBattle extends GFSMBase{ export default abstract class GFSMBattle extends GFSMBase{
player:GRoleBase<{}>; protected _player:() => GRoleBase<{}>;
get player():GRoleBase<{}>{
if(this._player)
return this._player();
return null;
}
//锁定的敌人
_enemy:() => GRoleBase<any>;
get enemy():GRoleBase<{}>{
if(this._enemy)
return this._enemy();
return null;
}
//流程图 //流程图
process: { [key: number]: GFSMProcessInfo; } = { process: { [key: number]: GFSMProcessInfo; } = {
@ -39,19 +53,16 @@ export default abstract class GFSMBattle extends GFSMBase{
execute: this.onAttackProcess.bind(this), execute: this.onAttackProcess.bind(this),
to:[ProcessEnum.MoveToTactical],//移动回阵型 to:[ProcessEnum.MoveToTactical],//移动回阵型
}, },
// [ProcessEnum.MoveToTactical]:{ [ProcessEnum.MoveToTactical]:{
// title:"移动回阵型", title:"移动回阵型",
// mode:GFSMProcessMode.WaitExecute, mode:GFSMProcessMode.WaitExecute,
// execute: this.onMoveToTacticalProcess.bind(this), execute: this.onMoveToTacticalProcess.bind(this),
// } }
} }
//锁定的敌人
enemy:GRoleBase<any>;
constructor(player:GRoleBase<{}>){ constructor(player:GRoleBase<{}>){
super(); super();
this.player = player; this._player = GRoleUtil.get(player);
} }
abstract onSeekEnemy():GRoleBase<any>; abstract onSeekEnemy():GRoleBase<any>;
@ -68,7 +79,7 @@ export default abstract class GFSMBattle extends GFSMBase{
return ProcessEnum.MoveToAttackRange; return ProcessEnum.MoveToAttackRange;
} }
if(this.enemy = this.onSeekEnemy()){ if((this._enemy = GRoleUtil.get(this.onSeekEnemy())) && this.enemy){
//如果有敌人 直接 攻击 //如果有敌人 直接 攻击
return ProcessEnum.MoveToAttackRange; return ProcessEnum.MoveToAttackRange;
} }
@ -122,7 +133,12 @@ export default abstract class GFSMBattle extends GFSMBase{
//播放移动 //播放移动
this.player.fsmAnim.isMove = false; this.player.fsmAnim.isMove = false;
this.player.fsmAnim.isAttack = true; this.player.fsmAnim.isAttack = true;
return GFSMProcessEnum.Wait; //如果有敌人则攻击 没有 则 重置
if(this.enemy){
return GFSMProcessEnum.Wait;
}else{
return ProcessEnum.MoveToTactical;
}
} }

View File

@ -32,6 +32,8 @@ enum ProcessEnum {
Move = 1, Move = 1,
//攻击 //攻击
Attack = 2, Attack = 2,
//死亡
Die = 3,
} }
//动画状态机基类 //动画状态机基类
@ -43,6 +45,9 @@ export class GFSMBattleAmin extends GFSMBase{
//是否移动 //是否移动
isMove:boolean = false; isMove:boolean = false;
//是否死亡
isDie:boolean = false;
//轨道的索引 //轨道的索引
trackIndex:number; trackIndex:number;
@ -50,6 +55,7 @@ export class GFSMBattleAmin extends GFSMBase{
spine:sp.Skeleton; spine:sp.Skeleton;
events:{event:string,fun:Function}[] = []; events:{event:string,fun:Function}[] = [];
starts:{name:string,fun:Function}[] = [];
constructor(spine:sp.Skeleton,trackIndex?:number){ constructor(spine:sp.Skeleton,trackIndex?:number){
super(); super();
@ -57,6 +63,7 @@ export class GFSMBattleAmin extends GFSMBase{
this.trackIndex = trackIndex || 0; this.trackIndex = trackIndex || 0;
//设置监听 //设置监听
this.spine.setEventListener(this.onEventListener.bind(this)); this.spine.setEventListener(this.onEventListener.bind(this));
this.spine.setStartListener(this.onStartListener.bind(this));
} }
//添加事件监听 //添加事件监听
@ -67,6 +74,14 @@ export class GFSMBattleAmin extends GFSMBase{
}) })
} }
//监听动画开始播放
addStartListener(name:string,fun:Function){
this.starts.push({
name,
fun,
})
}
onEventListener(entry: sp.spine.TrackEntry, ev: sp.spine.Event){ onEventListener(entry: sp.spine.TrackEntry, ev: sp.spine.Event){
this.events.forEach(item => { this.events.forEach(item => {
if(item.event == ev.data.name){ if(item.event == ev.data.name){
@ -75,6 +90,14 @@ export class GFSMBattleAmin extends GFSMBase{
}); });
} }
onStartListener(entry: sp.spine.TrackEntry){
this.starts.forEach(item => {
if(entry.animation.name == item.name){
item.fun();
}
});
}
// 流程图 // 流程图
process: { [key: number]: GFSMProcessAnimInfo; } = { process: { [key: number]: GFSMProcessAnimInfo; } = {
[ProcessEnum.Wait]:{ [ProcessEnum.Wait]:{
@ -82,10 +105,11 @@ export class GFSMBattleAmin extends GFSMBase{
isLoop:true, isLoop:true,
animName:GFSMBattleAminEnum.Wait, animName:GFSMBattleAminEnum.Wait,
mixs:[0.1,0.1], mixs:[0.1,0.1],
to:[ProcessEnum.Move,ProcessEnum.Attack], to:[ProcessEnum.Move,ProcessEnum.Attack,ProcessEnum.Die],
ifTo:[ ifTo:[
() => this.isMove, //前往移动 () => this.isMove, //前往移动
() => this.isAttack //前往攻击 () => this.isAttack, //前往攻击
() => this.isDie,
], ],
}, },
[ProcessEnum.Move]:{ [ProcessEnum.Move]:{
@ -93,26 +117,36 @@ export class GFSMBattleAmin extends GFSMBase{
animName:GFSMBattleAminEnum.Walk, animName:GFSMBattleAminEnum.Walk,
isLoop:true, isLoop:true,
mixs:[0.1,0.1], mixs:[0.1,0.1],
to:[ProcessEnum.Wait,ProcessEnum.Attack], to:[ProcessEnum.Wait,ProcessEnum.Attack,ProcessEnum.Die],
ifTo:[ ifTo:[
() => !this.isMove, //前往等待 () => !this.isMove, //前往等待
() => this.isAttack, //前往攻击 () => this.isAttack, //前往攻击
() => this.isDie,
], ],
}, },
2:{ [ProcessEnum.Attack]:{
title:"攻击", title:"攻击",
animName:GFSMBattleAminEnum.Attack, animName:GFSMBattleAminEnum.Attack,
isLoop:true, isLoop:true,
mixs:[0.1,0.1], mixs:[0.1,0.1],
to:[ProcessEnum.Wait,ProcessEnum.Move], to:[ProcessEnum.Wait,ProcessEnum.Move,ProcessEnum.Die],
ifTo:[ ifTo:[
() => !this.isAttack, //前往等待 () => !this.isAttack, //前往等待
() => !this.isAttack && this.isMove, //前往移动 () => !this.isAttack && this.isMove, //前往移动
() => this.isDie,
], ],
},
[ProcessEnum.Die]:{
title:"死亡",
animName:GFSMBattleAminEnum.Fly,
isLoop:true,
mixs:[0.1,0.1],
} }
} }
execute(process:GFSMProcessAnimInfo,dt:number){ execute(process:GFSMProcessAnimInfo,dt:number){
process.ifTo = process.ifTo || [];
process.to = process.to || [];
process.mode = GFSMProcessMode.WaitExecute; process.mode = GFSMProcessMode.WaitExecute;
process.execute = this.tick.bind(this); process.execute = this.tick.bind(this);
super.execute(process,dt); super.execute(process,dt);

View File

@ -1,13 +1,13 @@
import { _decorator, sp } from "cc"; import { _decorator, sp } from "cc";
import GObject from "../GObject"; import GObject from "../GObject";
import { JNFrameInfo } from "../../../../../extensions/ngame/assets/ngame/sync/frame/JNSyncFrame"; import { JNFrameInfo } from "../../../../../extensions/ngame/assets/ngame/sync/frame/JNSyncFrame";
import GFSMBase from "../fsm/GFSMBase";
import GFSMBattle from "../fsm/base/GFSMBattle/GFSMBattle"; import GFSMBattle from "../fsm/base/GFSMBattle/GFSMBattle";
import { GFSMBattleAmin } from "../fsm/base/GFSMBattle/GFSMBattleAmin"; import { GFSMBattleAmin, GFSMBattleAminEnum } from "../fsm/base/GFSMBattle/GFSMBattleAmin";
import { Vec2 } from "cc"; import { Vec2 } from "cc";
import { v2 } from "cc";
import { v3 } from "cc"; import { v3 } from "cc";
import { GTactical } from "../../entity/GTactical"; import { GTactical } from "../../entity/GTactical";
import { JEasing, JTween } from "../../../../../extensions/ngame/assets/ngame/sync/frame/game/tween/JNFrameTween";
import { v2 } from "cc";
const { ccclass, property } = _decorator; const { ccclass, property } = _decorator;
export enum GRoleAnimEvent{ export enum GRoleAnimEvent{
@ -26,9 +26,6 @@ export default abstract class GRoleBase<T> extends GObject<T>{
//动画状态机 //动画状态机
fsmAnim:GFSMBattleAmin; fsmAnim:GFSMBattleAmin;
//玩家是否镜像
_isMirror:boolean = false;
//玩家攻击范围 //玩家攻击范围
range:number = 100; range:number = 100;
@ -48,16 +45,18 @@ export default abstract class GRoleBase<T> extends GObject<T>{
blood:number = 100; blood:number = 100;
fullBlood:number = 100; fullBlood:number = 100;
get isMirror(){ //是否死亡
return this._isMirror; _isDie:boolean = false;
get isDie(){ return this._isDie}
set isDie(value:boolean){
this._isDie = value;
//设置死亡状态
this.fsmAnim.isDie = value;
} }
set isMirror(value:boolean){
if(value){ get():GRoleBase<T>{
GObject.SetMirror(this); if(this.isDie) return null;
}else{ return this;
GObject.SetMirror(this,false);
}
this._isMirror = value;
} }
onSyncLoad(){ onSyncLoad(){
@ -76,21 +75,11 @@ export default abstract class GRoleBase<T> extends GObject<T>{
//监听攻击 //监听攻击
this.fsmAnim.addEventListener(GRoleAnimEvent.Attack,this.onAttack.bind(this)); this.fsmAnim.addEventListener(GRoleAnimEvent.Attack,this.onAttack.bind(this));
//监听死亡击飞
this.fsmAnim.addStartListener(GFSMBattleAminEnum.Fly,this.onFly.bind(this));
} }
//攻击
onAttack(){
//敌人扣血
this.fsm.enemy.onHit();
}
//受击
onHit(){
this.blood--;
}
//创建一个状态机 //创建一个状态机
protected abstract fsmCreate():GFSMBattle; protected abstract fsmCreate():GFSMBattle;
//创建一个动画状态机 //创建一个动画状态机
@ -120,5 +109,42 @@ export default abstract class GRoleBase<T> extends GObject<T>{
} }
//攻击
onAttack(){
//敌人扣血
this.fsm.enemy.onHit();
}
//受击
onHit(){
this.blood-=50;
//检测是否死亡
if(this.blood <= 0){
//关闭状态机
this.fsm.close();
//设置死亡
this.isDie = true;
}
}
//击飞
onFly(){
console.log("onFly");
let vWorld = this.node.worldPosition;
let vEndWorld = this.getWorldBackLen(v2(800,500));
JTween(vWorld)
.to({x:vEndWorld.x},500)
.onUpdate(pos => this.node.worldPosition = vWorld)
.start();
JTween(vWorld)
.to({y:vEndWorld.y},500)
.easing(JEasing.Circular.Out)
.onUpdate(pos => this.node.worldPosition = vWorld)
.start();
}
} }

View File

@ -67,12 +67,21 @@ export default class GRolePVPEntity extends GRoleBase<GDemoMessage>{
} }
protected fsmCreate(): GFSMPVP { protected fsmCreate(): GFSMPVP {
// return null;
return new GFSMPVP(this); return new GFSMPVP(this);
} }
protected fsmAnimCreate(): GFSMBattleAmin { protected fsmAnimCreate(): GFSMBattleAmin {
return new GFSMBattleAmin(this.spine); return new GFSMBattleAmin(this.spine);
} }
//添加死亡销毁
onHit(){
super.onHit();
if(this.isDie){
//销毁数据
this.mode.killRole(this);
this.node.removeFromParent();
}
}
} }

View File

@ -0,0 +1,9 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "f07db6b6-6ffb-4cb1-9822-d9b248e3f57a",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@ -0,0 +1,19 @@
import GRoleBase from "../base/role/GRoleBase";
//角色工具类
export default class GRoleUtil{
//获取存活的玩家 如果不存活则返回 null
static get<T>(player:GRoleBase<T>):() => GRoleBase<T>{
if(!player) return null;
return ():GRoleBase<T> => {
if(player)
return player.get();
return null;
}
}
}

View File

@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "9215634b-6c3f-47a2-a303-04408eb3e053",
"files": [],
"subMetas": {},
"userData": {}
}