About

<#TEMPLATE_INCLUDE_NINEPAGE_ABOUTME#>
  • Jun

    23

    Adobe 公司最新推出的 ATF 工具引入的一个全新的图像文件格式:ATF(Adobe Texture Format)。深入地了解一下看看它到底产生什么样的图像可以便好的使用它。 

    ATF 实际上集合了三种其它的贴图格式:用于 Windows,Mac OS X 以及某些安卓设备上的  DXT1 格式;用于其它安卓设备上的 ETC1 格式;还有用于 iOS 上的 PVRTC 格式。因此一个 ATF 格式文件可以在任何能够运行 Flash Player 或 AIR 的地方工作。另外,第四种图片格式也会被使用:JPEG-XR。这个与LZMA 压缩算法相结合来降低文件的大小。将三种图片打包成一个往往文件的尺寸会增大。每种子文件格式图像质量都会稍有不同(具体细节不同之处可以查看原文:http://jacksondunstan.com/articles/2013,含示例图以及图片具体大小数据的对比),在大多数 3D 场景中质量的降低是可以接受的。

    简单来说, 一个好处是可以做到不使用 mip-maps(例如:为已知显示距离或者 2D 的图片进行压缩),那么你可以节省约 25% 的文件尺寸。如果恰巧知道应用程序将要运行的目标设备,可以节省掉更多。例如,只是将应用程序部署到 iOS 上,那可以只压缩为 PVRTC 格式。这通常会将文件的大小削减到三分之一,因为其它子格式被去掉了。如果能够舍弃 mip-maps 并且只使用一种子格式,那就更好了。

    PNG2ATF 工具使用方法:

    # All sub-formats. All mip-map levels.
    png2atf --i image.png -o image_all.atf

    # All sub-formats. No mip-map levels.
    png2atf --0,0 -i image.png -o image_all_nomip.atf

    # Only DXT. All mip-map levels.
    png2atf -c d -i image.png -o image_dxt.atf

    # Only DXT. No mip-map levels.
    png2atf -c d -0,0 -i image.png -o image_dxt_nomip.atf

    # Only ETC. All mip-map levels.
    png2atf -c e -i image.png -o image_etc.atf

    # Only ETC. No mip-map levels.
    png2atf -c e -0,0 -i image.png -o image_etc_nomip.atf

    # Only PVRTC. All mip-map levels.
    png2atf -c p -i image.png -o image_pvrtc.atf

    # Only PVRTC. No mip-map levels.
    png2atf -c p -0,0 -i image.png -o image_pvrtc_nomip.atf

    原文链接:http://jacksondunstan.com/articles/2013

    译文链接:http://bbs.9ria.com/thread-159763-1-1.html

    Adobe 官方 ATF SDK 压缩纹理简介:http://www.adobe.com/cn/devnet/flashruntimes/articles/introducing-compressed-textures.html

    Jun

    22

    Adobe Texture Format(简称 ATF)是 Flash 运行时 Stage3D API 固定纹理资源使用的推荐文件类型(也是现在其它一些 3D 类纹理资源的推荐文件类型)。

    Adobe Texture Format (ATF)工具用户指南:http://www.adobe.com/cn/devnet/flashruntimes/articles/atf-users-guide.html

    Jun

    22

    基于Starling框架的AcheGesture是为基于Adobe AIR技术的移动应用提供的一套手势识别库。设计来源于苹果iOS开发框架的UIGestureRecognizers(Cocoa-Touch UIKit)。AcheGesture主要特性:

    1、提供了最基本的几种手势,包括:Tap(轻击)、Double Tap(双击) 、Pinch(缩放)、Pan(拖拽)、Swipe(滑动)、Rotate(旋转)以及Long press(长按)。

    2、提供针对每种手势的自定义配置,例如Long press的判别时间阈值(timeThreshold)。

    3、处理手势之间的识别依赖(requireGestureRecognizerToFail)、识别优先级(priority)、同时作用(allowSimultaneous)等相互关系。

    4、使用回调的机制传出手势(离散和连续)的所有识别状态:recognized、possible、failed、began、changed、ended和cancelled。

    5、可扩展性,可以针对项目需求写手势识别扩展(GestureRecognizerPlugin),并动态注入(activate)。

    6、开源免费,可在任何场合和情况下使用。

    为何要写AcheGesture

    1、代码复用的需求:

    Starling提供了Touch事件,包括了单点和多点的。但是对于某个具体的手势却没有做封装,例如常见的Swipe。对于每一种手势实现后的代码逻辑复用是最基本的封装需求。

    2、手势识别复杂的依赖关系处理的需求:

    第二个原因,也是非常重要的原因就是处理多种手势关系的需求。例如一个显示对象绑定了一个单击(Tap)和一个双击(Double Tap),用户轻击两下,有以下可能:1、两个Tap和一个Double Tap,2、一个Tap和一个Double Tap 3、两个Tap,4、一个Double Tap。吃惊吗?竟然有四种,而且第2种可能相对比较难理解什么情况下发生的。其实一般情况下,我们期望得到的是第3和第4种。这就出现了手势识别依赖关系的需求。也就是说,Tap手势的识别依赖于Double Tap手势识别的失败(requireGestureRecognizerToFail)。通俗的说,就是,只有识别不出来Double Tap,Tap手势才能识别。多种手势的相互依赖关系使得手势的处理上复杂度提升,使得需要封装这样的逻辑统一处理。

    3、多手势同时作用的需求: 

    这也是一个非常常见的需求,但是如果只是一个Touch对象可能不能很方便的实现。就是例如使用Pinch手势的缩放的同时,还可能在Pan(拖拽移动)甚至还有可能使用Rotate同时进行旋转操作。

    如何使用AcheGesture

    Step1: 定义手势对象: 

    以轻击(Tap)手势为例,此手势包含了两种状态,“识别”(recognized)和“可能识别”(possible),在TapGesture配置类中定义。所以首先定义手势对象,传入每个状态的回调函数。

    private function linkGesture():void
    {
        var g1:Gesture = new TapGesture(onTapRecognized, onTapPossible);
    }

    此处有两个回调函数,onTapRecognized和onTapPossible。对于这个手势的定义,其实也可以直接使用Object类型,这个对象需要包含各种识别状态的回调函数,例如”recognized”, “possible”等等。以刚才的那个Tap手势为例,g1可写成以下这种形式:

    var g1:Object = {"recognized": onTapRecognized, "possible": onTapPossible};

    建议使用acheGesture.data包下面的类型来定义每一种手势,除了有强类型提示的好处以外,也可以方便或者每种手势所包含的手势状态。以轻击(Tap)手势而言,就只有“识别”(recognized)和“可能识别”(possible)两种状态。

    Step2: 绑定显示对象

    接下来是使用GestureManager.add方法绑定定义的手势和目标显示对象。如下所示:

    private function linkGesture():void
    {
      var g1:Gesture = new TapGesture(onTapRecognized, onTapPossible);
      GestureManager.add(_btn, new GestureVars().onTap(g1).vars);
    }

    三个参数,第一个传入绑定的显示对象(Starling.display.DisplayObject),第二个传入的是手势识别的配置对象,第三个参数是是否允许多个手势同时作用。和定义手势对象类似,此处使用的GestureVars去对配置属性进行强类型,其实也可以使用Object直接配置,如下代码所示:

    GestureManager.add(_btn, {"tap": g1}, false);

    所以如果都使用Object类型就可以简化写成:

    GestureManager.add(_btn, {"tap": {"recognized": onTapRecognized, "possible": onTapPossible} }, false);

    看个人喜好,建议使用acheGesture.data包下面的类型来强类型去配置手势。

    Step3: 处理手势状态回调

    所有的手势状态回调函数均接收一个参数,e: AcheGestureEvent,这个对象包含了手势状态回调会传出的一些属性,以Tap为例,在是否可能被识别(possible)状态,就是读取e.possible来确定如何显示按钮的状态。详细会在Tap手势的教程中介绍。

    function onTapRecognized(e:AcheGestureEvent):void
    {
      trace("tap gesture recognized!");
    }
    private function onTapPossible(e:AcheGestureEvent):void
    {
      trace("tap gesture onTapPossible >>>" + e.possible);
    }

    了解设置后的期望值。

    在使用手势库完成需求之前,需要了解某种绑定方式预期得到怎样的结果。以下面三种绑定方式为例,均是绑定了单击(Tap)和双击(Double Tap)只是在细节设置上不同。 

    第一种,只是单单绑定了这两种手势,但是注意点是,add方法第三个参数传的是false,也就是说,同一个时刻不能多个手势同时作用,因为Tap和Double Tap都是在用户Touch Ended的时候来判断,所以,如果用户轻击两下,间隔时间符合双击,则收到一个双击,一个单击。注意是一个单击,因为第二个单击在判断的时候被双击优先判断了,所以不被识别。注意比较下面两种情况。

    private function linkGesture1():void
    {
      var g1:Gesture = new TapGesture(onTapRecognized);
      var g2:Gesture = new DoubleTapGesture(onDoubleTapRecognized);
      GestureManager.add(_btn, new GestureVars().onTap(g1).onDoubleTap(g2).vars,false);
    }

    第二种情况比较简单,就是,设置了add第三个参数为true,即,允许同时多个手势被识别,如果还像上一个那种操作情况,用户轻击两下,并且间隔时间符合双击的要求,则收到,两个单击和一个双击。也就是说这两种手势的识别互不干扰。各自识别各自的。

    private function linkGesture2():void
    {
      var g1:Gesture = new TapGesture(onTapRecognized);
      var g2:Gesture = new DoubleTapGesture(onDoubleTapRecognized)
      GestureManager.add(_btn, new GestureVars().onTap(g1).onDoubleTap(g2).vars, true);
    }

    第三种情况其实可能是我们想要的,就是设定了“依赖关系”,单机的识别依赖于双击的识别失败。还是像刚才那样操作,用户轻击两下,并且间隔时间符合双击的要求,此时收到的只是一次双击,没有单击。如果用户轻击一下,则在延迟一小段时间后收到单击。原因是,单击的识别需要等待双击识别失败(超过双击的时间间隔阈值)。

    private function linkGesture3():void
    {
      var g1:Gesture = new TapGesture(onTapRecognized);
      var g2:Gesture = new DoubleTapGesture(onDoubleTapRecognized)
      g1.requireGestureRecognizerToFail(g2);
      GestureManager.add(_btn, new GestureVars().onTap(g1).onDoubleTap(g2).vars);
    }

    不同的设置带来不同的结果,了解自己需要的结果和对应的设置方法才能正确使用AcheGesture。

    备注:

    其它关于 AcheGesture 的链接(含DEMO):《Adobe AIR 移动开发:触摸、多点触控和手势输入》。

    原文链接:http://www.tuicool.com/articles/UviyMr

    Jun

    11

    Graphics 非实时的绘图方法

    • 1 Comments
    • Flash Platform

    在 Flash IDE 环境下的舞台中,绘制任意一个矢量图形,并选择库中的任意一张位图填充,当该位图通过右键属性更新位图时,舞台上矢量图形的填充位图将会同步更新。但这种更新仅限于 IDE 的库元件编辑状态,并不代表 swf 文件在运行时 Graphics 也是实时更新位图数据填充的。

    事实上,Graphics 的所有绘画方式生成的矢量图形填充位图后都是静态的,“非活动/非实时”的(不同于 Bitmap 与 BitmapData)。如下样例代码:

    var b:BitmapData = new BitmapData1();

    stage.addEventListener(MouseEvent.CLICK, click);

    var g:Graphics = this.graphics;
        g.beginBitmapFill(b);
        g.drawRect(0,0,1000,1000);
        g.endFill();

    function click(event:MouseEvent):void
    {
        b = new BitmapData2();
        /*
        //如果不通过以下代码进行重绘,绘制的图形是不会动态更新填充的位图数据的
        g.clear();
        g.beginBitmapFill(b);
        g.drawRect(0,0,1000,1000);
        g.endFill();
        */

    }

    Graphics 要点:

    1、Graphics 绘图方法生成的矢量图形层级深度小于 0,任何层级深度小于 0 的对象在 AS3 中是无法获取引用的。

    2、每一个 Sprite 或 Shape 类型的对象都拥有唯一一个 Graphics 对象的引用(注意 Graphics 对象本身不是图形对象,它只是提供了绘制图形的方法)。

    3、Graphics 的绘图方法的每一步操作都会通过“记录”的形式被保存于 Graphics 对象中,操作的次数越多,记录的次数就越多,越占用系统资源。

    4、调用clear() 可清空一个 Graphics 对象的所有绘图操作记录,释放系统资源。 

    4、copyFrom(sourceGraphics:Graphics) 方法复制的是一个 Graphics 对象绘图操作“记录”,而不是图形对象本身。

    Jun

    9

    利用 AS3 进行 XMP 开发

    • 0 Comments
    • Flash Platform

    利用 AS3  对文件进行 XMP 元数据操作(如读取图像文件的 EXIF 信息,对 jpg/jpeg、tiff、png、pdf、psd、ai 等文件进行元数据的读写)。需要特别注意的是,这个类库截止目前为止还处于开发阶段,所以如果对重要文件进行元数据进行“写”或“修改”操作之前最好对文件先进行备份,因为它有可能会损坏文件。

    Adobe 官方 XMP 开发者中心:http://www.adobe.com/devnet/xmp.html

    Google 项目中心:https://code.google.com/p/as3-xmp-file/

    Jun

    4

    “接下来不开心的时候,就想想那些在学ObjC的人……”

    6 月 3 日凌晨,苹果推出了最新的编程语言——Swift,新的 Swift 语言比 Obejective-C 和 Python 还要快(按照官方给出的 Benchmark 数据上写为比 OC 快3倍,比 Python 快9倍,官方统计一般都会含水份,所以打个对折吧),语句更加简洁高效,将降低应用开发门槛,更讨开发者喜欢。

    尽管只是通览了一下官方的几段 Swift 样例代码,但可以看出,Swift 虽然看起来像是个杂揉了众多语言的语言,但它剔除了其他语言大部分弊端,不仅能让初学者更容易入门,尤其是对已经拥有其它多年开发经验的不同语言开发者,转到 Swift 也变的更加熟悉和简单了(一些已经熟练使用其它语言的开发者在刚接触 OC 时大多会有抵触情绪,而对 Swift 大多则很容易接受)。

    与其把脚本语言通过标准变成更好的编程语言,不如把编程语言变成更像脚本语言。OC 就像传统木工的锯、斧、刨等手工工具,在经历了大修大补,小修小补,尤其是 XX SDK 之类版本不断变化之后,Swift 就像是在一次工业革命暴发中带来的一体化加工车床。而且完兼容旧的 OC 语言框架,不得不说苹果公司的产品就是人性化。

    看到这种语言的时候 Flash AS3 的开发者们应该最为熟悉吧,虽然 AS3 这种语言看起来有点冷门,在编程语言排行上目前最高时期也从未超过 18 位,但这 Swift 几乎就是当初被 Adobe 抛弃的 “AS4 规范”的实现。连同 Flash 的生成文件 SWF(ShockwaveFlash 文件)读作 Swiff,与 Swift 发音是如此的接近(苹果公司这是想满足我们 AS4 的愿望么),Flash 开发者社区已经开始有人将 Swift 当成了 AS4 的实现,甚至有了更为疯狂的想法《一个关于 AS4 与 Swift 的疯狂的建议》。

    接下来不开心的时候,就想想那些在学 OC 的人;更不开心的时候就想想那些正在写 OC 书籍写了一半或录制 OC 视频教程录了一半的人吧……瞧人家的保密工作做的:)。

    Jun

    2

    Flex 中 CSS 样式选择器的使用

    • 0 Comments
    • Flash Platform

    Flex 4.5 以后的版本中 CSS 样式选择器的举例说明(标签选择器、类别选择器、ID选择器、交集选择器、并集选择器、后代选择器、全局选择器、伪类等)。

    More...