目录
7.类似于android的eventbus发送事件(区别:注册是发送者要做的)
白鹭学习文档:http://edn.egret.com/cn/docs/page/579
白鹭引擎开发微信小游戏API:http://developer.egret.com/cn/apidoc/index/name/egret.HttpRequest#example
自己刚用微信开发者工具开发小游戏。遇到3个麻烦的问题:
1.屏幕各处的场景需要点击事件,但是微信小游戏只有屏幕点击事件,所以只能算出各处场景的上下左右边框,判断触屏的点是否在4个框组成的矩形内
2.画布上面又盖了一层画布,上层的点击事件会穿透到下层的点击事件,就是点击触发多事件
3.列表展示数据,往上滑动查看更多,像前端的listview或者scrollview等,自己实现很麻烦。
转到白鹭开发,用工具Egret Wing,会方便很多,听人家说,基本也发现不了微信小游戏和引擎开发出游戏的运行大区别。
我是先学的小例子 才看的这篇:小例子链接:https://blog.csdn.net/qq_37321098/article/details/84334672
知识收集:
1.资源文件导入
default.res.json文件,用记事本打开,按格式导入图片,但是未显示在资源组中,使用不了。
先添加:
{
"url": "assets/CheckBox/checkbox_select_up.png",
"type": "image",
"name": "checkbox_select_up_png"
}
再到组里面添加:
"groups": [
{
"keys": "checkbox_select_up_png",
"name": "preload"
}
]
2.this.addChild(circle2)
对对象再次调用this.addChild(circle2);会将被遮盖的circle2对象拿到层级列表顶层
3.层级关系
4.多次添加显示对象到显示列表
同一个显示对象无论被代码加入显示列表多少次,在屏幕上只绘制一次。如果一个显示对象A被添加到了B这个容器中,然后A又被添加到了C容器中。那么在第二次执行 C.addChild(A) 的时候,A自动的从B容器中被删除,然后添加到C容器中。
5.删除操作的注意点
当我们想要删除一个显示对象的时候需要执行的操作是:容器对象.removeChild( 显示对象 );
但执行这个删除操作,我们的“显示对象”必须拥有父级。换句话说,被删除的显示对象必须存在于显示列表当中。
如果当前删除显示对象不在显示列表之中,那么在JavaScript控制台中你将看见报错信息:
Uncaught Error: [Fatal]child未被addChild到该parent:
删除前做判断:
f( spr.parent ){spr.parent.removeChild( spr );}
6.容器深度相关
1) 容器现容纳个数:
容器.numChildren (但是第一位容纳对象下标为0)
2) 插队:
容器.addChildAt( 显示对象, 深度值 )
3) 消除
容器.removeChild( 显示对象 )
容器.removeChildAt( 深度值 ) 来删除一个指定深度的显示对象
4)交换深度
交换不同的深度:容器.swapChildren( 显示对象, 显示对象 ) 和 容器.swapChildrenAt( 深度值, 深度值 )
5)设置深度(自带容错,深度值无Max值)
手动设置物体的深度:容器.setChildIndex( 显示对象, 新的深度值 );
6)获取容器子对象
通过深度获取子对象:容器.getChildAt( 深度值 );
通过name获取子对象:先给子对象设置spr2.name = "sprite2";再控制:
var _spr:egret.DisplayObject = sprcon.getChildByName( "sprite2" );
_spr.alpha = 0.5;
7.类似于android的eventbus发送事件(区别:注册是发送者要做的)
数据的监听类型:DateEvent.DATE
事件的注册,发送,移除:
http://edn.egret.com/cn/docs/page/113
事件的接收:
http://edn.egret.com/cn/docs/page/114
使用步骤:
先创建实体类:Event类继承自egret.Event
接收地方:listenerName(evt:Event):void {...}
注册:事件发送者.addEventListener(事件类型, 侦听器, this);
发送:this.dispatchEvent(daterEvent);
移除:事件发送者.removeEventListener(事件类型, 侦听器, this);
检测某一个事件发送者是否注册了侦听器:hasEventListener
或者 willTrigger
事件发送者.hasEventListener(事件类型);(
被注册过,返回 true)
8.是否接收触摸
如果某些显示对象不再需要侦听TouchEvent,那就及时关闭吧:
显示对象实例.touchEnabled = false;
9.事件优先级
制定事件的优先级来确保那个事件侦听器会得到提前处理。可以在注册侦听器的时候制定事件的优先级。
public addEventListener(type:string, listener:Function, thisObject:any, useCapture:boolean = false, priority:number = 0)
当数字越大,则优先级越大。在触发事件的时候优先级越高。
10.获取资源的几种方式
- RES.getRes(name:string):any
同步获取资源 这种方式只能获取已经缓存过的资源,例如之前调用过loadGroup()被预加载的资源。
- RES.getResAsync(name:string,compFunc:Function,thisObject:any):void
异步获取资源,这种方式可以获取配置中含有的所有资源项。如果缓存中存在,直接调用回调函数返回,若不存在,就启动网络加载文件并解析后回调。
- RES.getResByUrl(url:string,compFunc:Function,thisObject:any,type:string=””):void
通过url获取不在配置中的资源,通常不建议使用这个接口,只有那些不合适填写在配置中,比如获取网络上其他服务器的资源时,才采用这种方式。
直接读取的demo:
private onAddToStage(event:egret.Event) {
RES.getResByUrl('/resource/assets/bg.jpg',this.onComplete,this,RES.ResourceItem.TYPE_IMAGE);
}
private onComplete(event:any):void {
var img: egret.Texture = <egret.Texture>event;
var bitmap: egret.Bitmap = new egret.Bitmap(img);
this.addChild(bitmap);
}
11.绘制图
1)加载完绘制
private onAddToStage(event:egret.Event) {
RES.addEventListener(RES.ResourceEvent.GROUP_COMPLETE, this.onGroupComplete, this);
RES.loadConfig("resource/default.res.json", "resource/");
RES.loadGroup("preload");
}
private onGroupComplete()
{
var img:egret.Bitmap = new egret.Bitmap();
img.texture = RES.getRes("bgImage");
this.addChild(img);
}
2)九宫格中心延伸图
var img:egret.Bitmap = new egret.Bitmap();
img.texture = RES.getRes("box");
img.width *= 2;
this.addChild(img);
var img2:egret.Bitmap = new egret.Bitmap();
img2.texture = RES.getRes("box");
var rect:egret.Rectangle = new egret.Rectangle(30,31,40,41);
img2.scale9Grid =rect;
img2.width *= 2;
img2.y = 150;
this.addChild(img2);
30:区域1 的宽度值。
31:区域1 的高度值
40:区域2 的宽度值
41:区域4 的高度值
Warning #1018: 9宫格设置错误
3)图片的平铺
平铺在容器中:
var img:egret.Bitmap = new egret.Bitmap();
img.texture = RES.getRes("box");
img.fillMode = egret.BitmapFillMode.REPEAT;//平铺属性
img.width *= 2;
img.height *= 3;
this.addChild(img);
4)纹理集组合多图片
将大量的图片拼合为一张图片从而减少网络请求,原先加载数次的图片资源现在加载一次即可
使用:http://edn.egret.com/cn/docs/page/135
5)截屏
http://edn.egret.com/cn/docs/page/500
12.绘图
0)清除绘图效果
shp.graphics.clear();
1)矩形
var shp:egret.Shape = new egret.Shape();
shp.graphics.beginFill( 0xff0000, 1);
shp.graphics.drawRect( 0, 0, 100, 200 );
shp.graphics.endFill();
this.addChild( shp );
2)带边框矩形
var shp:egret.Shape = new egret.Shape();
shp.x = 20;
shp.y = 20;
shp.graphics.lineStyle( 10, 0x00ff00 );//边框厚度 颜色
shp.graphics.beginFill( 0xff0000, 1); //矩形填充色 透明度
shp.graphics.drawRect( 0, 0, 100, 200 );
shp.graphics.endFill();
this.addChild( shp );
3)边框圆形
var shp:egret.Shape = new egret.Shape();
shp.x = 100;
shp.y = 100;
shp.graphics.lineStyle( 10, 0x00ff00 );
shp.graphics.beginFill( 0xff0000, 1);
shp.graphics.drawCircle( 0, 0, 50 ); //圆
shp.graphics.endFill();
this.addChild( shp );
4)线
var shp:egret.Shape = new egret.Shape();
shp.graphics.lineStyle( 2, 0x00ff00 );
shp.graphics.moveTo( 10,10 );//起点
shp.graphics.lineTo( 100, 20 );//终点
shp.graphics.endFill();
this.addChild( shp );
5)收尾相连线
var shp:egret.Shape = new egret.Shape();
shp.graphics.lineStyle( 2, 0x00ff00 );
shp.graphics.moveTo( 68, 84 );
shp.graphics.lineTo( 167, 76 );
shp.graphics.lineTo( 221, 118 );
shp.graphics.lineTo( 290, 162 );
shp.graphics.lineTo( 297, 228 );
shp.graphics.lineTo( 412, 250 );
shp.graphics.lineTo( 443, 174 );
shp.graphics.endFill();
this.addChild( shp );
6)绘制曲线
下图是一张二次贝塞尔曲线的结构图。
var shp:egret.Shape = new egret.Shape();
shp.graphics.lineStyle( 2, 0x00ff00 );
shp.graphics.moveTo( 50, 50);//起点
shp.graphics.curveTo( 100,100, 200,50);//控制点 终点
shp.graphics.endFill();
this.addChild( shp );
7)圆弧
drawArc( x:number,
y:number,
radius:number,
startAngle:number,
endAngle:number,
anticlockwise:boolean ):void
圆心在 (x, y) 位置,半径为 radius 。后面的参数表示根据 anticlockwise : 如果为 true,逆时针绘制圆弧,反之,顺时针绘制。
其中 startAngle 和 endAngle 都使用的是弧度表示。startAngle 的起始点是从 x 轴方向开始计算的。
下面的例子绘制了一个从 0 到 π 的圆弧:
var shp:egret.Shape = new egret.Shape();
shp.graphics.beginFill( 0x1122cc );
shp.graphics.drawArc(200,200,100,0,Math.PI,true);
shp.graphics.endFill();
this.addChild( shp );
http://edn.egret.com/cn/index.php/apidoc/egret243/name/global.Math :数学相关
http://edn.egret.com/cn/docs/page/674 :高级画图形
http://edn.egret.com/cn/docs/page/496 :多图形绘制
8)文本
在文本中添加多个换行符\n,让刚才的文本从横向排列变为纵向排列
var label:egret.TextField = new egret.TextField();
label.text = "这是一个文本";
this.addChild( label );
//自身的宽度与高度
console.log( label.width + "+" + label.height);
label.width = 70;
label.height = 70;
label.textColor = 0xff0000;
//字体 楷体
label.fontFamily = "KaiTi";
文本创建后,默认在容器的左上角
对文本的布局分为横向和纵向两种。
横向布局可以设置文字居左,水平居中,居右。
纵向布局可以设置文字居顶,垂直居中,居底。
横向设置:
label.textAlign = egret.HorizontalAlign.RIGHT;
label.textAlign = egret.HorizontalAlign.CENTER;
纵向设置:
label.verticalAlign = egret.VerticalAlign.BOTTOM;
label.verticalAlign = egret.VerticalAlign.MIDDLE;
9)文本描边-加粗-斜体
//设置描边属性
label.strokeColor = 0x0000ff;
label.stroke = 2;
加粗和斜体是:
//设置粗体与斜体
label.bold = true;
label.italic = true;
10)文本多样式-超链接
http://edn.egret.com/cn/docs/page/146:多样式
http://edn.egret.com/cn/docs/page/149 :超链接
http://edn.egret.com/cn/docs/page/292 :可输入文本
13.滤镜
比如将游戏卡片变成灰色(死亡了)等:http://edn.egret.com/cn/docs/page/947
14.Timer
倒计时
只需要关心两个属性,三个方法和两个事件即可:
两个属性分别是 delay
与 repeatCount
,两个属性分别表示每次间隔的时间(以毫秒为单位)和执行的次数(如果次数为0,则表示不停的执行)。
关心的三个方法为 start
、 reset
和 stop
。 从方法的字面意思中不难理解,三个方法的作用分别是开始计时,重新计时和暂停计时。
最后需要关心的两个事件分别为 TimerEvent.TIMER
和 TimerEvent.TIMER_COMPLETE
。这两个事件分别在计时过程中触发和计时结束后触发。
class TimerDemo extends egret.DisplayObjectContainer
{
public constructor()
{
super();
//创建一个计时器对象
var timer:egret.Timer = new egret.Timer(500,5);
//注册事件侦听器
timer.addEventListener(egret.TimerEvent.TIMER,this.timerFunc,this);
timer.addEventListener(egret.TimerEvent.TIMER_COMPLETE,this.timerComFunc,this);
//开始计时
timer.start();
}
private timerFunc()
{
console.log("计时");
}
private timerComFunc()
{
console.log("计时结束");
}
}
日志为:
16.循环调用事件
实现的方法有两种,注册侦听 ENTER_FRAME
事件和调用startTick
全局函数。监听 ENTER_FRAME
将会按照帧频进行回调,而startTick
一般以 60 帧回调。
补充:getTimer()
用以获取全局的 Egert 框架启动时间毫秒数。(console.log(egret.getTimer() 345)
)
这里有一点需要注意的是,Egret 需要从浏览器中获取当前的时间,而浏览器从用户的系统中获取时间,
当用户手动修改本地时间时可能会导致我们获取到的时间不准确。当用户有意欺骗浏览器时可能会造成
我们的程序出现问题。这在任意 JavaScript 前端程序中都有可能遇到。当我们希望程序更加稳固的
时候加入合适的服务端后台验证是有必要的,是可以被考虑的。要权衡开发的成本,评估用户修改本
地时间造成的影响,是可以被考虑的。
简单帧动画: