qq229449388 发表于 2017-11-16 00:48:34

羔羊引擎之羔羊皮肤以按钮为例

本帖最后由 qq229449388 于 2017-11-16 01:42 编辑

如果大家有学习过flex,应该知道flex的组件是皮肤与逻辑分离的,羔羊引擎也参照flex并进行修减,使用皮肤与逻辑分离的方式展现组件。http://zsh.gyarea.com/GYLiteLesson/swfs/lesson2/GYLiteAPI.swf
下面以羔羊引擎的按钮为例,讲解一下如何按钮的皮肤类ButtonSkin以及皮肤一贯的结构。
打开ButtonSkin类,可以看到ButtonSkin继承GYSkin,实现IButtonSkin,既然有继承,我们先去看看继承的是什么内容。
打开GYSkin类,可以看到1、2、3、4、5,大概5个方法,不多。
1、clone方法,看名字就知道应该是克隆本皮肤,返回一个一样的皮肤
2、copy方法,拷贝,跟克隆有什么区别呢?由于有的时候我们不止需要克隆某个皮肤,还需要复制一下皮肤信息,如按钮的label标签字体大小、颜色等信息,这个时候就用copy来进行拷贝
3、release方法,释放皮肤资源
4和5是hostComponent的get 和set方法,这个hostcomponent十分重要,是这个皮肤依赖的组件容器。
而以上这些方法,都被定义在接口ISkin,而刚刚按钮实现的IButtonSkin则继承ISkin,也就是说,所有的皮肤都必须实现IGYSkin
这里按钮皮肤跟GYSkin的关系,一句话,IButtonSkin继承IGYSkin,ButtonSkin继承GYSkin,实现IButtonSkin,而GYSkin则实现了IGYSkin,说太多了,自己去多看看源码。

说完GYSkin,又回到ButtonSkin,这下看看源码,没什么好说的,构造函数需要两个参数,一个是位图Vector,一个是九宫格参数(Scale9GridRect,大家注意这个九宫格类,是羔羊引擎自定义的,分别是距离左右上下的距离)
下面重点说明一下drawSkin方法
这个drawSkin是提供皮肤,根据按钮状态进行切换的
package {
    import GYLite.component.scaleDisplay.Scale9GridRect;
    import GYLite.skin.buttonSkin.ButtonSkin;

    import flash.display.BitmapData;

    public class FunnyButtonSkinextends ButtonSkin {
      public
      function FunnyButtonSkin(skinVec: Vector. < BitmapData > , rect: Scale9GridRect = null) {
            super(skinVec, rect);
      }
    }
}

可以看到,上面这个方法内容就是根据state状态,切换bitmapData,是不是发现做按钮很简单,羔羊引擎按钮一共有8个状态,在ButtonBase类的静态属性里面有注明,大家可以去看看。

正常来说,只要new GYButton就可以创建一个普通的按钮,如果只是创建普通按钮,要皮肤来有何用,所以下面我们尝试自定义一个按钮皮肤来实现一些外观不一样的按钮,我们还是使用上一节课的工程,上节课听的,请从传送门回去。

下面我们创建一个名字为FunnyButtonSkin的类,代码如下

private var _colorVec: Vector. < uint > =new Vector. < uint > ;
private var _tween: GYTween;
private var _x: Number;
private var _y: Number;
public function FunnyButtonSkin(skinVec: Vector. < BitmapData > , rect: Scale9GridRect = null) {
    super(skinVec, rect);
    //我们为这个按钮创建8个颜色用于修改label的颜色
    _colorVec.push(0xff0000, 0x00ff00, 0xfff000, 0x0000ff, 0x00ffff, 0xffffff, 0x33ff33, 0x00ffff);
}
override public function drawSkin(state: int) : void {
    _curSkin.bitmapData = (state < _stsVec.length && _stsVec) ? _stsVec : _stsVec;
    labelDisplay.color = _colorVec;
}为了让按钮的效果更明显,我们可以加点动画,例如常见的放大缩小按钮,动画我们使用到羔羊引擎的缓动类GYTween,因为本课重点不是这个,所以GYTween不在这进行说明,修改后最终代码如下



private var _colorVec:Vector.<uint> = new Vector.<uint>;
private var _tween:GYTween;
private var _x:Number;
private var _y:Number;
public function FunnyButtonSkin(skinVec:Vector.<BitmapData>, rect:Scale9GridRect=null)
{
                super(skinVec, rect);
                //我们为这个按钮创建8个颜色用于修改label的颜色
                _colorVec.push(0xff0000,0x00ff00,0xfff000,0x0000ff,0x00ffff,0xffffff,0x33ff33,0x00ffff);
}
override public function drawSkin(state:int):void
{
                _curSkin.bitmapData=(state<_stsVec.length && _stsVec)? _stsVec : _stsVec;
                labelDisplay.color = _colorVec;
                if(isNaN(_x))
                {
                              _x = _hostComponent.x;
                              _y = _hostComponent.y;
                }
                if(state == ButtonBase.STATE_OVER)
                {
                              if(_tween)
                              {
                                                _tween.clear();
                                                _tween = null;
                              }
                              var times:Number = 1.2;
                              _tween = GYTween.to(_hostComponent,[
                                                TweenData.getInstance("scaleX",times,NaN,GYTween.addEase),
                                                TweenData.getInstance("scaleY",times,NaN,GYTween.addEase),
                                                TweenData.getInstance("x",_x-(_hostComponent.width*(times-1)>>1),NaN,GYTween.addEase),
                                                TweenData.getInstance("y",_y-(_hostComponent.height*(times-1)>>1),NaN,GYTween.addEase)
                              ],100,0,tweenComp);
                }
                if(state == ButtonBase.STATE_UP)
                {
                              if(_tween)
                              {
                                                _tween.clear();
                                                _tween = null;
                              }
                              _tween = GYTween.to(_hostComponent,[
                                                TweenData.getInstance("scaleX",1,NaN,GYTween.addEase),
                                                TweenData.getInstance("scaleY",1,NaN,GYTween.addEase),
                                                TweenData.getInstance("x",_x,NaN,GYTween.addEase),
                                                TweenData.getInstance("y",_y,NaN,GYTween.addEase)
                              ],100,0,tweenComp);
                }
}
private function tweenComp():void
{
                _tween = null;
}下面我们创建一个以FunnyButtonSkin为皮肤的按钮,为了方便建立教程工程,我们先新建一个课时类,类名为Lesson1,代码如下,后面的教程都是以这种方式建立工程

package
{
      import GYLite.component.button.GYButton;
      import GYLite.component.container.GYSprite;
      import GYLite.component.scaleDisplay.Scale9GridRect;
      import GYLite.skin.GYSkinTheme;
      
      import flash.display.BitmapData;
      import flash.display.Stage;

      public class Lesson1
      {
                public function Lesson1(s:Stage)
                {
                        var skin:FunnyButtonSkin;
                        var b:GYButton;
                        var rect:Scale9GridRect;
                        var vec:Vector.<BitmapData>;
                        
                        //按钮皮肤需要的第一个参数位图数组,我们直接使用主题的
                        vec = (GYSprite.skinTheme as GYSkinTheme).commonBtnSkinVec;
                        //按钮皮肤需要的第二个参数九宫格,同样直接使用主题的
                        rect = (GYSprite.skinTheme as GYSkinTheme).commonRect;
                        skin = new FunnyButtonSkin(vec, rect);
                        b = new GYButton(skin);
                        b.width = 80;
                        b.height = 30;
                        b.toggle = true;//设置点击时自动切换选中状态
                        b.x = 0;
                        b.y = 100;
                        b.label = "funny";
                        s.addChild(b);
                }
      }
}创建自定义皮肤的按钮很简单,GYButton的构造函数需要一个皮肤类的参数,默认为null,则读取主题皮肤,我们创建一个FunnyButtonSkin类实例,传入GYButton即可,此类完成后,我们到主类处,创建Lesson1的实例,传入舞台作为参数,即可看到按钮

new Lesson1(stage);由于之前有些人说本引擎跟游戏没什么关系,从这节课开始,主题皮肤更换为游戏主题,以后则使用此主题进行讲解羔羊引擎。
下面看看按钮效果,此课工程请在附件下载

页: [1]
查看完整版本: 羔羊引擎之羔羊皮肤以按钮为例

感谢所有支持论坛的朋友:下面展示最新的5位赞助和充值的朋友……更多赞助和充值朋友的信息,请查看:永远的感谢名单

SGlW(66139)、 anghuo(841)、 whdsyes(255)、 longxia(60904)、 囫囵吞澡(58054)

下面展示总排行榜的前3名(T1-T3)和今年排行榜的前3名的朋友(C1-C3)……更多信息,请查看:总排行榜今年排行榜

T1. fhqu1462(969)、 T2. lwlpluto(14232)、 T3. 1367926921(962)  |  C1. anghuo(147)、 C2. fdisker(27945)、 C3. 囫囵吞澡(58054)