文档 v1.0

来自泡泡
Liuweichen留言 | 贡献2024年7月22日 (一) 02:57的版本 →‎编译

首次启动运行游戏

Demo资源下载

运行环境配置

vscode编辑器

- [vscode官网](https://code.visualstudio.com/)

 - 点击Download,找到对应系统的安装包,一直点击确定安装完成。  
 

node 版本 v10.24.1

- 必须使用指定的nodejs版本,推荐安装nvm以自由转换node版本。

 - [nvm下载及安装方式](https://blog.csdn.net/ppz8823/article/details/130862191)  
 - 安装nvm后,运行如下命令切换到node版本v10.24.1:  
  
    nvm install 10.24.1  
    nvm use 10.24.1  
    

修改host文件

- 找到host文件,一般在`C:\WINDOWS\system32\drivers\etc`目录下。 - 在文件末尾添加:

  
  199.232.68.133 raw.githubusercontent.com  
  

laya 版本 v2.13.1

- [laya官方ide](https://ldc2.layabox.com/layadownload/?type=layaairide-LayaAir%20IDE%202.13.1)

安装laya的cmd命令库

- 推荐安装方式:

  
  npm i -g cnpm@6.1.0  
  cnpm config set registry https://registry.npmmirror.com  
  cnpm i layaair2-cmd -g  
  

如何运行游戏

安装依赖

- 在demo目录下安装相关依赖:

 - 打开demo目录文件夹,运行:  
  
    npm i  
    
 - **注意**:如果安装失败,检查host文件是否修改,并尝试删除`node_modules`目录后重新运行命令。此操作只需进行一次。  
 

编译

- 每次有代码修改后,运行前需调用命令进行编译:

  
  npm run build  
  
 

运行

- 每次编译完成后,使用VSCODE运行调试,或按键F5启动游戏。

 - **注意**:不需要打开laya的IDE环境,直接用VSCode调试即可。  
   
 

登录界面

- 运行后,浏览器将显示登陆界面。

   
 - 输入账号密码后,选择指定地图(可选),即可看到战斗服务器世界中有自己的人物。

前端基础逻辑

根据以下步骤,一步步进入泡泡的游戏世界,即使你是新手也无需担心。

前端游戏入口

- /src/client/index.ts 文件中的 `XPopManager.onGameStart` 是前端的主要入口点。

创建第一个人物

在 `simpleGame` 类中,我们将创建并初始化第一个游戏人物。

  
export class simpleGame {  
    private firstModel: XModelHero;  
  
    constructor() {  
        // 创建第一个人物  
        this.firstModel = new XModelHero();  
        let path = 'role/model_avatar_body_default';  
  
        // 加载人物模型并播放动画  
        this.firstModel.loadModel(path, null, this, (success) => {  
            // 播放跑步动画  
            let actName = "act_avatar_base_run";  
            this.firstModel.playAniUp(`${actName}_up`);  
            this.firstModel.playAniDown(`${actName}_down`);  
  
            // 摄像机跟随  
            let camera = XPopManager.instance.xScene.camera;  
            camera.focus = this.firstModel;  
  
            // 定时更新人物位置  
            XTimer.loop(100, this, this.updateModelPos.bind(this));  
        });  
    }  
  
    updateModelPos(delta: number, frame?: string) {  
        // 更新人物位置  
        this.firstModel.position.x += 0.1;  
    }  
}  
  
// 设置游戏启动时执行  
XPopManager.onGameStart = () => {  
    new simpleGame();  
}  
    • 注意**:请将原代码中的 `new Main(),` 替换为 `new simpleGame();` 并重新编译运行。

UI界面开发

在编辑器中创建UI

打开Laya工程

使用指定版本的Laya编辑器打开 `demo/ui_laya/ui_laya.laya` 项目。

添加.scene界面

在编辑器中,可以添加一个新的scene界面,并在其上放置UI元素。

界面添加UI组件

例如,添加一个名为 `btnFirst` 的按钮,并确保其 `var` 属性有值,以便后续导出。

运行生成UI命令

在命令行中运行以下命令来生成UI代码:

  
npm run ui  

运行成功后,生成的UI类将位于 `src/ui/popxMaxUI.ts` 文件中,包含有值的UI组件的导出。

代码控制XUIComponent

注册UI类的控制文件

使用 `PopxBridge.regUIClass()` 方法在相应的类中注册UI类,并处理UI相关的按键逻辑。

代码调用显示UI

通过 `xUiManager.instance.openUI()` 方法来调用并显示UI界面。

前后端数据交互

该篇会讲述服务器和前端的数据同步,如果想要先了解项目目录和工作流,建议先参考如下篇幅 #主要工程目录

进入房间(游戏世界)

如下是最基本的开发登录流程说明

步骤 描述 流向
开始 流程的开始 -> 登录页面
登录页面 账号密码,选定地图,输入房间号(可不填) -> 远端服务器(官方)
远端服务器(官方) 获取玩家账户信息,分配到房间,房间就是我们的host代码 -> Client 和 -> Host
Client 监听XPopManager.onGameStart -> 前端逻辑开始
Host 监听XPopManager.onHostStart -> 房间战斗逻辑开始

远端服务器(官方)会处理最基本的登录,分配房间,创建游戏世界的逻辑,并且同步该世界中的游戏数据。

通过XpopManager管理类,来向Client和Host抛出事件,开发者可以监听这些事件做处理。

开发者需要关心的逻辑,就是Clint和Server(上图中Host)目录下的代码。


前后端协议交互

项目采用proto来做相互通信,建议参考如下篇幅 #npm run proto(协议通信)

前后端共用配置

前端src/client目录和后端src/server目录中,都可以调用如下代码来加载所有的表格配置

   CsvManager.ins.loadCsvs(this, () => {
     // Do some thing after load
   });

表格的加载逻辑和解析逻辑,可以参考CsvManager中的代码 src/shared/csv/CsvManager.ts


如何新增配置? 以demo中的item.csv为例.

  • 1.配置csv文件资源的根目录为res-extra/csv/ ,在里面添加item.csv
  • 2.CsvManager.ts文件中,添加读取表格和解析表格的逻辑
    // loadCsvs代码中,添加你需要解析的csv名称
    public loadCsvs(caller: any = null, listener: Function = null) {
        let assets = [
            this._prefix + "item.csv",
        ];
        // XResManager加载本地资源
        XResManager.instance.loadText(assets, () => {
            // 在加载完成的回调中,处理表格数据结构,生成CItemData,不再赘述
            this.onCompleted(caller, listener);
        });
    }
  • 3.解析表格得到的CItemData结构,定义在src/shared/dataMgr/中,可以被前后端一起调用

玩家战斗数据快照

游戏战斗服务器中,每个玩家的实时信息,通过快照来更新

XVF_SnapData

以demo中的Snap_UserData.ts为例

  • 该玩家数据中类中,包含的各种public变量,都是XVF_SnapData接口类型
export class Snap_UserData {
    //坐标旋转
    public position: XVF_SnapData<SyncPos>;
    //状态
    public state: XVF_SnapData<SyncState>;
    //hp
    public hp: XVF_SnapData<number>;
}

快照数据前端监听,服务器修改

  • 每次该接口类型的数据发生变化时,会调用OnSet方法,这类数据的修改逻辑是:服务器修改,前端监听变化
    • 前端登录成功后,服务器注册对应玩家数据
    • 前端对数据中的某个XVF_SnapData做监听,注册OnSet方法
    • 服务器战斗逻辑修改了该数据时,前端根据OnSet的逻辑做表现处理
  • XVF_SnapData数据,如果是复杂类型,需要调用UpdateData()方法,前端才能触发OnSet

如下的SyncState就是复杂类型

    public state: XVF_SnapData<SyncState>;
    public setState(key:string, obj:string):void{
        this.state.value.key = key;
        this.state.value.obj = obj;
        this.state.UpdateData();
    }
  • XVF_SnapData如果是基础类型,不需要调用UpdateData()
    public hp: XVF_SnapData<number>;
    public setHP(hp:number):void {
        this.hp.value = hp;
    }

项目目录和命令

主要工程目录

对于开发者,需要关心和操作的目录如下:

  • node_modules/ - 通过npm安装的PGT库文件,对外暴露的方法,可以通过bridge.d.ts来外部引用
  • res-extra/ - 开发者除了PGT的远程资源外,需要额外使用到的资源目录,比如UI,图片,音频,表格,最后会打包上传到PGT远端资源服务器
  • ui/ - 开发者自己在laya编辑器中,拼接的界面json文件,运行命令后,会转化为PGT指定的XUIComponent存放于此
  • src/ - 开发者所有的战斗逻辑代码修改都在此进行
 * src/client/ - 前端代码,入口文件index.ts,监听XPopManager.onGameStart,前端游戏逻辑  
 * src/server/ - 后端代码,入口文件index.ts,监听XPopManager.onHostStart,后端游戏逻辑  
 * src/shared/ - 前后端共用的数据结构,包括表格,协议,玩家数据
  • dist/ - 编译后,生成的运行文件,包含前后端代码
 * dist/client/ - 编译后生成的混淆的前端代码  
 * dist/host/ - 编译后服务端的代码文件,里面也包括表格数据的缓存

npm命令说明

以下是项目中常用的命令,和工作流相关,先简要说明用法,后续工作流中会继续补充。

npm run proto(协议通信)

该命令会用到tsrpc的proto协议, 把src/shared/protocols下的指定格式文件, 转换到src/shared/protocols/generated/serviceProto文件中,

  • 文件名为:Ptl{接口名}.ts (Ptl 是 Protocol 的缩写,l是小写的L)
  • 请求类型名为: Req{接口名},通过 interface 或 type 定义,需 export
  • 响应类型名为:Res{接口名},通过 interface 或 type 定义,需 export

例如,添加PtlPosition.ts文件 文件代码如下

  
// 该接口用于向服务器同步自身的坐标  
export interface ReqPosition {  
    i: number;  
    x: number;  
    y: number;  
    z: number;  
    ry: number;  
}  
export interface ResPosition {  
    ret: string;  
    diy: string;  
}  

在demo目录下运行 npm run proto后, serviceProto.ts中会增加可外部调用的api类型

  
export interface ServiceType {  
    api: {  
        "Position": {  
            req: ReqPosition,  
            res: ResPosition  
        },  
    },  
    msg: {  
  
    }  
}  

前端代码调用请求

// 前端可以用promise语法来调用同步位置的Request,异步处理服务器的返回值
   let remote = XPopManager.instance.xRemote;
   let ret = await remote.Request('Position', {i: 1, x:2, y:3, z:4, ry:5});
   if(ret && ret.isSucc){
       console.log(ret.res.diy)
   }

后端代码监听请求处理返回

// 服务器收到前端请求的处理返回RegisterRpc
      let host = XPopManager.instance.xHost;
      //当收到坐标变化请求
      host.RegisterRpc("Position", async (call: ApiCall<ReqPosition, ResPosition>) => {
      let index = call.req.i;
      let userData = this.usersData.get(index);
      userData.setPosition(call.req.x, call.req.y, call.req.z, call.req.ry);
      return call.succ({
       ret: "Success",
       diy: "自定义参数"
     });
   });

如果想更多了解proto的结构和数据类型说明,可以参考官方链接 [tsrpc-proto格式说明](https://tsrpc.cn/docs/server/service-proto.html)

npm run build ( 编译构建 )

每次代码有修改时,如果要调试运行,必须先运行此命令

运行后,会在dist目录下生成混淆过后的可执行代码

此时VSCode编辑器可以直接F5运行

npm run ui ( 生成ui类 )

如果开发者有额外的ui交互需求,希望在IDE中自己拼接UI 可以在指定目录下,

  • ui_laya/laya/ - 开发者可以自由扩展的ui资源目录
 * ui_laya/laya/pages - 开发者创建的.scene文件目录
 * ui_laya/laya/assets/uiextra - secne文件中引用到的各种美术资源,包括音频和动画

运行后,会在client目录代码中,生成对应的XUIComponent类,#XUIComponent

npm run server ( 启动本地host服务 )

启动一个本地host服务器, 局域网内其他用户在登录时输入你的房间号,就可以链接到你的本地游戏一起调试

npm run publish ( 打包文件 )

npm run upload( 上传文件 )

核心类目说明

XPopManager

XModel

[公共模型的路径集合](https://h5ppreview.jumpw.com/popion/web/v1.0.1729/version.json)

XUIComponent

地图的制作

地图官网地址

[地图网页](https://h5ppreview.jumpw.com/pgc/pgcedit0.0.2/index.html)

地图制作导出

在项目目录/地图编辑器操作说明中,有视频教程

地图测试权限申请

[论坛帖子](https://pgcbbs.popx.com/d/49-di-tu-shang-chuan-he-wan-fa-ce-shi-lin-shi-fang-an)

官方论坛

[论坛地址](https://pgcbbs.popx.com/)