AsWing入门教材第三章 alpha

由于本章较长,在写完之前会先陆续发布每一节,在全部完成之后将在Flashseer上发布完整的目录

请到这里看章节目录

http://www.flashseer.org/bbs/viewthread.php?tid=589&extra=page%3D1

AsWing入门教材第二章 alpha

在本章写完之前,请到我的博客上去看草稿

http://thiswind.flashseer.org

 

AsWing入门教材第一章发布

AsWing入门教材

作者:胡矿,iiley,Bill 

 www.flashseer.org 

第一章 图形编程

1.1 概述 (http://docs.google.com/Doc?id=dnp8gdz_5wmf725

1.2 创建框架 (http://docs.google.com/Doc?id=dnp8gdz_4cnpjqp

1.3 给框架定位 (http://docs.google.com/Doc?id=dnp8gdz_3gdr96f

1.4 在面板中显示图形 (http://docs.google.com/Doc?id=dnp8gdz_63n8m3f

1.5 2D图形 (http://docs.google.com/Doc?id=dnp8gdz_13dn73pw

1.6 颜色和填充 (http://docs.google.com/Doc?id=dnp8gdz_16d63xzw

Flex Builder 3 Beta 的新功能

总的来说,包括一下一些方面:

更快的编译速度:号称快了30-40%. 不过,iiley说没什么太大感觉。

编译器类缓存: 这个就是在编译的时候能够缓存编译过,没有修改过的类,从而提高编译速度。

更好的语言智能功能(AS3/MXML/CSS): 这里就是说,FB现在对 AS3, MXML,CSS的支持已经很大程度上的改进了。可以很方便的进行重构(记得以前有人问Flashseer,问如何重构,我记得iiley说的是用FDT的查找,替换。现在鸟枪换炮了),代码查找,代码提纲(以前好像有啊),语法 高亮显示,代码自动完成。号称Flex builder的核心都给改了。

重构: 支持方法名重构,类名重构,变量重构。 就是说,你要是想把一个类名给修改一下。那么它会自动给你把用到这个类的地方用强类型引用的代码全都给你自动修改。 重构会方便很多

类提纲,就是给你一个类似于提纲的试图。不过,我记得以前有这个功能,似乎就是没有Import罢了。

代码查找: 可以全局查找变量。很是方便

分析器: 这个可是最牛的一个东西了。它可以让你知道你的代码用多少的内存,让你强行运行垃圾收集器,可以看到你的程序内部的动作。对于分析程序来说,可是很有用的。 模块支持:现在,模块和模块定位器已经被整合到Flex里面来了(以前应该是cairngorm的) 多sdk支持 可以选择用flex sdk 2.0.1,也可以用flex Moxie(flex3的codename)

原文
http://www.onflex.org/ted/2007/06/flex-3-tuesday-code-enhancements.php

Adobe 的新动作

Adobe已经把Apollo 正式命名为AIR, 并且开始提供下载。

http://labs.adobe.com/technologies/flex/
Flex 2 & 3 SDK

http://labs.adobe.com/technologies/flex/sdk/

Flex Builder 3 Beta 已经放出。
http://labs.adobe.com/technologies/flex/flexbuilder3/

Adobe(r) AIR(tm) Extension for Dreamweaver

http://labs.adobe.com/wiki/index.php/AIR:Dreamweaver_CS3_Extension

Flash Player 9 也有升级。

http://labs.adobe.com/technologies/flashplayer9/

Recent news

1, Red5 0.6 的正式版的milestone已经出来了。这就意味着Red5已经很大程度上ready for production了

2, 更牛的是一个人写了一个As3的MySQL驱动程序。 这就意味着,你可以直接通过Flash 来连接数据库。 当然了,你肯定要放crossdomain.xml才行。

不过,一般使用Flash直接链接数据库的应用一般是基于Apollo的程序,也就省去了crossdomain.xml了。

参见这里: http://maclema.com/assql/

3, APE 也就是一个AS3的物理引擎发布了0.3alpha版。 想做Flash游戏的,应该参考这个。对你的帮助绝对事很大的。不过你需要对verlet integration 有所了解。 它是一种用来模拟物理状态的计算机计算方法。 它不是通过我们平时所熟悉的动量守恒以及动能守恒结合来计算的。因为那样计算量太大。 它有一定的误差,但是绝对事在可以忍受的范围内。 它的执行效率是比通过传统物理公式求解快得多的。

FDT 3.0 五月开始封闭测试,最晚7月可以出来

http://fdt.powerflasher.com/forum/viewtopic.php?t=801

新功能包括 :

* full AS3 Support (and AS2 of course)

完整的AS3支持,当然,AS2支持仍然保留(似乎Binding这样的标签也都是支持的)
留了扩展接口,如果你是Java程序员,可以基于这个开发一些自己的功能
性能有提升
兼容Flex
格式化工具(我最烦的就是整理代码,这下好了,直接可以给你格式化, 缩进都不用自己再调了)
许多有用的改进.

Apollo 新书可以下载了

已经放到Adobe Labs 上面了:

可以在这里下载:http://labs.adobe.com/wiki/index.php/Apollo:Books:Apollo_for_Adobe_Flex_Developers_Pocket_Guide

如果你国外网速不好,也可以在我们这里下。

Google Talk in Flash on your website

Google Talk 的Team 做了一个Flash 的google talk widget.

你可以把它插入到你的网页里面去。具体方法就是往网页里面放一段javascript 代码。

这里是生成代码的页面 。

flash 版本的google talk 并没有像js版本的那样去pull服务器,只有客户端这边发送内容的时候才会去通过http协议发送内容到服务器,其他情况,似乎通过socket.
而http 部分使用的似乎是 jason 。没有使用remoting。

flash 版本的google talk 可以预览视频。

DisplacementMapFilter

这次,雪の猫 在我们的翻译区  翻译了一篇关于DisplacementMapFilter的教程。

DisplacementMapFilter是利用位图来操作位图的滤镜,对于一些高级为图操作有很大的帮助。

详情请到我们的翻译区阅读。或者直接点这里

这里下载中日对照

Apollo 发布将至?

3月16日,Adobe 将在旧金山举办一场Apollo的活动。这次的活动可能会提供给开发人员一个预览版本。这很有可能是Adobe第一次公开发放Apollo运行环境给开发人员。

这个日子的确已经很近了。

而Beta版本的Apollo 也将在3月下旬放出。看来,Apollo 真的已经走近了。

AMFPHP 1.9 Beta + C 解码编码器 = 超快速度

AMFPHP 1.9 Beta + C 解码编码器 = 超快速度

AMFPHP 1.9 加入了一个新的功能。就是用C写了一个AMF协议的解码和编码器。

这样一来,效率最高提升了许多。尤其是大的数据源的时候,用php编码可能会超时而不能完成的操作,用C 的这个extension 就可以完成。他们做过的测试有一个是在1秒之内,完成7.3MB的编码(100,000个包含三个字段对象的数组)

 

安装比较简易:

说一下在Windows下:

1,你需要下载它的那个C语言扩展:php_amf.dll 点这里

然后,解压到:{php_root}/ext

 

2,并且找到php.ini 加上一行:

extension=php_amf.dll

 

不需要对AMFPHP 本身做任何修改或者配置。他会自动监测那个扩展是否存在,存在就会自动应用,否则就会使用php的解码和编码。

 

可以在这里下载amfphp1.9 beta

来源:http://www.5etdemi.com/blog/archives/2007/01/amfphp-19-beta-2-ridiculously-faster/

FlexBuilder 新插件–Cairngorm 支持

有人正在开发一个Eclipse的插件,用来改善并且加强FlexBuilder 的功能。

这个插件一个较大的特点就是它可以支持Cairngorm框架。 自动生成基础代码,而且还有Cairngorm 视图。

* 为 REST, Web Service (WSDL) and Remoting services自动生成代码.
* 增强型的AS3 类代码生成向导
* Cairngorm 中类的自定义向导
* FlexUnit test and test suite 生成器
* 生成Cairngorm测试程序以及Flex Unit测试程序.
* ASDoc 生成器.
* Cairngorm 视图.
* e4x editor and expression builder.

http://blog.thinkingdigital.org/?p=3

使用FlasFlash,FlexBuilder和AS3创建自适应的用户界面

由于不好排版,请下载PDF文档

这里是关于这片翻译的讨论

译者为 AServer

Apollo 新书

Adobe已经有了Apollo的新书。

这本书可以在亚马逊上预先定购,也可以等到Apollo在Lab上放出时下载。

估计和Adobe的其他书比如Programming ActionScript 3.0 之类的一样,有点类似文档的性质。

内容包括以下:

  1. 前言
  2. Apollo 介绍
  3. 开始开发Apollo应用程序
  4. 使用文件读写(输入输出)的API
  5. 在基于Flex的Apollo应用程序里面使用HTML
  6. Apollo Mini Cookbook
  7. 附录 A : Apollo 包和类(Packages and Classes)
  8. 附录 B : Apollo 命令行工具

参考链接:

http://www.amazon.com/Apollo-Adobe-Developers-Pocket-Guide/dp/0596513917/

http://weblogs.macromedia.com/mesh/archives/2007/02/apollo_pocketgu.html

使用ActionScript 2.0或ActionScript 3.0处理音频文件的提示点(cue point)

译者:雪の猫

 

Macromedia Flash Professional 8 和 Adobe Flex Builder 2 都支持直接在Flash video (FLV)文件中使用提示点。使用Flash 8(ActionScript 2.0),完成这工作只需要一个FLVPlayback组件的实例和简单的设置。可以在组件检查面板中定义或者调用FLVPlayback.addAsCuePoint()方法;使用Flex Builder 2,需要的是对应VideoDisplay实例指定的CuePointManager类的实例。两种情况下,接下来都是设置一个cuePoint事件的监听器对象和定义该对象一个特定的响应函数。

 

而对音频文件,实现提示点要困难些。虽然使用Flash8能用如MediaController, MediaDisplay, 或MediaPlayback这些媒体组件来装载MP3文件,但是要注意这些组件是为了兼容Flash Player 6 and 7。这些组件的结构比FLVPlayback旧,这样,使用它们会使生成的swf文件多出至少55KB。使用FLVPlayback仅使之增加33KB,可是它不能装载MP3文件。类似的,Flex Builder 2的VideoDisplay类只能装载video。可以暂且做几个只有声音的FLV文件(不包含视频内容)。不过,这看来并不广泛适用。特别在一个团队中,你并不能决定选择哪些外部资源。而最通常的音频格式是MP3。幸运的是,用一点ActionScript就可以弥补这个不足了。

 

这篇文章将讲述一个特别解决方案的两个版本:用一个自定义类SoundSync来支持内部声音资源或者是外部的MP3文件。代码有ActionScript 2.0(Flash Professional 8 )和ActionScript 2.0(Flex Builder 2)两种。

 

不管使用那种语言,方法是一样的。ActionScript 2.0和ActionScript 3.0 都提供了Sound类来代表嵌入或装载的声音文件。两种语言都允许播放,从开头播放或从音频的某个时刻播放,暂停,循环。我们当然想不重造轮子!那些已经有的功能都是有用的。缺少的只是对提示点的支持,所以看来应该保留原有功能而extend这个Sound类。

 

自定义类SoundSync要继承Sound并添加下面的新公有方法:

addCuePoint(): 添加一个提示点

getCuePoint(): 通过提示点的名字或者时间返回该提示点

removeCuePoint(): 通过提示点的名字或者时间删除该提示点

removeAllCuePoints(): 删除所有的提示点

 

 

此外,还添加了几个私有方法。并根据使用语言不同重写一些原有的方法。简而言之,SoundSync类使用一个timer不断对照当前的播放时间检查当前提示点对象的time属性。我们先从ActionScript 2.0开始再移植到ActionScript 3.0。

 

需要环境

 

为了充分学习,需要如下软件和文件:

Flash Professional 8

 

Flex Builder 2

 

In Labs: Flash Professional 9 ActionScript 3.0 Preview (可选)

 

示例文件

sound_sync.zip (ZIP, 3MB)

 

准备知识

对ActionScript 2.0的中等掌握和对Flex Builder 2及ActionScript 3.0的介绍性了解。

 

 

ActionScript 2.0版的SoundSync类

 

自定义类必须保存到一个外部文本文件中,命名为SoundSync.as。按照最佳实践,应该把这个文件放在符合包结构的路径下的文件夹中。这里,应该放到相对于全局classpath设置的(选择Edit > Preferences > ActionScript category > ActionScript 2.0 Settings 按钮,中文的按钮……我不是中文版)路径为net/quip/sound这个文件夹下。为了方便按照我的域名给包起名为net.quip.sound。请随便把它改成你喜欢的吧。有关包的细节,请参考Flash8帮助文档中”……我又不是中文版–b”节。

 

创建ActionScript 2.0 类文件

启动Flash Professional 8,选择File > New > ActionScript File 图一

 ---

|图1    |

|    |

 ---

 

输入如下的ActionScript代码:

/**************代码*1***********/

import mx.events.EventDispatcher;

import mx.utils.Delegate;

class net.quip.sound.SoundSync extends Sound {

// PROPERTIES 属性

// CONSTRUCTOR 构造

// METHODS 方法

// EVENT HANDLERS 事件处理

}

 

 

头两行import了两个类,后面的代码会用到他们。在ActionScript 2.0中,import语句可以方便以后输入类名的时候不必再输入其完整的包名。

 

 

接下来,是声明这个类继承自基类Sound。然后写上属性,构造函数,方法和事件的注释占个位置。对一个类的代码,这些不是必须的,但是他们使类的结构一目了然。下面把细节添上。

 

声明属性:

在// PROPERTIES 属性 的注释下面输入:

 

private var _cuePoints:Array;

private var _currentCuePoint:Number;

private var _interval:Number;

private var _intervalDuration:Number;

private var _secondOffset:Number;

// Event dispatcher

public var dispatchEvent:Function;

public var addEventListener:Function;

private var removeEventListener:Function;

 

为了方便,私有变量的名字用下划线(_)开头。这样就容易辨认出这些变量只能用在该类的内部(即,类外不可以访问)。一会儿再解释每个属性。先注意最后三个,为了使用EventDispatcher,它们是必须的,EventDispatcher可以使这个类的实例发送事件给监听器,包括cuePoint事件。

 

构造函数

在// CONSTRUCTOR 构造 的注释下面输入:

 

public function SoundSync(target:MovieClip) {

super(target);

init();

}

 

这个函数使SoundSync可以像Sound一模一样的使用。super语句调用父类(基类)的构造函数,它接受一个可选的MovieClip引用作参数。因为有这个语句,基类在这里完成其初始化。然后是调用init()方法,进一步完成SoundSync的初始化,下面介绍它:

 

方法

 

这个类包含下面一些方法,我们从init开始讲解:

 

init()

 

在// METHODS 方法 的注释下面输入:

 

private function init():Void {

// Initialize properties 初始化属性

_cuePoints = new Array();

_currentCuePoint = 0;

_intervalDuration = 50;

_secondOffset = 0;

// Initialize class instance as valid event broadcaster

// 把类的实例作为EventDispatcher的广播者

EventDispatcher.initialize(this);

}

 

好了,我们给几个属性赋值为默认的值。cuePoints是一个数组对象,元素是控制点对象的引用,用currentCuePoint作数组当前的索引。_intervalDuration 属性定义检查的周期,就是两次检查音频当前位置的时间间隔,单位是毫秒。_secondOffset属性用来指定播放开始后多少秒才开始检查(默认是0)。

 

最后一行调用EventDispatcher.initialize()方法,参数是this,这样每一个SoundSync的实例都可以发送事件了。

 

addCuePoint()

 

可以添加addCuePoint()方法了. 在init()之后输入:

 

// Add Cue Point 添加提示点

public function addCuePoint(cuePointName:String, cuePointTime:Number):Void {

_cuePoints.push(

{

type: “cuePoint”,

name: cuePointName,

time: cuePointTime,

target: this

}

);

_cuePoints.sortOn(”time”, Array.NUMERIC);

}

 

这个方法需要两个参数:cuePointName 和 cuePointTime。分别表示一个提示点的名字name和时刻temporal position。然后我们把两个参数的值赋给一个object对象的两个属性,用 Array.push()方法添加到cuePoints数组;花括号{}是new Object()的一个简记。此外,每一个提示点对象还需要一个字符串类型的type属性。最后,提示点对象还要一个target属性来引用发送事件的那个SoundSync的实例(this)。

 

每当添加一个提示点对象,_cuePoints数组要根据cuePoint.time属性重新排列。这样保证了提示点位置的正确。

 

getCuePoint()

 

为了对称, 应该提供一个方法检索已经被添加的提示点。在addCuePoint()方法后输入:

 

// Get Cue Point 得到提示点

public function getCuePoint(nameOrTime:Object):Object {

var counter:Number = 0;

while (counter < _cuePoints.length) {

if (typeof(nameOrTime) == “string”) {

if (_cuePoints[counter].name == nameOrTime) {

return _cuePoints[counter];

}

} else if (typeof(nameOrTime) == “number”) {

if (_cuePoints[counter].time == nameOrTime) {

return _cuePoints[counter];

}

}

counter++;

}

return null;

}

 

这个方法需要一个参数,可以是提示点的名字或时刻,这意味着参数类型可能是字符串或者可能是数值型。为了应对两种可能,声明参数类型是Object。在方法内,定义一个计数器,用来遍历_cuePoints数组。–b 在while循环里边用typeof检查参数nameOrTime的类型,如果是字符串,nameOrTime 比照当前提示点的name属性;如果是数值型,比照提示点的time属性。因为计数器是递增的,函数返回的是第一个name属性或time属性匹配nameOrTime的提示点,即使有重复的话也是如此。如果没有匹配,返回null。

 

getCurrentCuePointIndex() 和 getNextCuePointIndex()

 

这两个方法是”幕后英雄”,它们只被该类内部的其他方法访问。它们返回当前的或者下一个提示点在_cuePoints数组中的位置(索引),这是用来移去当前的提示点并选定下一个提示点。

 

在getCuePoint() 方法之后输入:

 

// 得到当前提示点的索引

private function getCurrentCuePointIndex(cuePoint:Object):Number {

var counter:Number = 0;

while (counter < _cuePoints.length) {

if (_cuePoints[counter].name == cuePoint.name) {

return counter;

}

counter++;

}

return null;

}

// 得到下一个提示点的索引

private function getNextCuePointIndex(seconds:Number):Number {

seconds = (seconds) ? seconds : 0;

var counter:Number = 0;

while (counter < _cuePoints.length) {

if (_cuePoints[counter].time >= seconds * 1000) {

return counter;

}

counter++;

}

return null;

}

 

 

第一个方法,getCurrentCuePointIndex(),要求一个提示点对象作为参数。使用一个刚刚那样的循环,这个方法检查每一个_cuePoints数组中提示点的name属性是不是和参数的name匹配。如果是,返回匹配像的索引,否则返回null。

 

 

第二个方法, getNextCuePointIndex(), 有趣一些 O_O||| 。 这个方法是要通过指定的时间来确定那一个提示点是”下一个”。假设有三个提示点在10秒,20秒和30秒处。如果音频播放了22秒,下一个可用的提示点就是30秒处的那个——在这个假设中是第三个,索引是2(因为数组下标是0开头)。

 

这个方法会被该类中的start()和pollCuePoints()两个方法调用,在后边一点讨论。现在有两个必须要解决的小问题:

 

参数seconds很有可能不能被提供,那样函数的返回值会是null。然后提示点保存的time是以毫秒为单位的,而基类的那些方法都要求其参数的单位是秒。这两个问题都很简单。第一个,我们用条件运算符(?:)来看看seconds参数的值,如果是合法的把它赋值给自己,否则把它赋值为0。

 

第二个,还是while循环遍历_cuePoints数组。比较每一个提示点的time属性和1000与参数的乘积(因为1秒是1000毫秒)。因为循环从0开始,第一个大于等于给定提示点time属性值的提示点是”下一个”提示点。啊~~这一句要怎么翻

 

removeCuePoint() 和 removeAllCuePoints()

 

这两个方法用来删除某一个提示点或删除全部提示点。在getNextCuePointIndex()方法之后输入

// 删除提示点

public function removeCuePoint(cuePoint:Object):Void {

_cuePoints.splice(getCurrentCuePointIndex(cuePoint), 1);

}

// 删除所有提示点

public function removeAllCuePoints():Void {

_cuePoints = new Array();

}

 

方法removeCuePoint(), 需要一个提示点对象作为参数。调用Array.splice() 方法来删除_cuePoints数组中指定的元素。用getCurrentCuePointIndex()方法的返回值确定要删除元素的索引。因为只删除一个元素,Array.splice()的第二个参数应该传入1。

 

方法removeAllCuePoints(), 是简单的把_cuePoints替换成一个新的空数组.

 

重写start(), stop(), 和loadSound() 方法

 

基类Sound有两个方法可以开始播放:Sound.start() 和 Sound.loadSound()。不管用那一个,SoundSync 都要开始不断的轮询音频的位置,和每一个提示点的time属性比较。同样的,调用了Sound.stop() 之后轮询要停止。

 

为了实现这一点, SoundSync重写了这三个方法,调用基类的方法完成基本功能之外执行附加的命令。

 

在removeAllCuePoints() 方法之后输入:

 

// Start

public function start(secondOffset:Number, loops:Number):Void {

super.start(secondOffset, loops);

dispatchEvent({type:”onStart”, target:this});

// Reset current cue point

_secondOffset = secondOffset;

_currentCuePoint = getNextCuePointIndex(secondOffset);

// Poll for cue points

clearInterval(_interval);

_interval = setInterval(Delegate.create(this, pollCuePoints), _intervalDuration);

}

// Load Sound

public function loadSound(url:String, isStreaming:Boolean):Void {

super.loadSound(url, isStreaming);

clearInterval(_interval);

_interval = setInterval(Delegate.create(this, pollCuePoints), _intervalDuration);

}

// Stop

public function stop(linkageID:String):Void {

if (linkageID) {

super.stop(linkageID);

} else {

super.stop();

}

dispatchEvent({type:”onStop”, target:this});

// Kill polling

clearInterval(_interval);

}

 

一开始, start()方法调用super.start()并传入两个可选参数。然后,发送onStart事件,提示音频的播放已经开始了。

 

两个重要的私有属性在这里根据可选参数secondOffset被赋值。第一个_secondOffset只是简单的copy以备用。第二个_currentCuePoint,以secondOffset作为getNextCuePointIndex()的参数计算得到。请注意,这里secondOffset 是一个可选参数(可能是null),所以getNextCuePointIndex()的确应该做那一检查。

 

最后,如果setInterval()的循环已经在运行,要用clearInterval()取消并开始新的轮询。静态方法Delegate.create()让轮询的作用域是这个类本身而不是setInterval()这个函数。

 

当然,开发人员可能使用loadSound()而绕过了start()。这种情况SoundSync的loadSound()是调用super.loadSound()并传入其期望的参数,然后启动轮询。

 

要节约处理器周期,一个好办法是当调用stop()之后停止轮询。因为linkageID在基类Sound中是一个可选参数,SoundSync的该函数要检查这个参数是否存在再调用合适的super.stop()。之后发送一个 onStop 事件并取消轮询。

 

这个类的灵魂: pollCuePoints()

 

 

把前面的一切整合起来! 在stop() 方法之后输入:

 

private function pollCuePoints():Void {

// If current position is near the current cue point’s time …

 // 如果当前位置接近提示点的time

var time:Number = _cuePoints[_currentCuePoint].time;

var span:Number = (_cuePoints[_currentCuePoint + 1].time) ? _cuePoints[_currentCuePoint + 1].time : time + _intervalDuration * 2;

if (position >= time && position <= span) {

// Dispatch event 发送事件

dispatchEvent(_cuePoints[_currentCuePoint]);

// Advance to next cue point … 下一个

if (_currentCuePoint < _cuePoints.length) {

_currentCuePoint++;

} else {

_currentCuePoint = getNextCuePointIndex(_secondOffset);

}

}

}

 

pollCuePoints()方法有点繁重但是很容易理解。这个方法每50毫秒调用一次,检查正在播放的音频的Sound.position属性,以比较当前和下一个提示点对象的time属性。如果position大于等于当前的提示点的time,但是小于等于下一个提示点time,那就把当前的提示点作为事件发送出去。

 

 

注意两个局部变量:time(时间) 和 span (间隔)。第一个是当前提示点time属性的值。而第二个可能是下一个提示点time属性的值——如果当前提示点的后面还有另外一个——或者当前提示点的time值加上轮询时间间隔的两倍。这个乘法是武断的,不过事实证明还很好用,何况只有到数组的最后一个提示点的时候才会用到。

 

cuePoint事件一发出,如果还有更多的提示点的话,_currentCuePoint就加1。没有了的话,音频就播放到结束,可能又要接着从头播放了,这样_currentCuePoint又要根据secondOffset被重置为最开始的那个提示点。

 

利用基类的事件处理

 

即使没有直接调用stop(),音频自己也会停止。这时轮询应该停止,请在// EVENT HANDLERS 事件处理 的注释后面写:

 

// onSoundComplete

public function onSoundComplete():Void {

// Kill polling

clearInterval(_interval);

// Reset current cue point

_currentCuePoint = 0;

// Dispatch event

dispatchEvent({type:”onSoundComplete”, target:this});

}

 

不幸的是,这样占去了一个Sound类很有用的事件(在AS2.0中有两种”事件处理”一种是比如onEnterFrame的回调函数,另一种是EventDispatcher这样使用AddEventListener注册监听器来处理的事件,这里的onSoundComplete函数是前者,而后面的dispatchEvent({type:”onSoundComplete”, target:this});属于后者,原文并没有区分,翻译的人解释道)。作为一个解决办法,SoundSync在clearInterval()中断轮询,_currentCuePoint重置为0之后,发送一个onSoundComplete来替代。这样一来,还是在音频播放完后触发动作的。

 

使用ActionScript 2.0版本的SoundSync

 

SoundSync 类使用简单。在需要音频提示点的FLA文件或其他ActionScript类中,实例化SoundSync来代替Sound类。之后要调用addCuePoint(),并创建监听对象来处理cuePoint 事件:

 

import net.quip.sound.SoundSync;

 

var ss:SoundSync = new SoundSync();

ss.addCuePoint(”first”, 1000);

ss.addCuePoint(”second”, 2000);

ss.addCuePoint(”third”, 3000);

ss.loadSound(”sample.mp3″, true);

 

var listener:Object = new Object();

listener.cuePoint = function(evt:Object):Void {

trace(evt.name + “, ” + evt.time);

}

ss.addEventListener(”cuePoint”, listener);

 

 

观看基于timeline的高级演示,请解压文章附带的ZIP文件,打开green_presidents.fla 。确认附带的音频文件green_presidents.mp3在和FLA文件相同的文件加下。并确认ActionScript 2.0版的SoundSync.as文件在相对全局classpath设置的目录为net/quip/sound文件夹下。

 

ActionScript 3.0的SoundSync

 

啊!准备好再来一次了吗?SoundSync 的ActionScript 3.0 版和其ActionScript2.0版非常接近。当然有一点差异,但是并不吓人。

 

创建ActionScript 3.0 的类文件

 

启动Flex Builder 2 菜单选择 File > New > ActionScript Project 见图2

 ---

|图2    |

|    |

 ---

 

给工程起名叫SoundSyncExample 然后点Finish(完成)按钮。这样就用 Flex Builder 2创建了一个新工程,工程包括bin和html-template文件夹,Flex和一个新的SoundSyncExample.as类文件将在发布时用到这两个文件夹,而SoundSyncExample将作为新应用程序的入口。SoundSyncExample将实例化ActionScript 3.0 版的S SoundSync;这对应的是上一节”使用 ActionScript 2.0 “的Flash 8的桢代码

 

看到 Flex Builder 2 自动的生成了包和类的声明,见图三,我们一会来添加内容。暂时保存和关闭它。

 

 ---

|图3    |

|    |

 ---

 

 

在工程中创建net.quip.sound 包的文件夹,选择File > New > Folder 。在New Folder(新文件夹)对话框,选择SoundSyncExample 文件夹在Folder Name(文件夹名)文本框中输入路径net/quip/sound。

 

最后,选择File > New > ActionScript Class。在New ActionScript Class(新ActionScript类) 对话框中,确认Package 文本框中是net.quip.sound 。在Name 项中输入SoundSync并在Superclass 项中输入flash.media.Sound 。选中Generate Constructor from Superclass (由父类生成构造函数)选项。见图4

 

 ---

|图4    |

|    |

 ---

 

和前一版一样,SoundSync 继承Sound 类。点 Finish(完成) 按钮。看到Flex Builder 2 又自动的生成了包和类的声明,并在SoundSync的构造函数中调用了super。

 

在ActionScript 3.0中,import语句不仅是为了方便,它们是必须的。作为代码自动生成功能的一部分,Flex Builder 2 会自动写好需要的import语句。不过,为了完成教程的学习,请把代码以及注释手工的添加到相应的位置。

 

package net.quip.sound

{

import flash.events.Event;

import flash.events.TimerEvent;

import flash.media.Sound;

import flash.media.SoundChannel;

import flash.media.SoundLoaderContext;

import flash.media.SoundTransform;

import flash.net.URLRequest;

import flash.utils.Timer;

 

public class SoundSync extends Sound

{

// PROPERTIES

// CONSTRUCTOR

public function SoundSync(stream:URLRequest=null, context:SoundLoaderContext=null)

{

super(stream, context);

init();

}

// METHODS

// EVENT HANDLERS

}

}

 

不要忘记构造函数中是要调用init()的!

 

声明属性

 

在// PROPERTIES 注释之后输入:

 

private var _cuePoints:Array;

private var _currentCuePoint:uint;

private var _timer:Timer;

private var _timerInterval:uint;

private var _startTime:Number;

private var _loops:uint;

private var _soundChannel:SoundChannel;

 

这里 _cuePoints 和 _currentCuePoint 与ActionScript 2.0版的那两个完全一样。 _timer 和 _timerInterval 属性 对应于那一版的_interval 和 _intervalDuration,而_startTime对应于之前的_secondOffset。最后,_loops 和 _soundChannel 是新的属性,将在后面逐步讲解。

 

注意到一些数值属性是新的数据类型uint。在ActionScript 3.0里,我们已经熟悉的Number表示的是双精度浮点数,表示Number要使用多达53???位 -_o。新的int类型是32为有符号整数(正数或者负数)而uint是32位无符号整数(只有正数)。Flash Player 处理int和uint比Number更加有效,所以如果不是必须使用浮点数应该选择新的数据类型。

 

构造函数

 

 

构造函数已经更新过了, 但是还是来回顾一下:

 

// CONSTRUCTOR

public function SoundSync(stream:URLRequest = null, context:SoundLoaderContext = null) {

super(stream, context);

init();

}

 

 

看起来很熟悉吧,因为这个和ActionScript 2.0版本非常相似。和以前一样,在父类初始化之后进行了这个类自己的初始化。不过注意到,在 ActionScript 3.0中可选的参数要给定一个默认值(这里两个都是null)

 

方法

 

大多数都熟悉了.

 

init()

在 // METHODS 注释之后输入:

 

// init

private function init():void {

_cuePoints = new Array();

_currentCuePoint = 0;

_timerInterval = 50;

_startTime = 0.0;

}

 

在这里用默认值进行了一些私有属性的初始化。注意函数返回类型的那个小写的”v”,区别于ActionScript 2.0中Void类型的大写V

 

addCuePoint()

 

这个方法是离开ActionScript 2.0的第一个里程碑 –b要怎么翻这句。在ActionScript 3.0 事件处理进行了很大变动,变得一致,易于控制和使用。为了通过类型检查,必须把_cuePoints数组中的一般Object对象替换成一个自定义类型CuePointEvent的对象,而CuePointEvent继承自新的Event类。

 

选择File > New > ActionScript Class。在New ActionScript Class (新ActionScript类)对话框,确认Package (包)文本框是 net.quip.sound;在Name(类名) 文本框中 输入CuePointEvent 并在Superclass(父类) 文本框中输入Event。选中Generate Constructor from Superclass (由父类生成构造函数)选项然后点Finish(完成) 按钮。把代码修改成和下面的一致:

 

package net.quip.sound

{

import flash.events.Event;

 

public class CuePointEvent extends Event

{

// PROPERTIES

public static const CUE_POINT:String = “cuePoint”;

public var name:String;

public var time:uint;

 

// CONSTRUCTOR

public function CuePointEvent(type:String, cuePointName:String, cuePointTime:uint, bubbles:Boolean = false, cancelable:Boolean = false)

{

super(type, bubbles, cancelable);

this.name = cuePointName;

this.time = cuePointTime;

}

 

// METHODS

// Clone

public override function clone():Event

{

return new CuePointEvent(type, name, time, bubbles, cancelable);

}

}

}

 

这个类有三个公有属性,其中第一个是常量:字符串”cuePoint”。使用这个属性的原因是,按照最佳实践推荐,这样做使事件的类型可以在外部的代码中使用CuePointEvent.CUE_POINT而不是字符串来指定。第二个和第三个属性用于保存提示点的name和time。

 

修改完代码之后,留意一下构造函数的参数。CuePointEvent 需要type, cuePointName 和 cuePointTime 然后是一组用于Event类的可选参数。调用super的时候按照Event的构造函数的需要提供参数。其他的赋值给对应的属性。

 

最后重写Event。clone()方法来返回一个派生类CuePointEvent的实例而不是原本的Event类的。

 

现在要写SoundSync.addCuePoint()方法了。回到SouncSync.as文档并在其init()方法之后输入:

 

// Add Cue Point

public function addCuePoint(cuePointName:String, cuePointTime:uint):void {

_cuePoints.push(new CuePointEvent(CuePointEvent.CUE_POINT, cuePointName, cuePointTime));

_cuePoints.sortOn(”time”, Array.NUMERIC);

}

 

除了要求使用Event的派生类,这个方法和ActionScript 2.0 版的几乎一样。

 

 

getCuePoint()

 

比起之前的版本只有一个变化是局部变量的计数器使用uint类型代替Number类型:

 

// Get Cue Point

public function getCuePoint(nameOrTime:Object):Object {

var counter:uint = 0;

while (counter < _cuePoints.length) {

if (typeof(nameOrTime) == “string”) {

if (_cuePoints[counter].name == nameOrTime) {

return _cuePoints[counter];

}

} else if (typeof(nameOrTime) == “number”) {

if (_cuePoints[counter].time == nameOrTime) {

return _cuePoints[counter];

}

}

counter++;

}

return null;

}

 

 

更多的相同

 

下面的四个方法getCurrentCuePointIndex(), getNextCuePointIndex(), removeCuePoint()
和removeAllCuePoints()。这些只是代码移植中非常一般的变化。一些原来是Number类型的用uint替换,Void换成void然后解决getNextCuePoint() 方法中两个小问题的办法有一些变化。这一次传入的参数已经是以毫秒为单位的了然后要用isNaN()函数来检查可能传进的null值,因为ActionScript3.0对数值型的检查更加严格。

 

在 getCuePoint() 方法之后输入:

// Get Current Cue Point Index

private function getCurrentCuePointIndex(cuePoint:CuePointEvent):uint {

var counter:uint = 0;

while (counter < _cuePoints.length) {

if (_cuePoints[counter].name == cuePoint.name) {

return counter;

}

counter++;

}

return null;

}

// Get Next Cue Point Index

private function getNextCuePointIndex(milliseconds:Number):uint {

if (isNaN(milliseconds)) {

milliseconds = 0;

}

var counter:uint = 0;

while (counter < _cuePoints.length) {

if (_cuePoints[counter].time >= milliseconds) {

return counter;

}

counter++;

}

return null;

}

// Remove Cue Point

public function removeCuePoint(cuePoint:CuePointEvent):void {

_cuePoints.splice(getCurrentCuePointIndex(cuePoint), 1);

}

// Remove All Cue Points

public function removeAllCuePoints():void {

_cuePoints = new Array();

}

 

 

play()

 

和原来的类有两个主要的不同。在ActionScript 3.0中,既没有start() 也没有loadSound() 方法。最接近的是play() 和 load()。两者中,只有前者能开始播放音频。这就是说只要重写play()方法就够了,但是要多解释一下。

 

在removeAllCuePoints() 方法之后输入:

 

// Play

public override function play(startTime:Number = 0.0, loops:int=0, sndTransform:SoundTransform=null):SoundChannel {

_soundChannel = super.play(startTime, loops, sndTransform);

_soundChannel.addEventListener(Event.SOUND_COMPLETE, onSoundComplete);

dispatchEvent(new Event(”play”));

// Reset current cue point

_startTime = startTime;

_loops = 0;

_currentCuePoint = getNextCuePointIndex(startTime);

// Poll for cue points

_timer = new Timer(_timerInterval);

_timer.addEventListener(TimerEvent.TIMER, pollCuePoints);

_timer.start();

return _soundChannel;

}

 

注意函数声明中的override关键字,这里是必须的。在 ActionScript 3.0中Sound.play()方法返回一个SoundChannel 类的实例,使用它来控制正在播放音频的声音效果。自定义类SoundSync的私有成员 _soundChannel 将引用这个实例,然后立刻使用它来监听表示播放完毕的soundComplete事件。这样也使在合适时取消轮询变得可能。

 

发送一个自定义的play事件。接着,保存一下 play()方法的两个可选参数startTime和loops以备用。事实上,私有属性_loops并不总和loops参数一致,后者表示了音频应该重复的次数。在这个类中,_loops会被 pollCuePoints() 累加,_loops是为了完成一些必须的算法。在ActionScript 2.0里,当循环的音频播放完毕而重复时Sound.position属性会置0,这样就方便了重置提示点。在ActionScript 3.0里,对应的属性是SoundChannel.position,可是SoundChannel.position不会自动置0。于是,当音频需要重复是_loops就被设计用来乘以SoundChannel.position的值。

 

然后,_currentCuePoint属性和之前的一样由 getNextCuePointIndex()来设定。使用新的Timer类代替setInterval()函数来实现轮询。这里的_timer保存一个对Timer 类实例的引用并负责监听TimerEvent.TIMER事件来触发pollCuePoints()方法。最后返回_soundChannel满足重写的Sound.play()方法。

 

stop()

 

和原来的版本类似,这个方法在明确被调用而停止音频的播放时取消轮询。注意这个方法并不是override的, 因为ActionScript 3.0中停止一个声音是由SoundChannel类控制的。在play()方法的下面输入:

 

// Stop

public function stop():void {

_soundChannel.stop();

dispatchEvent(new Event(”stop”));

// Kill polling

_timer.stop();

}

 

 

pollCuePoints()

 

ActionScript 3.0 中的”类的灵魂”和ActionScript 2.0的非常类似。记住SoundChannel.position对循环播放的音频并不会置0,所以如果循环播放要用内部的 _loops 属性乘以SoundChannel.position。此外的都是以前一样:检查当前提示点和下一个提示点的时间属性。如果音频的position 在当前提示点和下一个提示点之间,发送cuePoint事件。当没有下一个提示点时,检查一个武断的值,它是当前提示点的time值加上轮询时间间隔的两倍。

 

在stop()方法之后输入:

 

// Poll Cue Points

private function pollCuePoints(event:TimerEvent):void {

var time:Number = _cuePoints[_currentCuePoint].time + (length * _loops);

var span:Number = 0;

if (_cuePoints[_currentCuePoint + 1] == undefined) {

span = time + _timerInterval * 2;

} else {

span = _cuePoints[_currentCuePoint + 1].time + (length * _loops);

};

if (_soundChannel.position >= time && _soundChannel.position <= span) {

// Dispatch event

dispatchEvent(_cuePoints[_currentCuePoint]);

// Advance to next cue point …

if (_currentCuePoint < _cuePoints.length - 1) {

_currentCuePoint++;

} else {

_currentCuePoint = getNextCuePointIndex(_startTime);

_loops++;

}

}

}

 

利用同样的基类事件

 

和以前一样,要在音频文件自然结束时取消轮询。并发送soundComplete 来弥补已经用掉了一个。

 

在// EVENT HANDLERS 注释之后输入:

 

// onSoundComplete

public function onSoundComplete(event:Event):void {

// Reset current cue point

_currentCuePoint = 0;

// Kill polling

_timer.stop();

// Dispatch event

dispatchEvent(new Event(Event.SOUND_COMPLETE));

}

 

使用ActionScript 3.0版本的SoundSync

 

还记得SoundSyncExample.as文件吧? 现在该打开它了。

 

把代码改成:

 

package {

import flash.display.Sprite;

import flash.events.Event;

import flash.net.URLRequest;

 

import net.quip.sound.CuePointEvent;

import net.quip.sound.SoundSync;

 

public class SoundSyncExample extends Sprite

{

// CONSTRUCTOR

public function SoundSyncExample()

{

var ss:SoundSync = new SoundSync();

ss.load(new URLRequest(”green_presidents.mp3″));

ss.addCuePoint(”Benjamin Franklin”, 20100);

ss.addCuePoint(”Ulysses S. Grant”, 16479);

ss.addCuePoint(”Alexander Hamilton”, 9431);

ss.addCuePoint(”Andrew Jackson”, 13278);

ss.addCuePoint(”Thomas Jefferson”, 2439);

ss.addCuePoint(”Abraham Lincoln”, 5480);

ss.addCuePoint(”George Washington”, 0);

ss.load(new URLRequest(”green_presidents.mp3″));

ss.play();

ss.addEventListener(CuePointEvent.CUE_POINT, onCuePoint);

ss.addEventListener(Event.SOUND_COMPLETE, onSoundComplete);

}

// On Cue Point

private function onCuePoint(event:CuePointEvent):void {

trace(”Cue point: ” + event.name + “, ” + event.time);

}

// On Sound Complete

private function onSoundComplete(event:Event):void {

trace(”Audio finished: ” + event.type);

}

}

}

 

解压文章附带的ZIP文件后,把green_presidents.mp3放在Flex Builder 2 工程的文件夹下。以windows XP为例,默认的路径是C:\Documents and Settings\<用户名>\My Documents\Flex Builder 2\<工程名>

 

选择Run > Debug SoundSyncExample。 将启动默认浏览器来播放包含应用程序的SWF文件。当SWF文件在浏览器中运行时,切换到Flex Builder 2 观察Console (控制台)面板,当达到提示点时发现trace()的输出。看,虽然这几为总统先生按照姓氏字母的先后被排近来,它们还是按照时间顺序被触发。

 

如果有Flash Professional 9 ActionScript 3.0 Preview public alpha 发行版 –b,也可以用来测试。确认全局classpath设置指向含有package(net/quip/sound)的那个文件夹,然后打开一个新的FLA文件。确认发布设置是 ActionScript 3.0 然后设置Document Class(文档类)文本框中是SoundSyncExample。保存FLA文件到Flex Builder 2 文件夹的SoundSyncExample的子文件夹。测试SWF文件,注意观察Ouput(输出)面版。

 

进一步的学习

 

在本教程中讲述了使用ActionScript 2.0 及 3.0创建自定义SoundSync类。代码分别使用良种语言扩展了内建的类Sound,向其添加了提示点功能来回放音频文件。教程介绍了ActionScript两个版本的一些不同,有新的数据类型和相似的对象的结构上的变化。

 

代码升级/移植是叫人难受的,但是我希望这个练习可以减少些盲目的恐惧。ActionScript 3.0的前景被大大的拓宽了,但是它还是ActionScript。伴随你的足迹,探险会更激动人心。

 

学习更多关于 ActionScript 2.0,请参考下面的资源:

 

Learning ActionScript 2.0 in Flash (LiveDocs)

ActionScript 2.0 best practices

Flash ActionScript 2.0 Language Reference (LiveDocs)

Debugging ActionScript 2.0 code: Lifting the blindfold

 

学习更多关于 ActionScript 3.0, 包括移植到新语言的技巧, 请参考下面的资源:

 

ActionScript 3.0 overview (LiveDocs)

Tips for learning ActionScript 3.0

ActionScript 2.0 migration (LiveDocs)

Programming ActionScript 3.0 (LiveDocs)

Flex 2 Language Reference (LiveDocs)

 

关于作者

 

David Stiller是一位职业多媒体程序员/设计师。曾在NASA,Adobe和美国其他的主要汽车制造及造船公司任职。他喜欢立体摄影艺术,精致的木玩具船,还有土耳其咖啡。David自学成材,乐于和人分享在Flash 及ActionScript 论坛上学习,讨论和帮助的快乐。他是Community MX站点的驻站作者,该站是一个针对adobe产品的开发培训网站。David现在和他迷人的妻子Dawn还有可爱的女儿Meridian居住在维吉尼亚。

ActionScript2转ActionScript3

直接发,老是格式有问题。

我还是就发个pdf在这里好点。点下面连接下载:

ActionScript2转ActionScript3

 

Apollo FAQ

Apollo: 开发者问答录

来自Adobe Libs

(Redirected from Apollo:developerfaq)

Apollo 目前处于开发的早期阶段,因此,这个问答列表中所有的信息都有可能改变。

请注意,这篇文档仍然处于编辑状态,因此可能会不时加入新的更新内容。

目录

1 综述

1.1 什么是阿波罗(Appllo)

阿波罗是Adobe正在开发的一个跨平台运行环境的研发代号。阿波罗可以让开发人员使用他们的web开发技能(Flash,Flex,HTML,JavaScript,Ajax)来创建运行于桌面的富互联网应用程序(RIA)。

1.2 阿波罗主要面向哪种类型的应用程序?

虽然你可以基于阿波罗构建许多传统的桌面应用程序,阿波罗主要是为了在桌面平台上使开发和部署富互联网应用程序更加轻松和容易。(也就是说,阿波罗的主要侧重于将网络应用程序移植到桌面上来)。

因此,阿波罗1.0的主要功能也是以以上目的为考虑标准的。(在阿波罗1.0阶段,他们主要目标是把网络应用程序搬到桌面上,所以别指望你可以调用其他dll,或者exe之类的。这个在Flexcoder里面已经有人提过了,答案是目前的阶段,阿波罗1.0的主要目标不是这些。)

1.3 阿波罗主要面向哪些开发人员?

阿波罗主要面向那些正在使用网络技术(Flash , Flex, HTML, JavaScript, Ajax)开发互联网应用程序的开发人员。

1.4 阿波罗是免费的吗?

是的,阿波罗运行环境将会是免费的。就像Flash Player和Adobe Reader一样。

1.5 阿波罗什么时候发布?

我们计划在2007年的早些时候在Adobe Labs有一个pre-release。

目前我们计划在2007上半年发布Apollo 1.0 。

1.6 阿波罗1.0主要面向哪些操作系统?

阿波罗1.0主要会支持 windows 和 OS X。

我们同时也在考虑我们将要支持其他哪些操作系统。

1.7 阿波罗是否是一个网页浏览器?

不是,阿波罗是一个跨操作系统的运行环境。它是运行于浏览器之外的。

理论上,你是可以在阿波罗基础上创建一个浏览器的。

1.8 阿波罗的文件大小是多少?

目前这个运行环境的最终大小在5MB – 9 MB 之间。值得注意的是这个运行环境仅仅需要被下载一次。

1.9 阿波罗与Macromedia Central的关系是怎样的?

虽然目前阿波罗团队中许多人是来自Macromedia Central的,但是阿波罗同Central并没有直接的联系。

我们从Central中学到了许多东西(什么可行,什么不可行),在设计阿波罗的时候,我们也把这些经验考虑进去了。

阿波罗的基础代码同Macromedia Central的基础代码是完全不同的

2

开发

2.1 在阿波罗平台上,我可以使用哪些技术来开发阿波罗应用程序?

阿波罗可以允许你使用Flash/Flex , HTML/JavaScript或者他们的组合来开发你的应用程序。

Flash 编写的应用程序可以包含HTML,而HTML编写的应用程序也可以包含Flash.

另外,阿波罗应用程序可以同PDF文档很好的整合。

2.2 我可以使用HTML和Javascript来开发阿波罗应用程序吗?

是的

2.3 我应该是用什么样的集成开发环境(IDE)来开发阿波罗应用程序?

你可以使用任何你目前开发Flash, Flex, HTML, JavaScript使用的IDE。(比如FlexBuilder, Eclipse, vim 等)阿波罗并不强制要求你使用任何特别的IDE.

我们会发布一些命令行工具来帮助开发人员们在他们常用的开发环境中更方便的打包,开发。

实际上,你可以使用任何可以生成swf或者HTML 文件的工具。

2.4 我可以使用Flash 开发工具来创建阿波罗内容吗?

是的,只要你使用支持ActionScript 3.0 / AVM2的工具。(比如Flash开发工具的下一个版本)。

目前在Labs上,有一个用来预览ActionScript 3的Flash开发工具。

2.5 阿波罗运行环境如何发行?

阿波罗运行环境会有很多发行方式,包括但是并不限于一下:

  • 从Adobe的网站上下载
  • 同Apollo应用程序一起发布(为了防止用户没有安装过阿波罗运行环境)

我们同时也在发掘其他的发行方式,而且我们也相信阿波罗会很快达到一个很大的装机数。

我们有新的发布方式的时候,我们给出更多的信息。

注意,这个话题在这里有更详细的讨论。

2.6 开发人员可以随自己开发的应用程序发布阿波罗运行环境吗?

是的,除了可以创建并且发布跨平台的阿波罗安装文件,开发者还可以创建本地安装程序来检查用户是否已经安装了阿波罗运行环境。如果没有,那么就可以先安装阿波罗运行环境,然后,再安装用户创建的应用程序。

注意,这个话题在这里有更详细的讨论。

2.7 阿波罗应用程序是如何安装的?

安装阿波罗应用程序同安装任何其他应用程序是很相似的。用户下载一个跨平台的安装文件,双击安装文件开始安装过程。

阿波罗会提供同当前操作系统一致的安装过程,因此,终端用户的体验决定于他们运行的操作系统。

我们同时也在发掘其他阿波罗应用程序的安装方式。

2.8 阿波罗使用什么HTML和JavaScript 解释引擎?

HTML 和 JavaScript 是由WebKit HTML/JavaScript 引擎解释的。

2.9 阿波罗使用的WebKit同运行在Mac OSX(苹果电脑的操作系统)上的Safari浏览器(苹果平台上的网页浏览器)以及KDE中的KHTML浏览器(Linux上使用较多的网页浏览器)使用的WebKit一样吗?

是的

2.10 Adobe 为什么选择WEBKIT

我们花了相当多的时间研究了许多的HTML 引擎。 我们有如下四个考虑标准,WebKit满足所有这四点:

  • 我们可以贡献我们努力的开源项目
  • 已经证实可行的技术,而且用户和开发人员都比较熟悉
  • 文件大小上必须对阿波罗影响最小
  • 必须能够在移动设备上运行

虽然最终很难做出抉择,但是我们觉得WebKit是阿波罗的最佳选择。

2.11阿波罗使用WebKit会导致开发人员依赖一个新的HTML解析引擎吗?

不会,我们的目标是与目前的WebKit保持绝对兼容。这样就保证了在其他基于WebKit的浏览器(比如 苹果的Safari)中运行的应用程序同样也可以运行在阿波罗上。

2.12 Adobe 是否打算向WebKit 项目提交变化?

是的,我们的目标是成为WebKit社区的活跃成员。我们会很积极的提变化和修正。

2.13 这个WebKit是和Mac OS X 中的WebKit同一个框架?

不是的,WebKit 开源项目与 苹果的WebKit 框架 是两个不同的事物。

阿波罗直接使用WebKit 项目中的代码,而不是苹果的WebKit 框架。

2.14我可以在哪里找到更多WebKit的信息?

你可以从以下:

2.15 阿波罗应用程序可以和其他阿波罗程序互相通讯吗?

是的,我们会实现一个内部应用程序交流协议(IAC)来使得阿波罗应用程序之间更方便的互相通讯。

2.16 阿波罗应用程序可以直接使用数据库吗?

阿波罗1.0不会提供直接连接数据库的支持。然而,你是可以使用ActionScript(使用XML Socket 或者 Binary Socket)来写数据库驱动程序的。这样,可以让阿波罗应用程序直接同数据库通讯(本地或者远程均可)

2.17 开发者/设计者对其设计的阿波罗应用程序的界面有多大的控制?

开发人员和设计者对于阿波罗应用程序的界面会有100%的控制。

2.18 我可以重用我原来的Flex2代码吗?

可以,实际上,你不必写任何代码来使已经存在的Flex2应用程序运行在阿波罗上。但是,如果你想使用阿波罗的新特性,还是需要写一些相关代码的。

2.19 阿波罗向开发人员开放的API都有哪些?

已经公开讨论过得API有如下:

  • 文件读写
  • 联机 / 脱机
  • 窗口
  • 剪切板
  • 系统托拽
  • 网络支持
  • 本地存储以及设置

更多

2.20 阿波罗应用程序可以脱机工作吗?

是的,阿波罗会提供一系列API来实现联机工作的应用程序脱机工作。

2.21 开发人员可以用本地语言扩展阿波罗吗?

我们正在探索这方面的可行性。

2.22 阿波罗是否提供一个应用程序升级的机制?

是的,阿波罗会提供一个机制使得你的应用程序可以方便的升级。

2.23 阿波罗是否是一个exe或者演示文档开发工具?

不是,阿波罗是一个运行在客户端的跨平台的运行环境。

它的其中一个优点是安装文件可以小很多。因为你不需要每次都安装这个运行环境。

另外一个好处就是,你可以将Flash,HTML,PDF这几项技术在一个很低的层面整合到一起,而整合这些技术的优点在其他运行环境下都是几乎不可能的。

最后,他允许我们为阿波罗应用程序和用户提供一个更加标准并且更加统一的安全模型。

2.24 阿波罗运行环境提供怎样的安全机制?

我们的目标是给开发人员提供他们想要以及必需的功能,而仍然可以让他们开发一个安全的应用程序。

我们现在正在探讨阿波罗运行环境的安全模型的细节,当我们有细节的时候,我们回更新这个问答列表。

2.25 我可以用阿波罗创建CD-ROM 或者Kiosk应用程序吗?

你可以通过CD-ROM安装或者发行阿波罗应用程序, 但是,在现阶段,我们并没有打算让一个阿波罗应用程序直接从光盘上运行。你必须首先在用户电脑上安装你的应用程序。

当然,你可以可以创建基于Kiosk 的应用程序并且把它部署在阿波罗运行环境下。然而,这个并不是阿波罗1.0设计的目标。

2.26 Macromedia Central 可以在阿波罗上运行吗?

不可以。

Central 应用程序是基于ActionScript 2 而且使用老版本的Flash 播放器(AVM 1)。并且,所使用的应用程序架构与Central有非常大的依赖性。因此,Central 应用程序是不可以运行在阿波罗上的。

2.27 Flash 8 以及一下版本的swf是否可以运行在apollo上?

是的,然而,阿波罗的API仅仅能够通过ActionScript 3 / AVM2 来调用。因此,使用Flash 8 创作的内容虽然可以运行,但是,却不能直接访问阿波罗的API。

3 新闻和信息

3.1 我如何向阿波罗团队提交功能要求?

你可以发送邮件到:wish-apollo@adobe.com

3.2 我在哪里可以找到最新的关于阿波罗的信息?

3.3阿波罗是否会被在哪些将要到来的会议上提及?

http://weblogs.macromedia.com/mesh/archives/2006/09/public_apollo_c.html

4 问答录信息

4.1这是否是官方的问答录?

是的。

它由Mike Chambers维护。他负责管理Adboe阿波罗开发人员关系。

4.2 我如何向问答录提交我的反馈

你可以通过下面链接发送反馈

http://labs.adobe.com/wiki/index.php/Apollo:DeveloperFAQ