笔记三 :EgretH5通用MVC框架的入门操作:为UI界面的打开添加动画效果(UI部分)

前言:合格的游戏界面(UI)打开关闭通常需要过渡性的动画,这里记录如何在通用egret,MVC框架中,笔记一中创建的scene里面,增加打开界面添加动画效果的功能,效果如图:

1.打开\src\example\module\base\BasePanelView.ts 修改继承限定,运行关闭界面时进行其他操作

找到最底下的这几行代码:

    private closeBtnClickHandler(e:egret.TouchEvent):void{
        App.ViewManager.closeView(this);
    }

把private这个关键字改成protected:

    protected closeBtnClickHandler(e:egret.TouchEvent):void{
        App.ViewManager.closeView(this);
    }

原则上,框架内的东西不能随意更改,就像房子可以装修打洞,但不能动横梁柱子什么的,会出问题。

这里把private换成protected主要是方便继承基本panel界面的UI可以在关闭时增加新的功能,比如播放动画效果。

BasePanelView.ts参考代码:

/**
 * Created by egret on 15-1-7.
 */
class BasePanelView extends BaseEuiView {
    public closeBtn:eui.Button;
    public iconDisplay:eui.Image;
    public button:eui.Image;
    public contentGroup:eui.Group;

    private _icon:string;
    private _btn:string;

    public constructor(controller:BaseController, parent:eui.Group) {
        super(controller, parent);
        this.skinName = "resource/skins/PanelSkin.exml";
    }

    public set icon(value:string){
        this._icon = value;
        if(this.iconDisplay){
            this.iconDisplay.source = this._icon;
        }
    }

    public get icon():string{
        return this._icon;
    }

    public set btn(value:string){
        this._btn = value;
        if(this.button){
            this.button.source = this._btn;
        }
    }

    public get btn():string{
        return this._btn;
    }

    /**
     *对面板进行显示初始化,用于子类继承
     *
     */
    public initUI():void {
        super.initUI();
        this.closeBtn.addEventListener(egret.TouchEvent.TOUCH_END,this.closeBtnClickHandler,this);
    }

    /**
     *对面板数据的初始化,用于子类继承
     *
     */
    public initData():void{
        super.initData();
        this.iconDisplay.source = this._icon;
        this.button.source = this._btn;
    }

    protected closeBtnClickHandler(e:egret.TouchEvent):void{
        App.ViewManager.closeView(this);
        //App.ViewManager.open(ViewConst.Home);//rongqingmei
    }
}

2.打开\src\example\module\friend\FriendView.ts:  关闭界面时进行播放动画操作

添加上这几句代码:

    protected closeBtnClickHandler(e: egret.TouchEvent): void {
        App.ViewManager.playcloseView(2, this);
        //GameDispatcher.getInstance().dispatchEvent(new egret.Event(EventName.MAINBAR_CLOSE));
        //App.ViewManager.open(ViewConst.Home);//rongqingmei
    }

就是FriendView的界面在关闭时,会调用这里面的方法,这里是把基类的相应关闭按钮方法给重写了。

其中有一个App.ViewManager.playcloseView是接下来要写的播放动画的方法.

FriendView.ts参考代码:(出现错误的代码删除掉,是之后的笔记用到的东西)

/**
 * Created by egret on 15-1-7.
 */
class FriendView extends BasePanelView {
    public constructor(controller: BaseController, parent: eui.Group) {
        super(controller, parent);

        this.icon = "table_tittle"; //好友的图片
    }
    protected closeBtnClickHandler(e: egret.TouchEvent): void {
        App.ViewManager.playcloseView(2, this);
        GameDispatcher.getInstance().dispatchEvent(new egret.Event(EventName.MAINBAR_CLOSE));
        //App.ViewManager.open(ViewConst.Home);//rongqingmei
    }
}

3.打开\src\example\module\demo\DemoView.ts   打开界面时进行动画操作

添加组件:

button: eui.ToggleButton;

组件按钮的点击事件,在public initUI(): void 中添加:

this.button.addEventListener(egret.TouchEvent.TOUCH_TAP, this.buttonClickHandler, this);

点击事件的函数:

    private buttonClickHandler(e: egret.TouchEvent): void {
        App.ViewManager.playopen(2, ViewConst.Friend);
    }

核心与第二步类似,就是点击按钮播放动画并打开函数,这个函数接下来的步骤会写。

DemoView.ts参考代码:(出现错误的代码删除掉,是之后的笔记用到的东西)

/**
 * Created by egret on 15-1-6.
 */
class DemoView extends BaseEuiView {
    public constructor($controller: BaseController, $parent: eui.Group) {
        super($controller, $parent);
        this.skinName = "resource/skins/DemoSkin.exml";
    }

    button: eui.ToggleButton;
    //展开菜单
    menuBtn: eui.Button;
    maskRect: eui.Rect;
    menu: Menu;
    //hp,mp条
    lowHpRect: eui.Rect;
    fastHpRect: eui.Rect;
    addHP: eui.Button;
    downHP: eui.Button;
    //this.dispatchEvent(daterEvent);
    /**
     *对面板进行显示初始化,用于子类继承
     *
     */
    public initUI(): void {
        super.initUI();
        this.button.addEventListener(egret.TouchEvent.TOUCH_TAP, this.buttonClickHandler, this);
        this.menuBtn.addEventListener(egret.TouchEvent.TOUCH_TAP, this.menubuttonClickHandler, this);
        this.addHP.addEventListener(egret.TouchEvent.TOUCH_TAP, this.addbuttonClickHandler, this);
        this.downHP.addEventListener(egret.TouchEvent.TOUCH_TAP, this.downbuttonClickHandler, this);
        GameDispatcher.getInstance().addEventListener(EventName.MAINBAR_CLOSE, this.restoreButton, this);//监听界面的关闭

        //为左边的弹出菜单设定遮罩
        this.menu.mask = this.maskRect;
        //人物血条的变化
        this.initHpBar();
    }

    private buttonClickHandler(e: egret.TouchEvent): void {
        App.ViewManager.playopen(2, ViewConst.Friend);
    }
    /**左边中间的那个折叠菜单的按钮事件 */
    private menubuttonClickHandler(e: egret.TouchEvent): void {
        let tween;
        let self = this;
        if (self.menu.$visible) {
            self.menuBtn.touchEnabled = false;//播放动画时不可再次按按钮
            tween = egret.Tween.get(this.menu).to({ scaleX: 1.0, scaleY: 1.0, x: 100 }, 0).to({ scaleX: 1.0, scaleY: 1.0, x: -400 }, 460).call(function () { self.menu.$setVisible(false); self.menuBtn.touchEnabled = true; });
        } else {
            self.menu.$setVisible(true);
            self.menuBtn.touchEnabled = false;//播放动画时不可再次按按钮
            tween = egret.Tween.get(this.menu).to({ scaleX: 1.0, scaleY: 1.0, x: -400 }, 0).to({ scaleX: 1.0, scaleY: 1.0, x: 100 }, 460).call(function () { self.menuBtn.touchEnabled = true; });
        }
    }
    //关闭窗口时候的按钮恢复状态
    private restoreButton(): void {
        console.log("restoreButton");
        this.button.selected = false;
    }

    //初始化initHpBar;
    private initHpBar():void{
        this.updateHpBar(1);
    }

    private HpBarNumNow:number = 0;//HP栏目前显示的数值
    private HpBarV:number = 0.2;//Hp扣除时衰减的速度
    /**更新血条状态 */
    private updateHpBar(NumUpdate: number): void { //需要更新成的数值
        let self = this;
        if (NumUpdate > self.HpBarNumNow) {//更新的数值大于目前的数值时的逻辑
            let tween;
            //第一个条同时进行缓慢增长,实心的那条
            egret.Tween.removeTweens(self.fastHpRect);//播放前先清除之前的动画
            let tempHpNum:number = self.fastHpRect.scaleX;//动画是从目前的长度开始进行
            tween = egret.Tween.get(self.fastHpRect).to({ scaleX: tempHpNum }, 0).to({ scaleX: NumUpdate }, 1200).call(function () { 
             });
            //第二个条同时进行缓慢增长
            egret.Tween.removeTweens(self.lowHpRect);//播放前先清除之前的动画
            tempHpNum = self.fastHpRect.scaleX;//动画是从目前的长度开始进行
            tween = egret.Tween.get(self.lowHpRect).to({ scaleX: tempHpNum }, 0).to({ scaleX: NumUpdate }, 1200).call(function () { 
             });
            self.HpBarNumNow = NumUpdate; //HP栏目前的数值进行更新
            console.log("这是之前的HpBarNumNow,NumUpdate",self.HpBarNumNow,NumUpdate);
        } else if(NumUpdate < self.HpBarNumNow){//更新的数值小于目前的数值时的逻辑
            let tween;
            let tempHpNum:number = self.lowHpRect.scaleX;//动画是从目前的长度开始进行
            egret.Tween.removeTweens(self.lowHpRect);////播放动画前先清除之前的动画
            let t:number = (NumUpdate - tempHpNum)/this.HpBarV * 1000;//根据衰减时间计算衰减速度
            if(t < 0) t=-t;   //取绝对值
            tween = egret.Tween.get(self.lowHpRect).to({ scaleX: tempHpNum }, 0).to({ scaleX: NumUpdate }, t);
            egret.Tween.removeTweens(self.fastHpRect);////瞬变前先清除之前的动画
            self.fastHpRect.scaleX = NumUpdate;   //血条减血时瞬变
            self.HpBarNumNow = NumUpdate;
        }
    }

    private tempnum = 1;
    private addbuttonClickHandler(): void {
        if ((this.tempnum + 0.2) <= 1.0) {
            this.tempnum += 0.2;
        }
        this.updateHpBar(this.tempnum);
    }

    private downbuttonClickHandler(): void {
        if ((this.tempnum - 0.2) >= 0) {
            this.tempnum -= 0.2;
        }
        this.updateHpBar(this.tempnum);
    }

}

4.打开\src\core\mvc\ViewManager.ts  动画操作的具体函数代码

添加上以下三个函数:

     /**
     * 带动画开启面板
     * @param key 面板唯一标识
     * @param param 参数
     *
     */
    public playopen(playmode:number,key:number, ...param:any[]):IBaseView {
        var view:IBaseView = this.getView(key);
        if (view == null) {
            Log.trace("UI_" + key + "不存在");
            return;
        }

        if (view.isShow()) {
            view.open.apply(view, param);
            return view;
        }

        if (view.isInit()) {
            view.addToParent();
            view.open.apply(view, param);
        }
        else {
            App.EasyLoading.showLoading();
            view.loadResource(function () {
                view.setVisible(false);
                view.addToParent();
            }.bind(this), function () {
                view.initUI();
                view.initData();
                view.open.apply(view, param);
                view.setVisible(true);
                App.EasyLoading.hideLoading();
            }.bind(this));
        }
        //动画,动画从零开始就会卡
        let _tween;
        switch(playmode){
            //从小变大
            case 1: _tween = egret.Tween.get(view).to( {scaleX: 0.3,scaleY: 0.3}, 0 ).to( {scaleX: 1.0,scaleY: 1.0}, 200 );break;
            //逐渐显现
            case 2: _tween = egret.Tween.get(view).to( {alpha:0.3,scaleX: 1.0,scaleY: 1.0}, 0 ).to( {alpha:1.0,scaleX: 1.0,scaleY: 1.0}, 200 );break;
            default:break;
        }
        this._opens.push(key);
        return view;
    }

     /**
     * 带动画关闭面板
     * @param playmode 动画播放形式
     * @param key 面板唯一标识
     * @param param 参数
     *
     */
    public playclose(playmode:number,key:number, ...param:any[]):void {
        if (!this.isShow(key)) {
            return;
        }

        var view:IBaseView = this.getView(key);
        if (view == null) {
            return;
        }

        var viewIndex = this._opens.indexOf(key);
        if (viewIndex >= 0) {
            this._opens.splice(viewIndex, 1);
        }
        //动画,动画从零开始就会卡
        // console.log( "完成加载" )
        let _tween;
        switch(playmode){
            //从小变大
            case 1: _tween = egret.Tween.get(view).to( {scaleX: 1.0,scaleY: 1.0}, 0 ).to( {scaleX: 0.1,scaleY: 0.1}, 80 ).call( function(){ view.removeFromParent(); view.close.apply(view, param); } );break;
            //逐渐显现
            case 2: _tween = egret.Tween.get(view).to( {scaleX: 1.0,scaleY: 1.0,alpha:1.0}, 0 ).to( {scaleX: 1.0,scaleY: 1.0,alpha:0.1}, 80 ).call( function(){ view.removeFromParent(); view.close.apply(view, param); } );break;
            default:break;
        }
    }

     /**
     * 带动画关闭面板
     * @param view
     * @param param
     */
    public playcloseView(playmode:number,view:IBaseView, ...param:any[]):void {
        var keys = Object.keys(this._views);
        for (var i:number = 0, len = keys.length; i < len; i++) {
            var key:number = parseInt(keys[i]);
            if (this._views[key] == view) {
                this.playclose(playmode,key, param);
                return;
            }
        }
    }

其中的核心主要是在switch(playmode)中,根据要求播放相应动画,注意,对界面进行播放动画特别是缩放时,尽量避免从0开始变化,界面缩小到0的过程非常卡,等到0.2或者0.1时就让界面消失就可以避免卡顿。

ViewManager.ts 参考代码:

class ViewManager extends BaseClass {
    /**
     * 已注册的UI
     */
    private _views:any;

    /**
     * 开启中UI
     */
    private _opens:Array<number>;

    /**
     * 构造函数
     */
    public constructor() {
        super();
        this._views = {};
        this._opens = [];
    }

    /**
     * 清空处理
     */
    public clear():void {
        this.closeAll();
        this._views = {};
    }

    /**
     * 面板注册
     * @param key 面板唯一标识
     * @param view 面板
     */
    public register(key:number, view:IBaseView):void {
        if (view == null) {
            return;
        }
        if (this._views[key]) {
            return;
        }
        this._views[key] = view;
    }

    /**
     * 面板解除注册
     * @param key
     */
    public unregister(key:number):void {
        if (!this._views[key]) {
            return;
        }
        this._views[key] = null;
        delete this._views[key];
    }

    /**
     * 销毁一个面板
     * @param key 唯一标识
     * @param newView 新面板
     */
    public destroy(key:number, newView:IBaseView = null):void {
        var oldView:IBaseView = this.getView(key);
        if (oldView) {
            this.unregister(key);
            oldView.destroy();
            oldView = null;
        }
        this.register(key, newView);
    }

    /**
     * 开启面板
     * @param key 面板唯一标识
     * @param param 参数
     *
     */
    public open(key:number, ...param:any[]):IBaseView {
        var view:IBaseView = this.getView(key);
        if (view == null) {
            Log.trace("UI_" + key + "不存在");
            return;
        }

        if (view.isShow()) {
            view.open.apply(view, param);
            return view;
        }

        if (view.isInit()) {
            view.addToParent();
            view.open.apply(view, param);
        }
        else {
            App.EasyLoading.showLoading();
            view.loadResource(function () {
                view.setVisible(false);
                view.addToParent();
            }.bind(this), function () {
                view.initUI();
                view.initData();
                view.open.apply(view, param);
                view.setVisible(true);
                App.EasyLoading.hideLoading();
            }.bind(this));
        }
        this._opens.push(key);
        return view;
    }

    /**
     * 带动画开启面板
     * @param key 面板唯一标识
     * @param param 参数
     *
     */
    public playopen(playmode:number,key:number, ...param:any[]):IBaseView {
        var view:IBaseView = this.getView(key);
        if (view == null) {
            Log.trace("UI_" + key + "不存在");
            return;
        }

        if (view.isShow()) {
            view.open.apply(view, param);
            return view;
        }

        if (view.isInit()) {
            view.addToParent();
            view.open.apply(view, param);
        }
        else {
            App.EasyLoading.showLoading();
            view.loadResource(function () {
                view.setVisible(false);
                view.addToParent();
            }.bind(this), function () {
                view.initUI();
                view.initData();
                view.open.apply(view, param);
                view.setVisible(true);
                App.EasyLoading.hideLoading();
            }.bind(this));
        }
        //动画,动画从零开始就会卡
        let _tween;
        switch(playmode){
            //从小变大
            case 1: _tween = egret.Tween.get(view).to( {scaleX: 0.3,scaleY: 0.3}, 0 ).to( {scaleX: 1.0,scaleY: 1.0}, 200 );break;
            //逐渐显现
            case 2: _tween = egret.Tween.get(view).to( {alpha:0.3,scaleX: 1.0,scaleY: 1.0}, 0 ).to( {alpha:1.0,scaleX: 1.0,scaleY: 1.0}, 200 );break;
            default:break;
        }
        this._opens.push(key);
        return view;
    }

    /**
     * 关闭面板
     * @param key 面板唯一标识
     * @param param 参数
     *
     */
    public close(key:number, ...param:any[]):void {
        if (!this.isShow(key)) {
            return;
        }

        var view:IBaseView = this.getView(key);
        if (view == null) {
            return;
        }

        var viewIndex = this._opens.indexOf(key);
        if (viewIndex >= 0) {
            this._opens.splice(viewIndex, 1);
        }
        view.removeFromParent();
        view.close.apply(view, param);
    }

     /**
     * 带动画关闭面板
     * @param playmode 动画播放形式
     * @param key 面板唯一标识
     * @param param 参数
     *
     */
    public playclose(playmode:number,key:number, ...param:any[]):void {
        if (!this.isShow(key)) {
            return;
        }

        var view:IBaseView = this.getView(key);
        if (view == null) {
            return;
        }

        var viewIndex = this._opens.indexOf(key);
        if (viewIndex >= 0) {
            this._opens.splice(viewIndex, 1);
        }
        //动画,动画从零开始就会卡
        // console.log( "完成加载" )
        let _tween;
        switch(playmode){
            //从小变大
            case 1: _tween = egret.Tween.get(view).to( {scaleX: 1.0,scaleY: 1.0}, 0 ).to( {scaleX: 0.1,scaleY: 0.1}, 80 ).call( function(){ view.removeFromParent(); view.close.apply(view, param); } );break;
            //逐渐显现
            case 2: _tween = egret.Tween.get(view).to( {scaleX: 1.0,scaleY: 1.0,alpha:1.0}, 0 ).to( {scaleX: 1.0,scaleY: 1.0,alpha:0.1}, 80 ).call( function(){ view.removeFromParent(); view.close.apply(view, param); } );break;
            default:break;
        }
    }

    /**
     * 带动画关闭面板
     * @param view
     * @param param
     */
    public playcloseView(playmode:number,view:IBaseView, ...param:any[]):void {
        var keys = Object.keys(this._views);
        for (var i:number = 0, len = keys.length; i < len; i++) {
            var key:number = parseInt(keys[i]);
            if (this._views[key] == view) {
                this.playclose(playmode,key, param);
                return;
            }
        }
    }

    /**
     * 关闭面板
     * @param view
     * @param param
     */
    public closeView(view:IBaseView, ...param:any[]):void {
        var keys = Object.keys(this._views);
        for (var i:number = 0, len = keys.length; i < len; i++) {
            var key:number = parseInt(keys[i]);
            if (this._views[key] == view) {
                this.close(key, param);
                return;
            }
        }
    }

    /**
     * 根据唯一标识获取一个UI对象
     * @param key
     * @returns {any}
     */
    public getView(key:number):IBaseView {
        return this._views[key];
    }

    /**
     * 关闭所有开启中的UI
     */
    public closeAll():void {
        while (this._opens.length) {
            this.close(this._opens[0]);
        }
    }

    /**
     * 当前ui打开数量
     * @returns {number}
     */
    public currOpenNum():number {
        return this._opens.length;
    }

    /**
     * 检测一个UI是否开启中
     * @param key
     * @returns {boolean}
     */
    public isShow(key:number):boolean {
        return this._opens.indexOf(key) != -1;
    }
}

界面文件:\resource\skins\DemoSkin.exml 参考代码:

<?xml version="1.0" encoding="utf-8"?>
<e:Skin class="DemoSkin" width="650" height="1000" xmlns:e="http://ns.egret.com/eui" xmlns:w="http://ns.egret.com/wing" xmlns:ns1="*">
	<e:Image width="362" height="48" x="19" y="232" anchorOffsetX="0" anchorOffsetY="0" source="table_cloud_top" fillMode="repeat" visible="false"/>
	<e:Group width="450" height="108" anchorOffsetX="0" anchorOffsetY="0" horizontalCenter="0" bottom="0">
		<e:Rect width="448" height="67" x="1.3199999999999932" y="42.24000000000001" fillColor="0xebfff8" anchorOffsetX="0" anchorOffsetY="0" scaleX="1" scaleY="1"/>
		<e:Image width="449" height="41.99" x="449.20000000000005" y="50.24000000000001" anchorOffsetX="0" anchorOffsetY="0" source="table_cloud_top" fillMode="repeat" rotation="180.16" scaleX="1" scaleY="1"/>
		<e:ToggleButton id="button" label="ToggleButton" x="45" y="32" anchorOffsetX="0" width="74" anchorOffsetY="0" height="75" skinName="MenuButtonSkin" scaleX="1" scaleY="1"/>
		<e:ToggleButton id="button2" label="ToggleButton" x="140.76" y="32" anchorOffsetX="0" width="74" anchorOffsetY="0" height="75" skinName="MenuButtonSkin" scaleX="1" scaleY="1"/>
		<e:ToggleButton id="button3" label="ToggleButton" x="237" y="32" anchorOffsetX="0" width="74" anchorOffsetY="0" height="75" skinName="MenuButtonSkin" scaleX="1" scaleY="1"/>
		<e:ToggleButton id="button4" label="ToggleButton" x="335" y="32" anchorOffsetX="0" width="74" anchorOffsetY="0" height="75" skinName="MenuButtonSkin" scaleX="1" scaleY="1"/>
	</e:Group>
	<e:Group width="610.61" height="192.42" x="0" y="178.79" anchorOffsetX="0" anchorOffsetY="0">
		<ns1:Menu id="menu" x="78" y="37.21000000000001" skinName="MenuSkin" scaleX="1" scaleY="1" visible="false"/>
		<e:Rect id="maskRect" width="530.61" height="191.22" x="77.72" y="0" anchorOffsetX="0" anchorOffsetY="0" scaleX="1" scaleY="1"/>
		<e:ToggleButton id="menuBtn" label="切换按钮" skinName="MenuButtonSkin" x="14" y="58.210000000000036" scaleX="1" scaleY="1"/>
	</e:Group>
	<e:Group width="481.82" height="162.12" x="268.09" y="0" anchorOffsetX="0" anchorOffsetY="0">
		<e:Image width="354.76" height="130.62" x="17.36" y="18.78" anchorOffsetX="0" anchorOffsetY="0" source="menu_bg"/>
		<e:Rect width="83.63" height="85.16" x="38.73" y="41.51" anchorOffsetX="0" anchorOffsetY="0"  scaleX="1" scaleY="1" fillColor="0xffffff"/>
		<e:Rect width="167" height="19" x="157.41" y="71.56" anchorOffsetX="0" anchorOffsetY="0" fillColor="0xffffff"/>
		<e:Rect id="lowHpRect" width="167" height="19" x="157.41" y="71.56" anchorOffsetX="0" anchorOffsetY="0" fillColor="0xff0202"/>
		<e:Rect id="fastHpRect" width="167" height="19" x="157.41" y="71.56" anchorOffsetX="0" anchorOffsetY="0" fillColor="0xff7a7a"/>
		<e:Button id="addHP" label="+" x="175.24" y="105.67" anchorOffsetX="0" width="39" anchorOffsetY="0" height="38"/>
		<e:Button id="downHP" label="-" x="240.91" y="107.67" anchorOffsetX="0" width="33" anchorOffsetY="0" height="34"/>
	</e:Group>
</e:Skin>

猜你喜欢

转载自blog.csdn.net/u013617851/article/details/83012816