From 5653ff7ff688a24cf7bf1e66a0d53e6b960f7af5 Mon Sep 17 00:00:00 2001 From: zhandouxiaojiji Date: Thu, 5 Nov 2020 21:22:14 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=BB=BA=E8=A1=8C=E4=B8=BA=E6=A0=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 23 ++++++++++++++++------- common/MainEventType.ts | 1 + common/Utils.ts | 19 ++++++++++++++++++- main-process/AppMenu.ts | 20 ++++++++++++++++++++ main-process/Settings.ts | 3 +-- render-process/Properties.tsx | 8 ++++++++ sample/workdir/test.json | 8 ++++++++ sample/workspace.json | 2 +- 8 files changed, 73 insertions(+), 11 deletions(-) create mode 100644 sample/workdir/test.json diff --git a/README.md b/README.md index 666f494..e42661d 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,6 @@ 这是一个直观、可视化的行为树编辑器,行为树的保存格式为json,可以让策划自行去实现AI,技能,buff等复杂的游戏逻辑,从而减少不必要的沟通成本和提升开发效率。 ![](readme/preview.png) -## 技术栈 -+ react + ts -+ g6 -+ antd -+ electron - ## 使用方法 + 打开编辑器 + 工作区->节点定义->选择文件(json) @@ -37,13 +31,28 @@ interface BehaviorNodeTypeModel { doc?: string; //文档说明(markdown格式) } ``` +节点定义也是json格式,参照[sample/node-config.json](sample/node-config.json),编辑器不提供节点定义的编辑,强烈建议节点定义文件由代码生成。 + +## 编译与构建 +```shell +npm install # 安装依赖 +npm start # 运行测试 +npm run build # 编译exe可执行文件 +``` + +## 技术栈 ++ react + ts ++ g6 ++ antd ++ electron ## TODO + 复制粘贴功能(跨工作区) + 历史记录(撤销/恢复) + 资源面板支持树型结构 + 快捷键功能 ++ 右键菜单 + 联调功能 ## About -目前编辑器还处于非常简陋的阶段,本项目将长期维护,望前端大佬们多提点~ \ No newline at end of file +目前编辑器还处于非常简陋的阶段,有问题可以联系作者(QQ1013299930),本项目将长期维护,望前端大佬们多提点~ \ No newline at end of file diff --git a/common/MainEventType.ts b/common/MainEventType.ts index 21aff39..24a58a2 100644 --- a/common/MainEventType.ts +++ b/common/MainEventType.ts @@ -2,6 +2,7 @@ export default { OPEN_FILE: "OPEN_FILE", OPEN_DIR: "OPEN_DIR", OPEN_WORKSPACE: "OPEN_WORKSPACE", + CREATE_TREE: 'CREATE_TREE', CREATE_NODE: 'CREATE_NODE', SAVE: 'SAVE', SAVE_ALL: 'SAVE_ALL', diff --git a/common/Utils.ts b/common/Utils.ts index e52d89f..4edc9d2 100644 --- a/common/Utils.ts +++ b/common/Utils.ts @@ -1,7 +1,8 @@ import { TreeGraphData } from "@antv/g6/lib/types" -import { BehaviorNodeModel, GraphNodeModel } from "./BehaviorTreeModel"; +import { BehaviorNodeModel, BehaviorTreeModel, GraphNodeModel } from "./BehaviorTreeModel"; import Settings from "../main-process/Settings"; import { remote } from "electron"; +import * as path from 'path'; export const cloneNodeData = (nodeData: GraphNodeModel) => { const newData: GraphNodeModel = { @@ -111,4 +112,20 @@ export const findFromAllChildren = (node: TreeGraphData, id: string): TreeGraphD export const getRemoteSettings = () => { return remote.getGlobal("settings") as Settings; +} + +export const fileName2treeName = (filename: string) => { + return path.basename(filename).slice(0, -5); +} + +export const createNewTree = (filename: string) => { + const tree: BehaviorTreeModel = { + name: fileName2treeName(filename), + root: { + id: 1, + name: 'Sequence', + desc: '新建行为树' + } + } + return tree; } \ No newline at end of file diff --git a/main-process/AppMenu.ts b/main-process/AppMenu.ts index 28b5280..0a53570 100644 --- a/main-process/AppMenu.ts +++ b/main-process/AppMenu.ts @@ -1,4 +1,6 @@ import { Menu, app, dialog, BrowserWindow, MenuItem, WebContents, MenuItemConstructorOptions } from 'electron'; +import * as fs from 'fs'; +import * as Utils from '../common/Utils'; import MainEventType from '../common/MainEventType'; import { MainProcess } from './MainProcess'; import Settings from './Settings'; @@ -40,6 +42,24 @@ export default class AppMenu { return new MenuItem({ label: "行为树", submenu: [ + { + label: "新建", + click: () => { + (async () => { + const res = await dialog.showSaveDialog({ + properties: ['showOverwriteConfirmation'], + filters: [ + { name: "Json", extensions: ['json'] } + ] + }); + if (!res.canceled) { + const path = res.filePath; + fs.writeFileSync(path, JSON.stringify(Utils.createNewTree(path), null, 2)); + this.webContents.send(MainEventType.CREATE_TREE, path); + } + })(); + }, + }, { label: "打开文件", accelerator: "Ctrl+O", diff --git a/main-process/Settings.ts b/main-process/Settings.ts index e6c967f..20fa839 100644 --- a/main-process/Settings.ts +++ b/main-process/Settings.ts @@ -22,7 +22,6 @@ const sampleNodeClassify: BehaviorNodeClassify[] = [ ] - export default class Settings { private settings: SettingsModel; curWorkspace?: Workspace; @@ -61,7 +60,7 @@ export default class Settings { this.settings = JSON.parse(str); } else { this.settings = { - recentWorkspaces: [], + recentWorkspaces: ['sample/workspace.json'], recentFiles: [], nodeClassify: sampleNodeClassify, }; diff --git a/render-process/Properties.tsx b/render-process/Properties.tsx index 29e39b4..fff908f 100644 --- a/render-process/Properties.tsx +++ b/render-process/Properties.tsx @@ -2,6 +2,8 @@ import React, { Component } from "react"; import { Menu, Input } from "antd"; import * as fs from 'fs'; import * as path from 'path'; +import { ipcRenderer } from "electron"; +import MainEventType from "../common/MainEventType"; const { Search } = Input; @@ -33,6 +35,12 @@ export default class Properties extends Component { } componentDidMount() { + ipcRenderer.on(MainEventType.CREATE_TREE, (event: any, path: string) => { + console.log("on Create tree", path); + this.props.onOpenTree(path); + this.forceUpdate(); + }); + var workspace = this.props.workspace; if (workspace == '') { return; diff --git a/sample/workdir/test.json b/sample/workdir/test.json new file mode 100644 index 0000000..8c00b21 --- /dev/null +++ b/sample/workdir/test.json @@ -0,0 +1,8 @@ +{ + "name": "test", + "root": { + "id": 1, + "name": "Sequence", + "desc": "新建行为树" + } +} \ No newline at end of file diff --git a/sample/workspace.json b/sample/workspace.json index db61182..0c685fe 100644 --- a/sample/workspace.json +++ b/sample/workspace.json @@ -1,4 +1,4 @@ { "nodeConfPath": "sample\\node-config.json", - "workdir": "sample\\workdir" + "workdir": "E:\\code\\behavior3editor\\sample\\workdir" } \ No newline at end of file