egret-labs / egret-core

Egret is a brand new open mobile game and application engine which allows you to quickly build mobile games and apps on Android,iOS and Windows.
http://www.egret.com
Other
3.91k stars 795 forks source link

9102年都快过了,你们还在坚持 2014 年的构建方式 #362

Closed TripleTre closed 4 years ago

TripleTre commented 5 years ago

不错的,小学生们 ~

9102 年了,还不支持模块化。

nofastfat commented 5 years ago

你说的模块化是指编译or开发?

如果是编译的话,不要拿做web那一套来衡量游戏框架。诸如react、vue等等等再多框架开发如何如何高级、虚拟dom、实时编译....都是然并卵,最终呈现给用户的依旧是html/js/css,用户感知的是你产品的UI、UE和功能。

做游戏,重点考虑的是游戏的游戏性、性能和稳定性。

如果是指模块化开发,而在这吐槽的话,我只能说那是你们团队的主程太次。

另外,egret是有自定义模块这个功能的。举个栗子,基于这个是完全可以做到棋牌游戏模块化开发,各个游戏独立开发、独立编译,最终统一整合,我们目前就是这样做的-_-#

TripleTre commented 5 years ago

噢 ~ 原来你们目标就是棋牌游戏咯

nofastfat commented 5 years ago

你们难道连举一反三都不会?

主程真的是次

或者说,你就是来无脑吐槽的,而不是关注技术,

bw,这是github,不是bbs,别来丢人

Char-Ten commented 4 years ago

的确有这个问题,先别说typescript,就连js的模块系统都已经完善起来了,而egret开发的时候声明class就是全局声明,只要我的ts文件在src里面,在Main.ts里面就可以访问到。这种设计,对于单人开发开可以,毕竟代码都是自己写的,哪个类在哪里清清楚楚。但是多人开发的话,就留下了隐患了,比如,你阅读到同事的代码里面调用了n多个类,然后这些类是从哪里来,你必须一个个ctrl+左键点击跳转到对应文件里面去。又比如,你和你同事同时开发两个不同的场景,然后合并分支的时候,你和你同事的同名类名声明冲突了,去解决这个冲突又得花费不少时间成本。再比如,在ts或者nodejs的模块系统里面,在文件任意区域声明的变量,都是局部变量,因此这个文件被其他文件引入之后,只要该变量没被暴露出去(比如只是为了临时处理点数据什么的),那么它一定会被gc回收。而在白鹭里面,一旦你在文件全局作用域上声明一个变量,那它真的就是全局变量,不管有没有使用都不会被gc回收,特别是那种长时间挂机类的游戏,一旦对这个认识不足,很容易造成内存泄漏或者内存浪费。 说这么多也不是吐槽或者撕逼什么的,就事论事而已,希望官方能够关注到这一问题。

nofastfat commented 4 years ago

1.ts里面是有module这个关键字的(我们项目就大量使用到了),目的就是为了防止js污染,多人开发情况下,必然是需要进行“包”分类的。这么好的东西不用,靠人肉去检测类是否重了,当然麻烦。

2.gc回收方面,我只能说,一个原则:“自己拉的屎,自己擦干净”,如果在一个class外面去定义一个全局变量都能引起内存泄露,那么事件监听怎么办?回调怎么办?引用怎么办?这是一个开发习惯问题,不注意后患无穷。 在一个ts文件的class外面去定义一个全局变量,我只能说,要么是非常特殊的需求,要么就是这个人的编码习惯欠佳。

bw,我不是官方人员,就是一个普通的主程,我对一起编码的兄弟要求比较严,有一套编码、协作规范,其中一个准则就是:“自己拉的屎,自己必须擦干净”,这是为项目好,也是为他们好。 编码习惯问题、手不干净导致的BUG千奇百怪,也见得太多,以上属经验之谈,话锋虽厉,但无怼人之意。

Char-Ten commented 4 years ago
  1. typescript的module我也用过,不过我不是在egret里面用,而是在webpack打包的webgl项目里面用到。例如,我简单写了两个着色器文件:test.fgm.glsl和test.vtx.glsl,然后怎么在typescript里使用呢?首先在类型.d.ts里面声明如下代码:
    declare module "*.glsl"{
    const glsl:string
    export default glsl
    } 

    这个代码表示,ts引入文件的后缀是.glsl时,把它当字符串处理。然后利用typescript的类型系统,你可以很方便地这样使用着色器:

    
    import fgmShaderCode from 'xxx/test.fgm.glsl';
    import vtxShaderCode from 'xxx/test.vtx.glsl';

//创建着色器程序 function createProgram( gl:WebGLRenderingContext, vertexSource:string, fragmentSource:string ):WebGLProgram{ const program = gl.createProgram(); const vtxShader = gl.createShader(gl.VERTEX_SHADER); const fgmShader = gl.createShader(gl.FRAGMENT_SHADER);

gl.shaderSource(vtxShader,vertexSource);
gl.compileShader(vtxShader);
gl.attachShader(program,vtxShader);

gl.shaderSource(fgmShader ,fragmentSource);
gl.compileShader(fgmShader );
gl.attachShader(program,fgmShader );

gl.linkProgram(program)
return program 

} createProgram(gl,vtxShaderCode,fgmShaderCode)

不然以egret3D的例子,你自定义shader的话,只能通过字符串拼接或者字符串模板实现,或者走网络请求获取文本。而借助webpack和typescript模块系统,你可以将glsl代码单独写成文件,然后直接打包进最终的js代码里面,特别是一些关键的绘制shader,只要js代码下载下来就可以直接跑。  

其次对module的运用就是对一些类或者第三方库缺乏.d.ts的时候自己手动声明。
![image](https://user-images.githubusercontent.com/17474452/67665249-535bf900-f9a4-11e9-91cd-1b9c16ca3c91.png)

因为有ts模块系统的存在,并不会出现多人开发跨文件变量同名报错的情况,因为每个文件都是一个自己的作用域。而我之前说的报错,指的是用git合并分支之后,因为egret检测到了两个同名的类导致项目跑不起来,并不是人肉检测。 

所以在正常的typescript这个module的运用也大多如此了,但听你这么一说,在egret多人开发里面反而是处处需要用到,先学习了。

2. 随意在类外面声明变量这个问题,在nodejs项目里也好,在普通webpack项目里也好,很常见,比如常见的单例模式:
```typescript
class Test{
     //to write sth.
}
export default new Test()

或者全局计数,除非引入且调用createUUID,其他任何地方都无法修改count。而且没有引入这个函数的地方,可以随意使用创建、声明、使用createUUID这个变量名。

let count:number = 0;
export function createUUID():string{
    count ++;
    return `${Date.now().toString(16)}-${count}`
}

这种从代码层面的约束,我觉得比开发人员之间的约定要强太多,毕竟项目组的开发人员人来人往的,哪天来一堆萌新,工期又紧。。。

WanderWang commented 4 years ago

感谢您的反馈 ! 我们已经在处理这个问题了 , https://www.npmjs.com/package/@egret/compiler 这里是我们正在进行中的一些工作,会在近期完成