mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-06-26 03:14:47 +00:00
update
This commit is contained in:
parent
72f3d7e880
commit
fb1696d079
@ -1,7 +1,7 @@
|
||||
[
|
||||
{
|
||||
"__type__": "cc.Prefab",
|
||||
"_name": "RoleEntity",
|
||||
"_name": "RolePVPEntity",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"_native": "",
|
||||
@ -13,7 +13,7 @@
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "RoleEntity",
|
||||
"_name": "RolePVPEntity",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"_parent": null,
|
@ -8,6 +8,6 @@
|
||||
],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"syncNodeName": "RoleEntity"
|
||||
"syncNodeName": "RolePVPEntity"
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
9
JisolGameCocos/assets/resources/proto.meta
Normal file
9
JisolGameCocos/assets/resources/proto.meta
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "35e11e81-b6f9-4691-9b51-87135d43f671",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
12
JisolGameCocos/assets/resources/proto/GDemo.proto
Normal file
12
JisolGameCocos/assets/resources/proto/GDemo.proto
Normal file
@ -0,0 +1,12 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option java_package = "cn.jisol.ngame.proto";
|
||||
import "google/protobuf/any.proto";
|
||||
|
||||
//测试输入
|
||||
message GDemoMessage {
|
||||
//是否攻击
|
||||
bool isAttack = 1;
|
||||
//是否奔跑
|
||||
bool isRun = 2;
|
||||
}
|
11
JisolGameCocos/assets/resources/proto/GDemo.proto.meta
Normal file
11
JisolGameCocos/assets/resources/proto/GDemo.proto.meta
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"ver": "1.0.2",
|
||||
"importer": "text",
|
||||
"imported": true,
|
||||
"uuid": "c9f4975a-e568-4d6c-af34-98620327eaf1",
|
||||
"files": [
|
||||
".json"
|
||||
],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
@ -23,7 +23,7 @@ class JNGLayer extends JNLayer{
|
||||
//重写Socket
|
||||
class JNGSocket extends JNSocket{
|
||||
public url() {
|
||||
return "ws://localhost:8080/websocket";
|
||||
return "ws://192.168.0.127:8080/websocket";
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,6 +71,7 @@ export class JNGLayerBase extends JNLayerBase{
|
||||
|
||||
//重写Sync Base
|
||||
export class JNGSyncBase<T> extends JNSyncFrameComponent<T>{
|
||||
onSyncLoad() { }
|
||||
onSyncUpdate(dt: number,frame:JNFrameInfo, input?: T) { }
|
||||
protected getSync(): JNSyncFrame {
|
||||
return app.sync
|
||||
@ -80,6 +81,7 @@ export class JNGSyncBase<T> extends JNSyncFrameComponent<T>{
|
||||
//重写Sync Proto Base
|
||||
export abstract class JNGSyncProtoBase<T> extends JNSyncFrameProtoComponent<T>{
|
||||
|
||||
onSyncLoad() { }
|
||||
onSyncUpdate(dt: number,frame:JNFrameInfo, input?: T) { }
|
||||
protected getSync(): JNSyncFrame {
|
||||
return app.sync
|
||||
@ -94,7 +96,7 @@ export const app = {
|
||||
event : EventDispatcher.getIns(), //通知
|
||||
proto : NGameMessage.getIns(), //消息
|
||||
api : axios.create({
|
||||
baseURL: "http://localhost:8080",
|
||||
baseURL: "http://192.168.0.127:8080",
|
||||
}), //请求
|
||||
battle : GBattleModeManager.getIns(), //战斗
|
||||
}
|
@ -2,6 +2,7 @@ import { _decorator, Component, director, instantiate, Node, Prefab } from 'cc';
|
||||
import { app } from './App';
|
||||
import { JNGame } from '../../extensions/ngame/assets/ngame/JNGame';
|
||||
import { JNSyncAction } from '../../extensions/ngame/assets/ngame/sync/JNSyncAction';
|
||||
import JNFrameTween, { JTween } from '../../extensions/ngame/assets/ngame/sync/frame/game/tween/JNFrameTween';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass('Main')
|
||||
@ -15,8 +16,12 @@ export class Main extends Component {
|
||||
|
||||
async onLoad(){
|
||||
|
||||
JTween().start();
|
||||
|
||||
//加载 APP
|
||||
await JNGame.Init(app);
|
||||
await JNGame.Init(app,[
|
||||
{path:"proto/GDemo"}
|
||||
]);
|
||||
|
||||
//发生帧同步开始
|
||||
app.socket.Send(JNSyncAction.NSyncFrameStart);
|
||||
|
@ -113,7 +113,6 @@ export default class GPVPMode extends GBaseMode{
|
||||
return Math.abs((playerXY.y * 1000) - (enumy1XY.y * 1000)) + Math.abs((playerXY.x - enumy1XY.x)) -
|
||||
Math.abs((playerXY.y * 1000) - (enumy2XY.y * 1000)) + Math.abs((playerXY.x - enumy2XY.x))
|
||||
});
|
||||
console.log(playerXY,sort[0].tactical.getXY(sort[0].tacticalIndex),);
|
||||
return sort[0]
|
||||
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
import { Vec2 } from "cc";
|
||||
import { JNGSyncProtoBase } from "../../App";
|
||||
import GBaseMode from "../GBaseMode";
|
||||
import { v2 } from "cc";
|
||||
|
||||
|
||||
export default class GObject<T> extends JNGSyncProtoBase<T>{
|
||||
@ -14,5 +16,17 @@ export default class GObject<T> extends JNGSyncProtoBase<T>{
|
||||
this._mode = value;
|
||||
}
|
||||
|
||||
//设置镜像
|
||||
static SetMirror(role:GObject<{}>,flipX:boolean = true,flipY:boolean = false){
|
||||
let node = role.node;
|
||||
node.setScale(flipX ? -Math.abs(node.scale.x) : Math.abs(node.scale.x),flipY ? -Math.abs(node.scale.y) : Math.abs(node.scale.y))
|
||||
}
|
||||
|
||||
//获取v2世界坐标
|
||||
get v2World():Vec2{
|
||||
let world = this.node.worldPosition;
|
||||
return v2(world.x,world.y);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -12,11 +12,17 @@ export interface GFSMProcessInfo{
|
||||
//模式
|
||||
mode?:GFSMProcessMode;
|
||||
//执行方法
|
||||
execute?:() => number;
|
||||
execute?:(dt:number,info:GFSMProcessInfo) => number;
|
||||
//前往
|
||||
to?:number[];
|
||||
}
|
||||
|
||||
//流程枚举
|
||||
export enum GFSMProcessEnum{
|
||||
Reset = -1,//重置
|
||||
Wait = -2,//等待
|
||||
}
|
||||
|
||||
//状态机基类
|
||||
export default class GFSMBase{
|
||||
|
||||
@ -36,12 +42,12 @@ export default class GFSMBase{
|
||||
if(!this.current) this.current = 0;
|
||||
|
||||
//运行流程
|
||||
this.execute(this.process[this.current]);
|
||||
this.execute(this.process[this.current],dt);
|
||||
|
||||
}
|
||||
|
||||
//执行流程
|
||||
execute(process:GFSMProcessInfo){
|
||||
execute(process:GFSMProcessInfo,dt:number){
|
||||
if(!process) return;
|
||||
|
||||
process.mode = process.mode || GFSMProcessMode.Execute;
|
||||
@ -54,26 +60,27 @@ export default class GFSMBase{
|
||||
switch(process.mode){
|
||||
case GFSMProcessMode.Execute:
|
||||
//执行方法
|
||||
next = process.to[process.execute()-1];
|
||||
next = process.execute(dt,process);
|
||||
break;
|
||||
case GFSMProcessMode.WaitExecute:
|
||||
//执行等待方法
|
||||
let state = process.execute();
|
||||
//如果 状态 -1 则 不重置 下一次状态从当前开始流程执行
|
||||
if(state == -1){
|
||||
next = process.execute(dt,process);
|
||||
//如果 状态 Wait 则 不重置 下一次状态从当前开始流程执行
|
||||
if(next == GFSMProcessEnum.Wait){
|
||||
isReset = false;
|
||||
}else{
|
||||
next = state;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(process.to.indexOf(next) == -1 && next != GFSMProcessEnum.Wait && next != GFSMProcessEnum.Reset){
|
||||
console.log(`[GFSM]: 流程To中没有这个流程 请检查代码`,process,next);
|
||||
}
|
||||
if(!this.process[next]) next = null;
|
||||
|
||||
if(next){
|
||||
this.current = next;
|
||||
//运行下一个流程
|
||||
this.execute(this.process[next]);
|
||||
this.execute(this.process[next],dt);
|
||||
}else{
|
||||
if(isReset){
|
||||
//重置
|
||||
|
@ -1,54 +0,0 @@
|
||||
import GRoleBase from "../role/GRoleBase";
|
||||
import GFSMBase, { GFSMProcessInfo } from "./GFSMBase";
|
||||
|
||||
|
||||
export default abstract class GFSMBattle extends GFSMBase{
|
||||
|
||||
//流程图
|
||||
process: { [key: number]: GFSMProcessInfo; } = {
|
||||
0:{
|
||||
title:"寻找敌人",
|
||||
execute: this.onSeekEnemyProcess.bind(this),
|
||||
to:[1]
|
||||
},
|
||||
1:{
|
||||
title:"攻击敌人",
|
||||
execute: this.onAttackProcess.bind(this),
|
||||
}
|
||||
}
|
||||
|
||||
//锁定的敌人
|
||||
enemy:GRoleBase<any>;
|
||||
|
||||
|
||||
abstract onSeekEnemy():GRoleBase<any>;
|
||||
|
||||
//寻敌流程
|
||||
onSeekEnemyProcess():number{
|
||||
|
||||
if(this.enemy){
|
||||
//如果有敌人 直接 攻击
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(this.enemy = this.onSeekEnemy()){
|
||||
//如果有敌人 直接 攻击
|
||||
return 1;
|
||||
}
|
||||
|
||||
//负责继续寻敌
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
abstract onAttack();
|
||||
|
||||
//攻击敌人
|
||||
onAttackProcess(){
|
||||
this.onAttack();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import GRoleBase from "../../role/GRoleBase";
|
||||
import GRolePVPEntity from "../../role/PVP/GRolePVPEntity";
|
||||
import GFSMBattle from "../GFSMBattle";
|
||||
import GFSMBattle from "../base/GFSMBattle/GFSMBattle";
|
||||
|
||||
|
||||
//PVP 状态机
|
||||
@ -9,7 +9,7 @@ export default class GFSMPVP extends GFSMBattle{
|
||||
player:GRolePVPEntity;
|
||||
|
||||
constructor(player:GRolePVPEntity){
|
||||
super();
|
||||
super(player);
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
@ -18,8 +18,5 @@ export default class GFSMPVP extends GFSMBattle{
|
||||
return this.player.mode.getEnumy(this.player);
|
||||
}
|
||||
|
||||
//攻击
|
||||
onAttack() {
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,6 @@
|
||||
import { GFSMBattleAmin } from "../base/GFSMBattle/GFSMBattleAmin";
|
||||
|
||||
export default class GFSMPVPAnim extends GFSMBattleAmin{
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "3a061d5f-a202-4d3d-8758-1d1afbe1cd15",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
9
JisolGameCocos/assets/script/battle/base/fsm/base.meta
Normal file
9
JisolGameCocos/assets/script/battle/base/fsm/base.meta
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "552fd09c-0320-46c9-ac7a-abe954b75093",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "05230b14-5c88-45fd-99c6-31b4b0513f45",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
@ -0,0 +1,112 @@
|
||||
import { Vec2 } from "cc";
|
||||
import GRoleBase from "../../../role/GRoleBase";
|
||||
import GFSMBase, { GFSMProcessEnum, GFSMProcessInfo, GFSMProcessMode } from "../../GFSMBase";
|
||||
|
||||
|
||||
//流程枚举
|
||||
enum ProcessEnum {
|
||||
//寻找敌人
|
||||
SeekEnemy = 0,
|
||||
//移动到可攻击范围
|
||||
MoveToAttackRange = 1,
|
||||
//攻击敌人
|
||||
AttackEnemy = 2,
|
||||
//回阵型
|
||||
MoveToTactical = 3,
|
||||
}
|
||||
|
||||
export default abstract class GFSMBattle extends GFSMBase{
|
||||
|
||||
player:GRoleBase<{}>;
|
||||
|
||||
//流程图
|
||||
process: { [key: number]: GFSMProcessInfo; } = {
|
||||
[ProcessEnum.SeekEnemy]:{
|
||||
title:"寻找敌人",
|
||||
execute: this.onSeekEnemyProcess.bind(this),
|
||||
// to:[ProcessEnum.MoveToAttackRange], //移动到可攻击范围
|
||||
to:[ProcessEnum.AttackEnemy], //移动到可攻击范围
|
||||
},
|
||||
[ProcessEnum.MoveToAttackRange]:{
|
||||
title:"移动到可攻击范围",
|
||||
mode:GFSMProcessMode.WaitExecute,
|
||||
execute: this.onMoveToAttackRangeProcess.bind(this),
|
||||
to:[ProcessEnum.AttackEnemy,ProcessEnum.MoveToTactical] //攻击敌人 回阵型
|
||||
},
|
||||
[ProcessEnum.AttackEnemy]:{
|
||||
title:"攻击敌人",
|
||||
mode:GFSMProcessMode.WaitExecute,
|
||||
execute: this.onAttackProcess.bind(this),
|
||||
},
|
||||
[ProcessEnum.MoveToTactical]:{
|
||||
title:"移动回阵型",
|
||||
mode:GFSMProcessMode.WaitExecute,
|
||||
execute: this.onMoveToTacticalProcess.bind(this),
|
||||
to:[ProcessEnum.SeekEnemy], //寻找敌人
|
||||
}
|
||||
}
|
||||
|
||||
//锁定的敌人
|
||||
enemy:GRoleBase<any>;
|
||||
|
||||
constructor(player:GRoleBase<{}>){
|
||||
super();
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
abstract onSeekEnemy():GRoleBase<any>;
|
||||
|
||||
//寻敌流程
|
||||
onSeekEnemyProcess(dt:number):number{
|
||||
|
||||
if(this.enemy){
|
||||
//如果有敌人 直接 攻击
|
||||
return ProcessEnum.MoveToAttackRange;
|
||||
}
|
||||
|
||||
if(this.enemy = this.onSeekEnemy()){
|
||||
//如果有敌人 直接 攻击
|
||||
return ProcessEnum.MoveToAttackRange;
|
||||
}
|
||||
|
||||
//负责继续寻敌
|
||||
return GFSMProcessEnum.Reset;
|
||||
|
||||
}
|
||||
|
||||
//移动可攻击范围
|
||||
onMoveToAttackRangeProcess(){
|
||||
|
||||
//如果没有敌人则回阵型
|
||||
if(!this.enemy) return ProcessEnum.MoveToTactical;
|
||||
|
||||
let distance = Vec2.distance(this.player.v2World,this.enemy.v2World);
|
||||
|
||||
//如果在攻击范围则调用攻击 负责 靠近目标
|
||||
if(distance < this.player.range){
|
||||
return ProcessEnum.AttackEnemy;
|
||||
}else{
|
||||
//靠近目标
|
||||
// this.player.
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//移动回阵型
|
||||
onMoveToTacticalProcess(){
|
||||
|
||||
}
|
||||
|
||||
onAttack(dt:number){
|
||||
this.player.onAttackUpdate(dt);
|
||||
}
|
||||
|
||||
//攻击敌人
|
||||
onAttackProcess(dt:number){
|
||||
this.onAttack(dt);
|
||||
return GFSMProcessEnum.Reset;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "ac1a0b3b-e57a-4718-a27f-39b8e072f74e",
|
||||
"uuid": "8c02bc4d-30d6-47fe-82ff-e5496d4dca8f",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
@ -0,0 +1,135 @@
|
||||
import { sp } from "cc";
|
||||
import GFSMBase, { GFSMProcessEnum, GFSMProcessInfo, GFSMProcessMode } from "../../GFSMBase";
|
||||
|
||||
//角色动画名称枚举
|
||||
export enum GFSMBattleAminEnum {
|
||||
Wait = "std", //等待
|
||||
Walk = "walk", //移动
|
||||
Attack = "atk", //攻击
|
||||
Fly = "jifei", //击飞
|
||||
Skill = "jifei", //技能
|
||||
}
|
||||
|
||||
//动画流程信息
|
||||
export interface GFSMProcessAnimInfo extends GFSMProcessInfo{
|
||||
//动画名称
|
||||
animName:string;
|
||||
//是否循环播放
|
||||
isLoop?:boolean;
|
||||
//与下一个动作的融合值
|
||||
mixs?:number[];
|
||||
//播放的轨道
|
||||
track?:sp.spine.TrackEntry;
|
||||
ifTo?:(() => boolean)[];
|
||||
}
|
||||
|
||||
//流程枚举
|
||||
enum ProcessEnum {
|
||||
//等待
|
||||
Wait = 0,
|
||||
//移动
|
||||
Move = 1,
|
||||
//攻击
|
||||
Attack = 2,
|
||||
}
|
||||
|
||||
//动画状态机基类
|
||||
export class GFSMBattleAmin extends GFSMBase{
|
||||
|
||||
//是否攻击
|
||||
isAttack:boolean = false;
|
||||
|
||||
//是否移动
|
||||
isMove:boolean = false;
|
||||
|
||||
//轨道的索引
|
||||
trackIndex:number;
|
||||
|
||||
//动画Root
|
||||
spine:sp.Skeleton;
|
||||
|
||||
constructor(spine:sp.Skeleton,trackIndex?:number){
|
||||
super();
|
||||
this.spine = spine;
|
||||
this.trackIndex = trackIndex || 0;
|
||||
}
|
||||
|
||||
|
||||
// 流程图
|
||||
process: { [key: number]: GFSMProcessAnimInfo; } = {
|
||||
[ProcessEnum.Wait]:{
|
||||
title:"等待",
|
||||
isLoop:true,
|
||||
animName:GFSMBattleAminEnum.Wait,
|
||||
mixs:[0.1,0.1],
|
||||
to:[ProcessEnum.Move,ProcessEnum.Attack],
|
||||
ifTo:[
|
||||
() => this.isMove, //前往移动
|
||||
() => this.isAttack //前往攻击
|
||||
],
|
||||
},
|
||||
[ProcessEnum.Move]:{
|
||||
title:"移动",
|
||||
animName:GFSMBattleAminEnum.Walk,
|
||||
isLoop:true,
|
||||
mixs:[0.1,0.1],
|
||||
to:[ProcessEnum.Wait,ProcessEnum.Attack],
|
||||
ifTo:[
|
||||
() => !this.isMove, //前往等待
|
||||
() => this.isAttack, //前往攻击
|
||||
],
|
||||
},
|
||||
2:{
|
||||
title:"攻击",
|
||||
animName:GFSMBattleAminEnum.Attack,
|
||||
isLoop:true,
|
||||
mixs:[0.1,0.1],
|
||||
to:[ProcessEnum.Wait,ProcessEnum.Move],
|
||||
ifTo:[
|
||||
() => !this.isAttack, //前往等待
|
||||
() => !this.isAttack && this.isMove, //前往移动
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
execute(process:GFSMProcessAnimInfo,dt:number){
|
||||
process.mode = GFSMProcessMode.WaitExecute;
|
||||
process.execute = this.tick.bind(this);
|
||||
super.execute(process,dt);
|
||||
}
|
||||
|
||||
//-1 继续播放 0 重新执行流程 * 指定分支
|
||||
tick(dt:number,info:GFSMProcessAnimInfo){
|
||||
|
||||
//判断是否会切换动画 (默认不切换)
|
||||
let to = GFSMProcessEnum.Wait;
|
||||
info.ifTo.forEach((run,index) => {
|
||||
if(run()){
|
||||
to = info.to[index];
|
||||
}
|
||||
});
|
||||
|
||||
if(to >= 0) {
|
||||
//和下一个动作融合
|
||||
let mix = info.mixs[to - 1] || 0;
|
||||
if(mix){
|
||||
//设置融合
|
||||
this.spine.setMix(info.animName,this.process[to].animName,mix);
|
||||
}
|
||||
info.track = null;
|
||||
return to;
|
||||
}
|
||||
|
||||
//播放动画
|
||||
if(!info.track){
|
||||
console.log("播放动画",info);
|
||||
info.track = this.spine.setAnimation(this.trackIndex,info.animName,info.isLoop);
|
||||
}
|
||||
|
||||
return to;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "559e87e4-5a3f-4cc2-873d-e0fb5b61375b",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
@ -2,6 +2,10 @@ import { _decorator, sp } from "cc";
|
||||
import GObject from "../GObject";
|
||||
import { JNFrameInfo } from "../../../../../extensions/ngame/assets/ngame/sync/frame/JNSyncFrame";
|
||||
import GFSMBase from "../fsm/GFSMBase";
|
||||
import GFSMBattle from "../fsm/base/GFSMBattle/GFSMBattle";
|
||||
import { GFSMBattleAmin } from "../fsm/base/GFSMBattle/GFSMBattleAmin";
|
||||
import { Vec2 } from "cc";
|
||||
import { v2 } from "cc";
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
//角色基类
|
||||
@ -11,9 +15,31 @@ export default abstract class GRoleBase<T> extends GObject<T>{
|
||||
spine:sp.Skeleton;
|
||||
|
||||
//状态机
|
||||
fsm:GFSMBase;
|
||||
fsm:GFSMBattle;
|
||||
|
||||
onLoad(){
|
||||
//动画状态机
|
||||
fsmAnim:GFSMBattleAmin;
|
||||
|
||||
//玩家是否镜像
|
||||
_isMirror:boolean = false;
|
||||
|
||||
//玩家攻击范围
|
||||
range:number = 10;
|
||||
|
||||
get isMirror(){
|
||||
return this._isMirror;
|
||||
}
|
||||
set isMirror(value:boolean){
|
||||
if(value){
|
||||
GObject.SetMirror(this);
|
||||
}else{
|
||||
GObject.SetMirror(this,false);
|
||||
}
|
||||
this._isMirror = value;
|
||||
}
|
||||
|
||||
onSyncLoad(){
|
||||
|
||||
if(!this.spine) this.spine = this.node.getComponent(sp.Skeleton);
|
||||
//如果没有生成则直接销毁
|
||||
if(!this.spine) {
|
||||
@ -23,15 +49,26 @@ export default abstract class GRoleBase<T> extends GObject<T>{
|
||||
|
||||
//创建角色状态机
|
||||
this.fsm = this.fsmCreate();
|
||||
//创建角色动画状态机
|
||||
this.fsmAnim = this.fsmAnimCreate();
|
||||
|
||||
}
|
||||
|
||||
//创建一个状态机
|
||||
protected abstract fsmCreate():GFSMBase;
|
||||
protected abstract fsmCreate():GFSMBattle;
|
||||
//创建一个动画状态机
|
||||
protected abstract fsmAnimCreate():GFSMBattleAmin;
|
||||
|
||||
onSyncUpdate(dt: number,frame:JNFrameInfo, input?: T){
|
||||
//更新状态机
|
||||
this.fsm.onUpdate(dt);
|
||||
this.fsm && this.fsm.onUpdate(dt);
|
||||
this.fsmAnim && this.fsmAnim.onUpdate(dt);
|
||||
}
|
||||
|
||||
//普攻更新
|
||||
onAttackUpdate(dt:number){
|
||||
|
||||
this.fsmAnim.isAttack = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,18 +4,53 @@ import GFSMBase from "../../fsm/GFSMBase";
|
||||
import GFSMPVP from "../../fsm/PVP/GFSMPVP";
|
||||
import GPVPMode, { GPVPModePlayerEnum } from "../../../PVP/GPVPMode";
|
||||
import { GTactical } from "../../../entity/GTactical";
|
||||
import { GFSMBattleAmin } from "../../fsm/base/GFSMBattle/GFSMBattleAmin";
|
||||
import { JNFrameInfo } from "../../../../../../extensions/ngame/assets/ngame/sync/frame/JNSyncFrame";
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
export interface GDemoMessage{
|
||||
isAttack?:boolean;
|
||||
isRun?:boolean;
|
||||
}
|
||||
|
||||
//PVP 角色
|
||||
@ccclass('GRolePVPEntity')
|
||||
export default class GRolePVPEntity extends GRoleBase<{}>{
|
||||
export default class GRolePVPEntity extends GRoleBase<GDemoMessage>{
|
||||
|
||||
//所属阵容
|
||||
ones:GPVPModePlayerEnum;
|
||||
_ones:GPVPModePlayerEnum;
|
||||
|
||||
get ones():GPVPModePlayerEnum{
|
||||
return this._ones;
|
||||
}
|
||||
set ones(value:GPVPModePlayerEnum){
|
||||
//如果是敌方则设置镜像
|
||||
if(value == GPVPModePlayerEnum.ENEMY){
|
||||
this.isMirror = true;
|
||||
}else{
|
||||
this.isMirror = false;
|
||||
}
|
||||
this._ones = value;
|
||||
}
|
||||
|
||||
//攻击距离
|
||||
|
||||
//在阵容中的下标
|
||||
tacticalIndex:number;
|
||||
tactical:GTactical;
|
||||
|
||||
getClassName():string{return "GDemoMessage"}
|
||||
onSyncUpdate(dt: number,frame:JNFrameInfo, input?: GDemoMessage) {
|
||||
super.onSyncUpdate(dt,frame,input);
|
||||
if(input){
|
||||
if(Object.prototype.hasOwnProperty.call(input,"isAttack")){
|
||||
this.fsmAnim.isAttack = input.isAttack;
|
||||
}
|
||||
if(Object.prototype.hasOwnProperty.call(input,"isRun")){
|
||||
this.fsmAnim.isMove = input.isRun;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
get mode():GPVPMode{
|
||||
@ -25,9 +60,13 @@ export default class GRolePVPEntity extends GRoleBase<{}>{
|
||||
this._mode = value;
|
||||
}
|
||||
|
||||
protected fsmCreate(): GFSMBase {
|
||||
protected fsmCreate(): GFSMPVP {
|
||||
return null;
|
||||
return new GFSMPVP(this);
|
||||
}
|
||||
protected fsmAnimCreate(): GFSMBattleAmin {
|
||||
return new GFSMBattleAmin(this.spine);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
import { _decorator, Component, Label, Node } from 'cc';
|
||||
import { app, JNGLayerBase } from '../../App';
|
||||
import { director } from 'cc';
|
||||
import GRolePVPEntity from '../../battle/base/role/PVP/GRolePVPEntity';
|
||||
import { Toggle } from 'cc';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass('HomeView')
|
||||
@ -12,6 +15,21 @@ export class HomeView extends JNGLayerBase {
|
||||
this.frameText.string = `当前帧数: ${app.sync.frame}`;
|
||||
}
|
||||
|
||||
//设置移动
|
||||
setRoleMove(data:Toggle){
|
||||
console.log("移动",data.isChecked);
|
||||
director.getScene().getComponentsInChildren(GRolePVPEntity).forEach((role) => {
|
||||
role.input.isRun = data.isChecked;
|
||||
})
|
||||
}
|
||||
//设置攻击
|
||||
setRoleAttack(data){
|
||||
console.log("攻击",data.isChecked);
|
||||
director.getScene().getComponentsInChildren(GRolePVPEntity).forEach((role) => {
|
||||
role.input.isAttack = data.isChecked;
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user