人的记忆是有极限的,所以写博客记录一下。。。

最近开发的模拟经营类微信小游戏项目,同屏显示的精灵数太多,使用cocos creator开发性能有点差,所以不得不用Laya。

特地测试了一下:

cocos creator同屏(其实也不算全部同屏,算是大部分,因为引擎2.0版本以上已经去除了culling)数量在400+左右,其中400个精灵不停的切换父节点(因为3d游戏做成2d的需要改层级遮挡关系)在微信上运行IphoneX的FPS已经掉到30帧左右了,黑鲨1是60帧,IphoneX的FPS比黑鲨还低可能是ios处理js本来就比较慢的原因。

逻辑代码全部不变,全部转成了Laya之后,同屏700个精灵在微信上运行IphoneX的FPS是60帧,黑鲨也是60帧,再多点就没测试了,因为已经满足需求了。

所以就觉定用Laya了,使用的版本是2.1.1.1,在这之前已经使用过Laya开发了一款3D的小游戏,由于2D的UI界面比较少,所以踩的坑不多。这次的游戏是2D的,结果踩了一连串的坑。。。。。

首先吐槽一下可视化的UI编辑器,选中精灵按键盘的方向键是微调位置,但是我选中了层级窗口的节点,想按方向键上下切换节点,左右展开节点,但是每按一次方向键节点的位置就微调了1,这应该算是BUG吧,不知道为什么这么久还不修。。。

接下来是坑了:

1.很多情况下节点不填宽高默认auto是会出BUG的,比如坐标转换会出错,使用Dialog(这个组件比较特别,就算设置了宽高也会出现BUG,不知道是什么操作)如果创建了之后直接弹出(new Dialog().popup()),由于不能及时获取到宽高,弹窗位置不会居中,第二次弹出正常。要解决的话需要在构造函数设置一下宽高,有些弹窗还必须要再onAwake再设置一下宽高才能解决。

2.由于是从creator转过来的,所以锚点用习惯了anchor,然后坐标转换一直不对,悲剧了,折腾了一段时间之后断点进去看了函数实现发现Laya是用pivot的。。。。最后自己复制代码出来改装了一下:

/**局部坐标转换成全局坐标 应用锚点* @param {pos} 需要转换的局部坐标* @param {node} 局部坐标所在的容器* @param {toGlobalNode} 需要转换到的上级容器 (默认舞台)*/export function localToGlobalAR(pos:Point,node:Laya.Sprite,toGlobalNode?:Laya.Sprite){//坐标转换let point = new Point(pos.x,pos.y);toGlobalNode=toGlobalNode || Laya.stage;while (node && !node.destroyed){if (node==toGlobalNode)break ;//锚点偏移计算(优先anchor 其次pivot)if(node["anchorX"])node.pivotX = node["anchorX"] * node.width;if(node["anchorY"])node.pivotY = node["anchorY"] * node.height;point=node.toParentPoint(point);node=node.parent as Laya.Sprite;}return point;}/**全局坐标转换成局部坐标 应用锚点* @param {pos} 需要转换的全局坐标* @param {node} 需要转换到局部坐标所在的容器* @param {toGlobalNode} 全局坐标所在的上级容器 (默认舞台)*/export function globalToLocalAR(pos:Point,node:Laya.Sprite,toGlobalNode?:Laya.Sprite){let point=new Point(pos.x,pos.y);var list=[];toGlobalNode=toGlobalNode || Laya.stage;while (node && !node.destroyed){if (node==toGlobalNode)break ;list.push(node);node = node.parent as Laya.Sprite;};var i=list.length-1;while (i >=0){node=list[i];//锚点偏移计算(优先anchor 其次pivot)if(node["anchorX"])node.pivotX = node["anchorX"] * node.width;if(node["anchorY"])node.pivotY = node["anchorY"] * node.height;point=node.fromParentPoint(point);i--;}return point;}

3.接上面,容器的scale为0时 转换出来的坐标会是NaN

4.导入bmfont后必须要重启项目才能在UI编辑器中预览,而且在使用这个UI界面之前必须要先加载bmfont。

5.bmfont是不能直接设置fontSize的,需要在加载完成后加上bmFont.autoScaleSize = true。示例如下

let mBitmapFont = new Laya.BitmapFont();
这里不需要扩展名,外部保证fnt与png文件同名
mBitmapFont.loadFont(url, Laya.Handler.create(this, function (font: Laya.BitmapFont) {if (font) {var name = url.match(/\/(.*?).fnt/)[1];font.autoScaleSize = true;Laya.Text.registerBitmapFont(name, font);}cp.runWith(font);
}, [mBitmapFont]));

6.bmfont在UI编辑器中设置fontSize是无效的,我才发现原来Laya在UI编辑器使用bmfont的正确姿势是直接设置scale。。。

7.bmfont在微信小游戏上运行会报错,必须要把domparserinone.js库勾上。

8.把节点放到Panel下实现滚动效果,节点的parent并不是Panel,而是被嵌套了一层Box,获取Panel需要.parent.parent。

9.使用了scrollRect时候子节点位置会根据scrollRect的x,y来,坐标转换又来坑了。。

10.3D的Animator重新播放要填参数play(name,layer,0),normalizedTime填0;

11.一个Tween实例调用了clear之后,再调用一次clear会清掉别的Tween(这是巨坑,莫名其妙的)。

12.使用了布局需要注意HBox会根据x坐标排序,VBox会根据y坐标排序。(cocos是根据节点顺序zIndex排序)。

13.最后是粒子,粒子实现原理是创建了一个网格  所有粒子都是渲染到这个网格上的,粒子运动的运算是在shader上,默认发送出来的粒子是不会根据节点移动(拖尾效果),而且不能清空已经被激活的粒子(源码可能是我没看仔细,找不到)只能等待生命周期结束(使用对象池要注意的问题,避免从对象池取出来后还残留着上次的生命周期没结束的粒子,销毁需要延迟等待什么周期自行结束后才放到对象池延迟时间是particle.emitter["setting"].duration * 1000),想要清空就直接destroy掉。

想要移除拖尾效果(应该说是移除全局拖尾效果,只留局部拖尾,也就是所有粒子都相对于父节点的坐标系)就重写一下Particle2D的customRender和_particleTemplate对象的addParticleArray加上节点移动时跟原位置的偏移。代码如下:

//粒子静态跟随对象(不拖尾)
class CustomParticleStaticFollow extends Laya.Script {private staticFollowElement: Laya.Sprite;private srcX: number;private srcY: number;private oldX: number;private oldY: number;onUpdate() {let ele = this.getPointElement();if (ele.x !== this.oldX ||ele.y !== this.oldY) {let par = this.owner as CustomParticle2D;par.setOffset(ele.x - this.srcX, ele.y - this.srcY);this.oldX = ele.x;this.oldY = ele.y;}}setStaticFollowElement(ele: Laya.Sprite) {this.staticFollowElement = ele;ele = this.getPointElement();this.oldX = this.srcX = ele.x;this.oldY = this.srcY = ele.y;}getPointElement(): any {let rect = this.staticFollowElement.scrollRect;if (rect) return rect;else return this.staticFollowElement;}
}export class CustomParticle2D extends Laya.Particle2D {private offset: Laya.Point;/**静态跟随的对象 */private staticFollowElement: Laya.Sprite;constructor(setting: Laya.ParticleSetting) {super(setting);this.offset = new Laya.Point(0, 0);}/**自定义渲染 */customRender(context, x, y) {// this.transformthis["_matrix4"][0] = context._curMat.a;this["_matrix4"][1] = context._curMat.b;this["_matrix4"][4] = context._curMat.c;this["_matrix4"][5] = context._curMat.d;this["_matrix4"][12] = context._curMat.tx - this.offset.x;this["_matrix4"][13] = context._curMat.ty - this.offset.y;var sv = (this["_particleTemplate"]).sv;sv.u_mmat = this["_matrix4"];}/**绑定静态跟随的对象(绑定坐标会改变的节点,跟着偏移,不拖尾)*/bindStaticFollowElement(ele: Laya.Sprite) {//绑定静态跟随的对象let follow = (this.getComponent(CustomParticleStaticFollow) || this.addComponent(CustomParticleStaticFollow)) as CustomParticleStaticFollow;follow.setStaticFollowElement(ele);this.setOffset(0, 0);return this;}clearStaticFollowElement() {let com = this.getComponent(CustomParticleStaticFollow) as CustomParticleStaticFollow;com && com.destroy();this.setOffset(0, 0);}/**设置偏移 */setOffset(x: number, y: number) {this.offset.x = x;this.offset.y = y;}setParticleSetting(setting: Laya.ParticleSetting) {super.setParticleSetting(setting);//重定向粒子 生成坐标(加上偏移)let pt = this["_particleTemplate"];pt.taddParticleArray = pt.addParticleArray;pt.addParticleArray = function (position, velocity) {if (this.posot) {position[0] += this.posot.x;position[1] += this.posot.y;}this.taddParticleArray(position, velocity);}pt.posot = this.offset;}
}

使用方法是:

let setting = new Laya.ParticleSetting();setting.textureName = "texture.png";//必须要设置一张图片 不然会报错let par = new CustomParticle2D(setting);
par.load(url);
par.bindStaticFollowElement(map.owner.parent);

[开发笔记] LayaAir-踩坑相关推荐

  1. HBase眼高手低从Shell到IDEA编程、心路笔记、踩坑过程

    HBase眼高手低从Shell到IDEA编程.心路笔记.踩坑过程 HBase眼高手低 通过shell操作Hbase Foundation 在terminal中输入hbase,就可以查看hbase命令的 ...

  2. 我的物联网开发入门和踩坑历程

    我的M5Stack物联网开发入门和踩坑历程:基于M5STACK和ONENET 开发准备 M5STACK简介 环境配置 UIflow环境 ESP-IDF环境 方法一 方法二(更推荐) 感知模块 网络连接 ...

  3. Slam学习笔记——ROS踩坑记录

    Slam学习笔记--ROS踩坑记录 1. 安装 2. ROS文件系统 2.1 工作区 2.2 包package 2.2.1 包的操作 2.2.2 描述文件package.xml 2.3 节点node ...

  4. Android SDK 开发——发布使用踩坑之路

    前言 在 Android 开发过程中,有些功能是通用的,或者是多个业务方都需要使用的. 为了统一功能逻辑及避免重复开发,因此将该功能开发成一个 SDK 是相当有必要的. 背景 刚好最近自己遇到了类似需 ...

  5. uniapp开发聊天APP踩坑记录

    最近工作重心转移到了uniapp上,有一说一,这个框架跨端确实牛逼,一套代码能一次编译到多端使用.但随之而来的兼容性问题也是层出不穷,同样的在面临APP底层的改动也显得力不从心.同时,uniapp的性 ...

  6. 高德地图开发-常用api踩坑使用

    一.高德地图的加载初始化 在这就踩过很多坑,新建项目正常显示没问题,放到我们的项目就是不显示,加载不出来, 这个时候不要慌,只要确保下面三部完成就莫问题了 1.引入高德地图开发者api <scr ...

  7. Could not resolve all files for configuration “: app: debug Compileclasspath“ mac开发 cordova build踩坑

    作为小白第一次开发android,想到会踩坑,没想到这么多.话不多说直接上主题,在做基于ionic + cordova安卓开发时遇到了一个打包的问题,如下图. Could not resolve al ...

  8. react开发公众号踩坑日志

    最近在用react开发一个公众号产品.以前没有过开发公众号的经验,在这里记录一下过程中踩过的坑. 这个项目是前后端开发的.本篇文章只站在前端的视角,希望给大家一个参考 一.授权回调 微信授权过程 进入 ...

  9. 开源大数据开发平台DataSphereStudioLinkis踩坑记录

    Linkis:https://github.com/WeBankFinTech/Linkis DataSphereStudio:https://github.com/WeBankFinTech/Dat ...

  10. uni-app开发,防止踩坑

    一.组件设置全屏覆盖 设置宽度和高度100%是没用的 需要在里面加设置一层view,并且设置对应宽高分别为vw和vh <uni-popup><view class="wra ...

最新文章

  1. Spring Data JPA 五分钟快速入门和实践
  2. WinForm 读写配置文件
  3. CSS 布局与“仓库管理”的关系
  4. 亚信联创java面试题_亚信联创面试题及答案
  5. python 整数输出 d f_如何将数字(10,11,12,13,14,15)分配给Python 3中的字母(A,B,C,D,E,F)?...
  6. bme280 环境传感器开发板_半导体所在柔性湿度传感器与非接触控制方面取得进展...
  7. 为Android安装BusyBox
  8. 【CV实战】Ubuntu18.04源码编译安装opencv-3.4.X+测试demo
  9. 【Spark】Spark 2.4 Stream 读取kafka 写入kafka
  10. autobench 快速入门
  11. fckeditor代码总结
  12. wh计算公式_电池的wh和mah怎么换算?
  13. 惠普打印机双击之后没有扫描_惠普打印机 找不到 扫描图标 怎么办,急需扫描一些证件 ,求救...
  14. Python 使用乐动体育的 backoff 更优雅的实现轮询
  15. 武魂java_jdk及tomcat的安装
  16. Angular NgModule
  17. ubuntu下.chm文档查看工具
  18. 《数据库系统原理》教学上机实验报告
  19. 基于Master-DistributedMaster-Slave架构的replication
  20. 《LCD总结篇(中级)》

热门文章

  1. syslog Linux系统log打印原理
  2. 电容基础知识简介--作用、参数和类型
  3. python3学习(3):ID 遍历爬虫
  4. 使用多种格式转换方法将MKV转成GIF
  5. windows Tasklist命令详解
  6. [附源码]JAVA毕业设计教学质量评价系统(系统+LW)
  7. 单片机PWM舵机控制
  8. html5+javascript+css实现---网页版坦克大战---无需运行环境
  9. web端拨打电话、发送短信
  10. apple mobile 2 PC