如何用Egret实现抽奖轮盘


640

一、简介

本篇教程适合初次接触白鹭的同学,我们通过实现抽奖效果,让大家对egret的touch事件,timer计时器以及滤镜有一个基本的了解。具体效果如下:


640?wx_fmt=gif

二、具体实现方法

1、创建一个Luck类编写抽奖的主逻辑


Luck类继承自egret.DisplayObjectContainer容器

class Luck extends egret.DisplayObjectContainer {
   
   public constructor() {
       super();
   }
}
2、数据初始化
//存放所有奖品的数组
private arr_img: string[] = [];
//抽奖计时器
private tim:egret.Timer;
//初始化
private init() {
       //创建中心区域的红色抽奖按钮
       this.creatbtn();
       //给存放奖品的数组赋值
       this.arr_img = ["xg_png", "ct_png", "lj_png", "zs_png", "my_png", "mg_png", "hua_png", "yy_png", "jct_png", "xr_png"];
       //绘制轮盘使奖品以圆的形式排列
       this.setcircle();
       //添加抽奖时的计时器
       this.tim = new egret.Timer(500,0);
       this.tim.addEventListener(egret.TimerEvent.TIMER,this.Luckyanimation,this);
   }
3、创建红色抽奖按钮(creatbtn)

设置抽奖按钮居中:改变按钮的锚点,默认的锚点在左上角,改为按钮的中心this.btn.anchorOffsetX = this.btn.width / 2;this.btn.anchorOffsetY = this.btn.height / 2;然后让按钮的位置在整个舞台的中心。此时在创建按钮的时候舞台上什么都没有,所以直接用this.stage.stageWidth是获取不到舞台的宽高的。在以后的项目中同学们可以创建一个date类,用来存放全局的数据,本篇教程是在main.ts中直接添加了两个静态属性STAGEWIDTHSTAGEHEIGHT具体方法如下:


//舞台宽度
public static STAGEWIDTH: number;
//舞台高度
public static STAGEHEIGHT: number;
protected createGameScene(): void {
       Main.STAGEWIDTH = this.stage.stageWidth;
       Main.STAGEHEIGHT = this.stage.stageHeight;
       this.addChild(new Luck);
}
private btn: egret.Sprite;//中心的抽奖按钮
//绘制抽奖按钮
private creatbtn() {
       //创建抽奖按钮的精灵
       this.btn = new egret.Sprite();
       this.addChild(this.btn);
       //让按钮居中
       this.btn.x = Main.STAGEWIDTH / 2;
       this.btn.y = Main.STAGEHEIGHT / 2;
       this.btn.anchorOffsetX = this.btn.width / 2;
       this.btn.anchorOffsetY = this.btn.height / 2;
       //开启btn的可点击
       this.btn.touchEnabled = true;
       //给btn添加点击事件
       this.btn.addEventListener(egret.TouchEvent.TOUCH_TAP, this.onbtnTap, this);
       
       //绘制红色的圆并添加到btn中
       let cir:egret.Shape = new egret.Shape();
       cir.graphics.beginFill(0xff0000);
       cir.graphics.drawCircle(0,0,50);
       cir.graphics.endFill();
       this.btn.addChild(cir);

       //添加抽奖文字
       let cj:egret.TextField = new egret.TextField();
       cj.text = '抽奖';
       cj.anchorOffsetX = cj.width/2;
       cj.anchorOffsetY = cj.height/2;
       cj.textColor = 0xd8ee1f;
       this.btn.addChild(cj);
   }
4、使所有奖品以圆的形式排列

private point = []; //结果
private bitmapArr:egret.Bitmap[] = [];//
//让奖品以圆的形式排列
private setcircle() {
   this.getPoint(200, Main.STAGEWIDTH / 2, Main.STAGEHEIGHT / 2, this.arr_img.length);
   for (let i: number = 0; i < this.point.length; i++) {
       let img = new egret.Bitmap();
       img.texture = RES.getRes(this.arr_img[i]);
       img.width = 60;
       img.height = 60;
       img.anchorOffsetX = img.width / 2;
       img.anchorOffsetY = img.height / 2;
       //根据拿到的坐标给每一个奖品赋值
       img.x = this.point[i].x;
       img.y = this.point[i].y;
       img.name = i+'';
       this.addChild(img);
       this.bitmapArr.push(img);
   }
   }
/**
* 求圆周上等分点的坐标
* @param r  圆的半径
* @param ox 圆心坐标x
* @param oy 圆心坐标y
* @param count 等分个数
*/
private getPoint(r: number, ox: number, oy: number, count: number) {
   let radians = (Math.PI / 180) * Math.round(360 / count); //弧度
   for (let i: number = 0; i < count; i++) {
       let x = ox + r * Math.sin(radians * i);
       let y = oy + r * Math.cos(radians * i);
       this.point.unshift({ x: x, y: y }); //为保持数据顺时针
   }
}


在egret中,用/***/进行注释会在编写代码时有代码提示,当参数比较多时,可在注释行中用@param声明每个参数的作用。

640?wx_fmt=jpeg

5、编写点击抽奖的响应事件

在点击事件里移除对当前点击的监听,防止用户多次点击。

扫描二维码关注公众号,回复: 5099777 查看本文章

在计时器里可以直接用 timer.delay 改变计时器的延迟毫秒数。



private rad:number;
private isjia:boolean = true;

//点击开始抽奖
private onbtnTap() {
   //移除点击事件监听
   this.btn.removeEventListener(egret.TouchEvent.TOUCH_TAP, this.onbtnTap, this);
   //获取一个随机数
   this.Getrandom();
   //开启计时器
   this.tim.start();
   //
   this.isjia = true;
   this.jsq = 0;
}

private jsq:number=0;   //控制计时器在延迟小于30的时候实现一个抽奖滚动的过程
//抽奖动画特效
private Luckyanimation(){
   this.num++;
   if (this.num>=this.arr_img.length) this.num =0;
   this.creatfilter(this.bitmapArr[this.num==0?this.arr_img.length-1:this.num-1],this.bitmapArr[this.num]);
   //实现由慢到快,再由快到慢的过程
   if(this.tim.delay>30 && this.isjia){
       this.tim.delay-=30;
   }else{
       this.jsq++;
   }
   if(this.jsq>=100){
       this.isjia = false;
       this.tim.delay+=20;
   }
   if(!this.isjia && this.num==this.rad && this.tim.delay>400){
       this.tim.stop();
       //当计时器停止并且已经停在了抽奖的位置时,再给抽奖按钮添加监听
       this.btn.addEventListener(egret.TouchEvent.TOUCH_TAP, this.onbtnTap, this);
   }      
}
//获取随机出现的值
private Getrandom(){
   this.rad = Math.floor(Math.random()*this.arr_img.length);
}
//设置滤镜
private creatfilter(bitmap0:egret.Bitmap,bitmap:egret.Bitmap) {
   var color: number = 0x33CCFF;        /// 光晕的颜色,十六进制,不包含透明度
   var alpha: number = 0.8;             /// 光晕的颜色透明度,是对 color 参数的透明度设  定。有效值为 0.0 到 1.0。例如,0.8 设置透明度值为 80%。
   var blurX: number = 35;              /// 水平模糊量。有效值为 0 到 255.0(浮点)
   var blurY: number = 35;              /// 垂直模糊量。有效值为 0 到 255.0(浮点)
   var strength: number = 2;            /// 压印的强度,值越大,压印的颜色越深,而且发光与背景之间的对比度也越强。有效值为 0 到 255。暂未实现
   var quality: number = egret.BitmapFilterQuality.HIGH;        /// 应用滤镜的次数,建议用 BitmapFilterQuality 类的常量来体现
   var inner: boolean = false;            /// 指定发光是否为内侧发光
   var knockout: boolean = false;            /// 指定对象是否具有挖空效果
   var glowFilter: egret.GlowFilter = new egret.GlowFilter(color, alpha, blurX, blurY, strength, quality, inner, knockout);
   bitmap0.filters=[];//先清除上一个的发光滤镜,再给当前图片添加
   bitmap.filters = [glowFilter];
}


-END-

640?wx_fmt=png


喜欢本文的朋友们,欢迎关注订阅号,收看更多精彩内容!



猜你喜欢

转载自blog.csdn.net/shirln/article/details/86582040