用FlashCS3开发透明的AIR(Apollo)应用

该方法适用于所有不习惯Flex或者暂时不希望介入Flex Builder2、3开发的开发人员。转载请保留出处:用FlashCS3开发透明的AIR(Apollo)应用 – http://www.awflasher.com/blog/archives/947

【更新】开发步骤详细截图(共19张)我发布在as3blog.com了:忘记MXML,用CS3携Apollo起飞!(http://as3blog.com/as3/cs3-develop-air)

虽然我们并不使用Flex3作为开发环境,但我们需要准备Flex3和Flex3 SDK,这可以在Adobe官方找到。其缘由是,我们需要用Flex3作为AIR文件的发布工具,而Flex3 SDK,可以为我们提供一个非常重要的swc文件:airglobal.swc。我们需要采用这个ariglobal.swc的文件,替换Flash CS3安装目录中的“enConfigurationActionScript 3.0Classesplayerglobal.swc”,这一步非常重要。因为我们需要让FlashCS3的编译器知道,AIR的Runtime所提供的API。否则,在FlashCS3中所有对AIR的API调用将是不能通过编译器编译,进而无法生成SWF文件的。

然后,我们回到Flex Builder3中。建立一个AIR项目,并且修改AIR项目的配置xml文件(你的AIR项目如果是MyAir那么你的AIR配置xml文件将是MyAir-app.xml),找到rootContent结点,例如我的项目叫做“awflasher”,那么在xml文件中,会有如此一段内容:

<rootContent systemChrome="none"transparent="true" visible="true">awflasher.swf</rootContent>

这其中的“awflasher.swf”就是我们通过Flash CS3编译得到的。回过头我再解释一下为什么要copy那个airglobal.swc覆盖playerglobal.swc,是因为,我们在Flash CS3中,可能会有如下的代码:

awflasher_mc.addEventListener(flash.events.MouseEvent.MOUSE_DOWN, go);function go(someEvent)
{
stage.window.startMove();
}

其中的stage.window.startMove中,无论是window对象还是startMove方法,都需要AIR的API提供支持。虽然AIR Runtime显然会提供支持,但是Flash CS3的编译器在之前的playerglobal.swc中是无法辨别这些API的。因此才需要刚才说到的那一步。

后附实际运行截图以及AIR文件如下: Continue reading “用FlashCS3开发透明的AIR(Apollo)应用”

gotoAndLearn.com的Flash视频教程全套下载公布

由于要将下一代平台迁移到Apollo上,gotoAndLearn.com的Lee Brimelow放出了他多年来精心准备的FLV视频教程直接下载地址。大家可以方便的全部下载了。记得每天看两段,提高英语,也提高技术:)

Lee是一位了不起的前端技术研究专家,他在Flash的各个领域均有试验项目,并同时介入了WPF的探索中,开通了theflashblog.com和thewpfblog.com两大blog。

如同好的程序员应该同时掌握Java和.net一样;好的前端工程师也应该同时掌握Flash/Flex和WPF。

创建基于Flash技术弹性布局的Web应用程序

转载请保留出处:http://www.awflasher.com/blog/archives/822

在James O’Reilly出看到《Creating Liquid GUIs with Flash》一文,颇有感慨。其实很早我就考虑用Stage.onResize来实现动态布局的应用程序设计了,只不过一直没有系统地考虑过如何设计一些细节。James给出的类固然很强大,但是也觉得有点儿复杂,就简化了一下。

我把基本的功能封装成了一个“Liquid” 类,配以静态方法和静态属性,一来我觉得一个应用程序基本上都是在_root级进行模块划分,另一方面也算是为了和“Stage”类“遥相呼应”。再者,这里写的太复杂我想也会增加阅读的难度,毕竟我是想简述一个设计思想。最完美的解决方案我认为是模仿XHTML/CSS那样,任何MC都可以有自己的top、padding这种属性。但目前看来要用ActionScript写一套这个太麻烦了。等Apollo吧,反正快出来了。

OK,言归正传,首先简述一下Flash的内置类:Stage。Stage类有一些静态属性,其中最重要的就是align、scaleMode以及width和height,这四个属性配合onResize事件广播,就能完美地部署应用程序界面了。其原理就是,当swf在渲染层的尺寸改变的时候,Stage类会广播一个“onResize”事件,只要一个对象具有onResize方法,或者一个MovieClip具有onResize函数;更简单地,当前时间轴有一个函数onResize,这个方法、函数就会执行。而通过函数体中对Stage.width, Stage.height的引用,就能针对性地定位MovieClip了。值得一提的是,需要预先将align和scaleMode两个属性的值分别设置成“TL”和“noScale”后,应用程序就不会因为外界swf的拉伸而变形,而且基准中心永远在左上角,即左上角的坐标永远是(0,0),这对于我们定位其他资源是非常有意义的。

我将这些逻辑封装成Liquid类,来完成一些基本的设置。在时间轴上,调用一次Liquid的_init方法,让align和scaleMode预设置为以上提到的“TL”和“noScale”,然后将Stage的listner指向Liquid类的另一个静态方法onResize;另一方面,有addMC方法来保存所有需要绝对定位的MovieClip,开发者传入MovieClip的实例引用和一个绝对定位描述对象,并将这个描述对象最为这个MovieClip的一个实例属性,就能将这个“预定位置了的”MovieClip加入Liquid类的一个监听对象集合。

而在onResize中,去遍历这个集合,能得到MovieClip的实例指向和它的位置描述,这样每次外界舞台尺寸变化的时候,就可以重新按照预定的位置描述来分配位置了。

这里公布的Liquid类,只能算作抛砖引玉,可以针对诸如“边距”一类的属性(margin)再做一些扩展,当然,还是期待Apollo能轻松实现这些定位(基于CSS描述的MovieClip,不知道是不是YY了一点儿)。此外,Flex2是否有相应的package,由于我没有深入接触Flex,不得而知,如果有现有的package,拿过来直接用也不错。

Liquid类源码: Continue reading “创建基于Flash技术弹性布局的Web应用程序”

状态机-简单、重要、高可应用性的思想

转载请注明:http://www.awflasher.com/blog/archives/534

其实在数字电路中就已经介绍过这种模型,包括后续的“信息论”、“随机过程”等课程中,也介绍到了这个模型中的一些基本概念。可是平时在课堂上学过了,没有实际应用确实难以记住。这次在师弟Xophiix(http://www.xophiix.com.cn)处看到状态机一文,发现确实能将这一概念运用到Flash的交互开发中。Xophiix虽然仅仅是大二的学弟,但是有着非常强烈的创新欲望和实践经验。所谓三人行必有我师,这次这个“状态机”,确实帮了我那个挫的不能再挫的“是男人就下100层”的大忙。

言归正传,来介绍如何使用状态机模型进行开发。

首先,要明确什么叫做状态(Status)。我不想引用什么字典里的解释,那样只会将这里的问题复杂化。举例说明最方便。就拿我这个游戏来说,玩家所扮演的小人,就存在三种状态:小人跑动(move)、小人站立静止(stand)、小人在空中坠落(falling)。为了配合下面的代码实例,我简记为move, stand, falling,下同。图中分别用橘黄标示为A,B,C。

状态的一大特性就是转化。状态不是孤立的,换句话说,状态是变化的,是会互相转化的,比如,move可以转化到falling;falling可以转化到stand。
值得一提的是,转化有两条原则:
·转化本身的逻辑性 – 并非所有的状态之间都可以任意转化,这里stand就不能变化为falling,因为小人不可能站在挡板上不动自己掉下;而falling也不能转化为move,因为小人掉下的途中不可能跑动(脚踩空),而必须通过一次stand,再跑动。

转化的外界因素 – 转化的时候需要一个外因,这里四种转化,我用数字表示为1,2,3,4,意义分别是
1、移动出了挡板,从空中坠落
2、坠落途中掉在挡板上,站立
3、用户按左、右键,或者掉在了有“方向履带”的挡板上,小人跑动起来
4、用户停止按键并且小人站在非“方向履带”的挡板上,小人站立

这两条原则总结完了之后,就好设计程序了。但是在设计程序之前,一定要把这几个状态以及转换原则疏理清晰,如果你连一共有几种状态都分不清楚就开始写代码,那肯定有更多的麻烦等着你。

while-switch的方法可能是VC程序员最熟悉的了,前文提到的Xophiix的blog中可以看到。不过在Flash中,还是onEnterFrame-switch比较方便。毕竟Flash是按frame渲染的,用onEnterFrame的循环在资源消耗上有着很大的优势。代码如下,保留了整个小人的Action,状态机核心在中间加粗部分:

getPlayer.onEnterFrame = function()
{

if (this.isTowardLeft == undefined)
{
// 是否站在履带上
xinc = 0;
}
else if (this.isTowardLeft)
{
// 左旋转履带
xinc = -1;
}
else
{
// 右旋转履带
xinc = 1;
}
if(Key.isDown(Key.LEFT))
{
//按下左件
xinc -= spd;
}
if(Key.isDown(Key.RIGHT))
{
//按下右件
xinc += spd;
}    switch( statusNow )
{
case “stand”://站立状态
if( xinc != 0 )
{
//如果x轴向增量不为零,代表人应该移动了
this.gotoAndPlay( “move” );
statusNow = “move”;
//跳转到移动状态
break;
}
break;
case “move”://移动状态
if( !this.isOnLand)
{
//如果人不在挡板上,则坠落
this.gotoAndStop( “falling” );
statusNow = “falling”;
}
else if( xinc == 0 )
{
//如果x轴向增量为0,则站住
this.gotoAndStop( “stand” );
statusNow = “stand”;
break;
}
break;
case “falling”://坠落状态
if( this.isOnLand )
{
//如果人掉在挡板上,则转化为站立
this.gotoAndStop( “stand” );
statusNow = “stand”;
break;
}
break;
default:break;
}

//简单物理模型的建立,参考了ox_darkness师兄@Flash8
if( statusNow == “stand” )
{
yinc = 0;
this._y = this.receiveTarget._y;
}
if( statusNow == “move” )
{
yinc = 0;
this._y = this.receiveTarget._y;
if( xinc > 0 )
{
this._xscale = -Math.abs( this._xscale );
}
else if ( xinc < 0 )
{
this._xscale = Math.abs( this._xscale );
}
if( xinc != 0 )
{
this._x += xinc;
}
if( statusNow == “falling” )
{
this._y += yinc;
}
}
if( statusNow == “falling” )
{
yinc+=0.15;
this._y += yinc;
if( xinc > 0 )
{
this._xscale = -Math.abs( this._xscale );
}
else if ( xinc < 0 )
{
this._xscale = Math.abs( this._xscale );
}
if( xinc != 0 )
{
this._x += xinc;
}
}
if (this._y > sceneh || this._y < -5)
{
gameOver();
}
}

记录被各大网站收藏的原创文章

被泛滥地垃圾网站转载,肯定不是什么光荣的事情,我发现很多编辑把一些基本的东西都搞乱了,整个就是胡乱贴过去。这样不仅害了读者,也是对作者的极大不敬。然而大站转载,不但保留原文出处,更是细心编辑版式,不失能作为对自己的鼓励。

当然,任何文章都会遭来砖块,这个我是有心理准备的。我希望真正有高手,能用砖块能砸中我的每一个疏漏,让我受益,更让读者受益。
产品线体验 – 不止是用户体验
@ZDNet

Apollo开发的商业前景及革命(

@ ZDNet、ZDNet

Adobe的新产品线策略 @ CSDN

理性思考Flash与Ajax相关问题
@ 蓝色理想

背叛时间轴·突破IDE
@ 蓝色理想 | 闪吧

完美的loading—完美到底(三篇连载)
@ 蓝色理想 | 闪吧

鼠绘技巧
@ 闪吧

全局变量让你告别繁琐的路径
@ 闪吧

闲扯一些Flash小技巧
@ 闪吧

Webservice使用实例-各地天气预报|各国货币转换
@ 闪吧

with语句指向自身的小办法
@ 闪吧

多功能PageRank显示插件
@ 闪吧

坐标非整数时的像素化
@ 闪吧

由Flash中的异步、同步联想到setInterval的一些用法。

本文原创 by awflasher.com 做人要厚道,转载注明出处http://www.awflasher.com/blog/archives/496

今天去了一趟书店,看了很多Flash的书,那叫一个垃圾。倒不是说写得不好,而是有些地方明显回避。其实骂“垃圾”主要是因为看到一些立着“难点”、“高级”牌坊的书。一遇到真正麻烦的情况,就撤了。买“突破难点”就是为了了解难点如何突破嘛,那些众人皆知的事情本应该是另外相关入门书的任务。比如 setInterval ,几乎没看到一本负责任讲得深入的。

当然,我并不是通过“贬低”这些不负责任的作者们来提高自己,在Flash中控制异步同步并非我的长处,所以肯定会存在一些问题!我也希望希望大家多多提出自己的评论、想法。

言归正传:其实异步、同步的问题在Flash开发中,似乎并没有引起太多人的关注。一来设计师们认为 loadMovie 这样的东西封装得很好了,根本不需要深入考虑其细节,即便是更加复杂一点的工程,用 MovieClipLoader 来运筹帷幄,似乎在异步、同步的问题上也没有遇到什么麻烦。

异步、同步,并不能简单说哪个好,哪个不好。要是站在易用性、用户体验的角度来说,异步当然更好。每一次的操作不必等待其他请求就能直接给予用户反馈。当然,也不能完全异步操作。细节到一个集成电路的运作,大到使用某应用程序完成某一项工作,都不可能每次都在上一件任务都不做完的情况下就匆匆执行用户的下一个指令。特别是Windows图形界面的出现、网络通信工具的出现以及AJAX的大张旗鼓的宣传,人们似乎已经忘记了计算机内核最稳定以及最基本的同步运算原理。
Continue reading “由Flash中的异步、同步联想到setInterval的一些用法。”

背叛时间轴·突破IDE

背叛时间轴·突破IDE – 改了一两个错别字,并且给出了loading解决方案(最后)

首先我想要申明,这个标题确实夸张了。只是希望通过这种夸张能引起各位不愿意重视ActionScript的Flashers的注意。

其实每一个Flasher,特别是经历过Flash4、Flash5的这一批人,都是常年通过时间轴来部署作品界面的。包括我自己,对时间轴的熟悉也经历了一个比较长的过程。这个过程中,我也距离Flash的思想越来越近。

先说说IDE的概念吧,相信对于一个界面或者动画设计师来说,IDE绝对是一个足够陌生的名词。其实,我们每天用到的Flash就是一个IDE环境。我在这里更准确地引用如下概念,相信看完后IDE这个词将不再陌生:

集成开发环境(Integrated Development Environment,简称IDE),又名集成编程环境或可视化开发环境,是为方便软件开发人员进行开发而设计的软件,一般针对某一编程语言开发,大多数为界面友好的可视化环境,一般整合源代码编辑器、调试器、编译器和资源编辑器。

显然,时间轴是IDE的一部分,但我更愿意把时间轴分离出来强调,甚至适度夸张地批判。因为有时候时间轴确实笨重的。如果您不是一个逐帧动画高手,而是一个以开发Flash应用程序(尤其是游戏)的设计师,我想时间轴许多情况下所表现的特性显得十分尴尬。比如MotionTween看起来只有两个关键帧,其实之间的渐变帧都是要耗占文件体积的。

此外,有很多情况下,我们需要动态的管理一些场景上的元素。如果用时间轴,我想恐怕只能用最土的gotoAndPlay、gotoAndStop配合使用了。当然,在Flash4、Flash5时代,确实造就了一批顶级高手,他们仅用gotoAndPlay来完成任务,这些人有着严谨的逻辑思维能力和极好的心态。然而到了MX时代,尤其是MX2k4时代,AS的飞跃发展,导致之前的这种天才设计模式沦为一介莽夫之举!

Flash5中attachMovie的出现,无疑是一场革命性的发展。可惜那个时候用attachMovie的人并不多,因为相比时间轴,它确实挺麻烦的。由于项目需求在那个时候与现在不同,时间轴效果仍然是主流的开发手段。

MX时代最大的革命我印象最深刻的其实是IDE。Flash5中愚昧的面板到了MX变得那么乖巧听话。MX时代的到来引发了一场Flash制作风暴,越来越多的人(主要是动画制作为主)加入到Flasher这个队伍中来。可惜后来MX2k4和8改变了界面,其实我个人挺喜欢MX的IDE界面设计的!(不知道以后会不会推出一个可制定IDEskin的怀旧版)

MX和MX2k4的推出,使得AS更加规范,项目需求的改变,导致时间轴的效果越来越显得捉襟见肘了。更多的人开始投入动态部署场景的行列,然而值得一提的是,有一些老一辈Flash设计大师似乎仍然不为之所动,MM推出的时间轴特效更是MX2k4的一大败笔。当然瑕不掩瑜,AS2.0给MX2k4予以无限光芒,这段时间涌现了大量的AS-coder,水平参差不齐,不论如何,这是另一场革命!

这个时代中,项目需求又有所变化,越来越多的复杂的应用程序要通过Flash来完成,要不是半路杀出一个AJAX,我怀疑Javascript真的要被Actionscript盖住光芒了。我自己独立完成的56涂鸦也是使用的MX2k4完成的。

现在到了8,虽然AS没有实质上变革,但项目需求又一次提高,时间轴完全不能独立部署一个优秀的应用程序了。更多的人开始关注Actionscript,开始关注attachMovie这样一个曾经被我们因“麻烦”而嫌弃的语句。

不想太纯粹的讨论技术,于是发了以上一些胡言乱语,现在还是简单介绍一些attachMovie吧。

首先,要明白Flash的基本编译原理。SWF文件中的内容无疑主要来自于库,这个概念相对大家都不会陌生(就是Library)。库中包含了所有的时间轴引用的元件,当然_root也是一个MC元件,它也包括所有的在IDE中的零散图形。剩下的内容就是库中含有linkage ID的元件了。这些元件就是attachMovie的最重要的操作对象!

不想强调太多的理论知识,因为这些内容都可以在帮助文档中找到。我想结合自己的开发经验谈一谈:

首先,attach的内容,尽量不要attach到_root下。因为本来就是要动态的管理MC,如果清一色放到_root下,会导致分类不明确,很难高效率调度、管理MC。我建议在_root下动态建立一个MC。比如,你有一个游戏中,要防止对手和友军,那不妨就建立两个MC容器“NPC_mc”“Enemy_mc”,然后再对这两个mc进行attache:

var NPC:MovieClip = _root.createEmptyMovieClip("NPC_mc",1);
var EMY:MovieClip = _root.createEmptyMovieClip("Enemy_mc",2);
for (var i=0;i<iMax;i++)
NPC.attachMovie(....);
for (var j=0;j<jMax;j++)
EMY.attachMovie(....);

其次,由于是动态建立MC,很多时候我们无暇管理深度,Macromedia Flash 2k4以来,提供了一个非常重要的方法:getNextHightestDepth(),这个方法可以找到当前MC中最深的一个深度,然后以Number型返回。

~~转载请保留原文地址:http://www.awflasher.com/blog/archives/472
这样一来,我们经常会看到2k4版本后的一些“模版式”代码:

//某循环内
var d:Number = this.getNextHighestDepth();
this.attachMovie("someLibStr","myMC"+d,d);
//某循环内

显然,代码简单易懂,非常适合动态部署大量的MC(配合循环)

动态地删除则是removeMovieClip,这个语句非常简单,就不赘述了。

最后整理一些常见问题:
·库中的连接名给错
·自命名没有随层级变化而变化,强烈推荐用一个名词+深度来命名。
·深度序号未定义,造成MC指向undefined
·母MC未定义(这个容易在含有function的情况下出现)

所有这些问题通过trace绝对可以找到,大家多点耐心就行了。关于loading的问题,参V2组件loading地解决方案。

最后祝大家顺利突破IDE、打破时间轴的限制!

[技术]原创-完美的loading-完美到底[减负]

V2,也爱,也恨!这里介绍关于含有V2组件项目的loading问题
转载请注明原帖:http://www.awflasher.com/blog/archives/468

V2组件自面世以来就颇受争议,大体概括如下:

优点:
·界面比V1组件更加美观、统一,人机交互模式更加完善
·均采用面向对象脚本部署

缺点
·体积笨重,开发一些只用到一两个组件的小应用程序时很尴尬

消息机制方面使用EventDispather的消息广播机制,取代原有的AsBroadcast机制。使得刚出来的时候很多人根本不会用。

这里就不讨论更多了,先说loading。含有大量v2组件的产品要想见人肯定是不能不作loading的,比如aw’s blog左边的那个blog小贴士。然而每次在loading的时候似乎都会遇到麻烦。那就是笨重的体积全部被放到第一帧导出了,这样导致对一些300k以内的,含有v2组件的SWF文件进行远程载入的loading效果变得捉襟见肘

解决的办法也不是没有,简单概括为三个步骤:

一、去掉“Export in first frame”
V2-Component-Loading

二、在发布的时候设置一下“Export frame for classes”,这一点非常重要!
V2-Component-Loading

三、对于外埠读取的含有V2的swf文件,将容器mc进行如下设置:

loader_mc._lockroot = true;

好了,现在放心享受精彩而笨重的V2组件吧~!

aw补充一点:最近在开 Continue reading “[技术]原创-完美的loading-完美到底[减负]”

[技术]原创-完美的loading-完美到底[利器]

参考英文教程,并作出大量原创补充 – Neil Webb, neil AT nwebb DOT co DOT uk, http://www.nwebb.co.uk
转载请注明原帖:http://www.awflasher.com/blog/archives/468

2006年12月19日的一个小补充:关于onLoadInit与onLoadComplete的细节对比(文末)

读取外埠数据参与Flash应用程序部署是一件非常重要和常见的工作,尤其是我们常常需要检测这些数据加载的进度。传统的做法是采用loadMovie的方法,不过这种方法需要对被载入的外埠资源进行太多的预先性操作,当外埠资源不可知或者不是swf文件时,loadMovie显得无能为力。而MovieClipLoader(下称MCL)类却帮我们大大简化了这项麻烦工作。此外,它使得我们能获取更多的需要,并减少代码量。我们可以用一个单独的MCL类来载入一个,或者多个外埠资源到指定的MC或者层级,或者我们可以为每一个加载工作制定不同的MCL实例。

我决定分两部分来完成这篇教程。首先,我们将介绍MCL的基本用法;然后我们将介绍如何使用一个单独的MCL实例来读取外埠资源到不同的MC,并且,我们将加入侦听器对象来参与工作。当然,不通过侦听器也可以完成任务,我们暂时不介绍侦听器,因为这样你会更加容易理解MCL。

那么,我们首先来大体了解一下MCL有哪些回调函数,后面也会有详细介绍(aw附:回调函数我个人理解就是某一个类组、参数事先确定,拥有指定功效的方法;再详细点说,从字面上看,所谓回调,就是指先定义好,等某些时刻需要的时候,回过头来调用。也就是特定的事件触发函数)这里可以了解一下什么叫做回调函数):
Continue reading “[技术]原创-完美的loading-完美到底[利器]”

[技术]原创-完美的loading-完美到底[基础]

很久没有发技术日志了,要来就来个完美的。您别激动,一个小小的loading谈什么完美,我想你看了就知道^_^
我的口号,将此文打造成全球最完善的非Flash初学者loading教程贴。转载请保留原文地址:
http://www.awflasher.com/blog/archives/444

首先,想说一下我写此文的动机。记得很早之前我曾经说过“没有loading的flash,不是完整的flash”。我想那个句话可能偏激了。因为有时候一些不到10k的flash,确实不需要做什么loading。但我始终认为,做一个优秀的loading是衡量一个flasher水准,甚至态度的。你问我为什么,我可以告诉你,因为loading是唯一一个你不会多看而所有用户、客户会看的东西,所以你对loading的重视程度,甚至可以反衬你这个flasher的职业道德!

有些做设计为主的朋友,我认识不少,他们对loading都是得过且过的态度,做一个loading,更多的是自己找一个现成的,然后每次去套用,我个人认为是很不好的习惯。并不是说我不提倡代码、元件的重用度,而是我觉得对于loading这种东西,套多了,是要出问题的。我强烈建议那些已经达到可以修改人家loading水平的flasher看看我的东西,当然,如果你连flash的as该写在哪都不知道,建议先入门了。

好,下面切入正题,如何制作loading。

首先要感激Macromedia的大智慧,提供了很好的两个函数使我们可以做出完美的loading,那就是getBytesLoaded和getBytesTotal。请不要再用你改来改去改了两三年的那个什么getFrameLoaded什么什么了,我都记不清楚怎么拼了。我只想说, Continue reading “[技术]原创-完美的loading-完美到底[基础]”