Y.Boy's Blog

Web Game,Flex,Flash,AIR,RIA,ActionScript,Pixel Bender

用Starling开发的ClickBird完美地运行在智能电视上


ClickBird是一款使用Starling开发的小游戏demo,经过一段时间在各种iOS和Android系统的移动设备上测试过,性能表现很理想,绝大多数能跑60fps。这虽是一个小游戏,但基本的帧动画,缓动计算,粒子效果,切换场景时的开销计算等等都有了,能跑个60fps,我觉得已经是不错的。如果用AIR不做游戏,而做个应用,性能已经足够有余。

除了移动设备,今天我特地在互联网电视(也称智能电视)上做了个测试,总体超出预期。测试机是乐视的S50,android系统,50寸,1920*1080分辨率。用的是体感遥控,用体感遥控玩Flash小游戏,顿时觉得有些高大上。这款用Starling做的游戏,从移动设备移植到智能电视上,基本不用改什么代码。只是做互联网电视应用需要注意一点:屏幕永远竖直向下,没有重力感应,也不能转屏。另外,除了智能电视,还可以在电子盒子上安装(例如乐视盒子)。

用Adobe AIR来开发东西,爽!快!适合在各种移动设备上开发游戏和应用。对于智能电视方面,不知道现在家庭智能电视市场怎么样,但从技术上讲,用Adobe AIR来开发电视游戏或应用很是可以。

  • 请从这里下载iOS和Android的安装文件:http://riaoo.com/?p=2602
  • 备注:想安装在android智能电视或电视盒子上,请把apk文件复制到U盘,在电视里从U盘安装,这样是最快的并且可避免很多麻烦。因为我在电视里发现下载不了网盘上的文件。


【更新:iOS和Android】一个Starling的小游戏demo:点小鸡 v1.5


一直看到Adobe AIR在一直更新版本,可以看到新增功能点不多,但在质量和性能方面有所提升。这很好,性能才是关键,目前的功能特性用来做些应用和小游戏还是足够有多了。前些天Adobe发布了Flash Runtime在2014年的路线图,产品经理心血来潮地说了些话:《Flash Runtime产品经理正能量地回复了”AIR is Dead”一贴

于是用空闲的时间做了个demo,感觉性能还是很可以的,经常跑到55fps以上,偶尔掉到40fps。资源是提取网上其它游戏的,demo仅供测试无商业用途,我留下了邮件地址,欢迎原作者与我联系。

 


Flash Runtime产品经理正能量地回复了”AIR is Dead”一贴


2014年的Flash Runtimes路线图更新后,Adobe论坛上一个贴子被挖了出来,名为”AIR is Dead“。然后Flash Runtime产品经理正能量地回复了一下,翻译如下:

2014年的Flash Player和AIR

Adobe一如既往地发展和完善Flash Player和AIR。随着向前的发展,在每季度发布的版本里都会涌现我们提到过的新特性,每当有新特性出现了,我们会定期更新到发布文档中。在2014年,我们增加以下这些新东西:

安全性

安全性依然是我们的首要任务、重中之重!我们会逐步解决安全性的相关问题。特别地,我们会继续积极主动地去研究并作出一些实质性的改变来减少Flash Player和AIR受到的黑客攻击。

质量和性能

数亿人在他们日常的在线生活中都会使用过Flash运行时,成千上万的企业都凭借着Flash运行时取得成功。我们意识到,他们都非常重视稳定性和性能效率。我们必须在发现严重问题时马上解决它,并且继续不断提升运行时的质量和性能。

新特性

以下这些新特性和新功能已经在我们的产品开发任务中,在未来的一些日子里我们会实现它们:

  • Final release of iOS packaging time reduction
  • Flash Player – Chrome debugger
  • AIR – Concurrency for iOS
  • AIR – Gamepad support for iOS 7
  • AIR – Game marketing and discovery
  • Stage3D – AGAL 2.0 support
  • Stage3D – Support for multiple render targets
  • Stage3D – Anti-Aliasing for render textures
  • Stage3D – New texture wrapping modes
  • Supplementary character enhancement support for the TextField control

注意:除了以上这些,我们也会在Bug库里(bugbase.adobe.com),找出那些急需解决的问题,并解决它。

然后在移动设备方面,我特别需要说一下:
Adobe AIR致力于支持iOS和Android平台。在目前来看,我们并不打算支持其它平台。但是!我们会评估以后的发展情况来作出新的考虑。

我想,我需要介绍一下我自己。目前我在Adobe担任Flash运行时的产品经理和客户经理,包括Flash Player、AIR和Gaming SDK。

在18年前,我进入了Adobe,担任Photoshop 3的软件测试工程师。曾经分别在Geoworks和Adaptec两家公司当过QE,那时开始我就对质量和性能方面产生激情。在经历过Photoshop 4的发布后,我得到快速的成长。我总是热衷于创新来帮助客户并且一直认为质量和性能是重中之重。当然,提高质量和性能并不是什么让人惊喜的创新点,但我觉得如果质量和性能都无法保证,那么,什么创新性的新功能都是无用的。

在定制2014年的开发计划时,在核心团队中,只有我一个把“提高质量和性能”提出来,正是“质量和性能是重中之重”这一信念驱动着我。在2013年里,我花了大部分时间和客户进行交流。这些客户包括开发者、战略合作伙伴,还有数亿的Flash Player和AIR使用者。他们当中有要求支持新平台和增加新功能,但绝大多数人关注的是质量和性能。这也是为什么我把安全性、质量和性能放在首位。

这是否意味着我们不需要添加新功能了吗?当然不是。上面列出的新特性只是我所知道的已经是确定下来并列入路线图而已。这并不意味着我们不会添加新功能,特别地,我们会在社区交流中发现用户需求。我们甚至会为合作伙伴解决急切的问题。随着思路的改进,我们会定期更新路线图。

感谢您们的反馈以及对Flash运行时的关注和热情,我们将一如既往地带领Flash Player和AIR前进!

Thanks,
Chris

 

仔细阅读全文,真是让人激动人心。多读几次,仿佛回到从前AS2被市场逼着要升级到AS3一样带来新气勃勃。Flash能不能发展,Adobe愿不愿意投入资源来发展Flash,完全是看我们是否真的想用它了,也就是要看市场大不大了,我们就是Flash的市场了。这是双方面的,相互影响的,应该要互利共赢。


用javascript判断浏览器是否使用chrome内置的flash player


使用如下javascript代码可判断浏览器是否使用了chrome内置的flash player:

var isPPAPI = false;
var type = ‘application/x-shockwave-flash’;
var mimeTypes = navigator.mimeTypes;

var endsWith = function(str, suffix)
{
return str.indexOf(suffix, str.length – suffix.length) !== -1;
}

if (mimeTypes && mimeTypes[type] && mimeTypes[type].enabledPlugin &&
(mimeTypes[type].enabledPlugin.filename == “pepflashplayer.dll” ||
mimeTypes[type].enabledPlugin.filename == “libpepflashplayer.so” ||
endsWith(mimeTypes[type].enabledPlugin.filename, “Chrome.plugin”)))
{
isPPAPI = true;
}

alert(“PPAPI enabled: ” + isPPAPI);


我误解了的Bitmap:原来Bitmap有两种方式来绘制BitmapData的


本文是我的个人观点,望大家一起来研究。

Flash Player渲染Bitmap的确很快,比渲染矢量要快。但,大家知不知道Bitmap是如何把BitmapData绘制到屏幕上的呢?我用词很小心,不敢说“Bitmap把BitmapData渲染到屏幕上”,说绘制可能很准确。因为Adobe的文档上是说”draw”而不是”render”。

别以为,你用了Bitmap而不是矢量,渲染性能就是最快的。万万没想到,原来Bitmap绘制BitmapData有两种方式:使用矢量渲染器作为填充位图形状,或使用更快的像素复制例程(using the vector renderer as a fill-bitmap shape, or using a faster pixel-copying routine)。这是关于Bitmap的API文档里说的(http://help.adobe.com/zh_CN/FlashPlatform/reference/actionscript/3/flash/display/Bitmap.html)只有使用了第二种绘制方式,渲染Bitmap才是最快的。在以下条件,Flash Player才会使用第二种方式:

  • 不能将拉伸、旋转或倾斜效果应用于 Bitmap 对象。
  • 不能将颜色转换应用于 Bitmap 对象。
  • 不能将混合模式应用于 Bitmap 对象。
  • 不能通过蒙版或 setMask() 方法进行剪裁。
  • 图像本身不能是遮罩。
  • 目标坐标必须位于一个整像素边界上。

这是原汁原味的英文版说明:

  • No stretching, rotation, or skewing can be applied to the Bitmap object.
  • No color transform can be applied to the Bitmap object.
  • No blend mode can be applied to the Bitmap object.
  • No clipping can be done through mask layers or setMask() methods.
  • The image itself cannot be a mask.
  • The destination coordinates must be on a whole pixel boundary.

个人猜想,“使用矢量渲染器作为填充位图形状”这种绘制方式就像在内部创建了shape对象,然后进行位图填充,那么,肯定比“像素复制例程”方式使用了更多的内存。于是,我创建了10000个只有一像素的位图,分别尝试了使用blendMode和没有使用blendMode的情况,观察了内存(flash.system.System.totalMemory),证明了这一点。

最近发生在我身边的一连串事件(设置了scrollRect属性或大量位图叠加时出现透明像素不透明的情况),肯定与Bitmap这个特性有关系。我千方百计想证明这一点,但由于Flash Player就像一个黑盒,你不可能看到源码,所以Adobe文档上说的,大家相信就是了。

以后使用位图时,也要有意识地尽量满足上述条件,让Bitmap选择最快的方式去绘制BitmapData。不但提高CPU效率,也节省了内存。


总结一下使用Stage3D时的那些限制


了解一下Stage3D的那些限制,在日常开发中会很有帮助。目前总结了下面那些限制,可能还有其它,欢迎您来查漏补缺。日后如果我发现更多限制,我会第一时间补上,所以本文会持续更新。

  • AGAL 限制:每个程序 200 个 opcode [引自]
  • 绘制调用限制:每个 Context3D.present() 调用 32768 个 drawTriangles() 调用[引自]
  • Context3D.createIndexBuffer() 单个缓冲区中的最大索引数为 524287 [引自]
  • Context3D.createVertexBuffer() 单个缓冲区中的最大顶点数为 65535 [引自]
  • Context3D.createTexture()和Context3D.createCubeTexture()的参数streamingLevels的最大值是 log2(min(width,height)) [引自]
  • Context3D.configureBackBuffer() 缓冲区的最小大小为 50×50 像素 [引自]
  • IndexBuffer3D 索引为 16 位无符号整数,即所允许的最大索引值为 65535 (0xffff) [引自]
  • Program3D.upload() 两个参数都必须为Endian.LITTLE_ENDIAN [引自] (:程序会在每次调用 Context3D.drawTriangles() 方法时运行顶点着色程序和片段着色程序。顶点程序会为要绘制的三角形列表中的每个顶点执行一次。片段程序会为三角形表面的每个像素执行一次)
  • Context3D.setVertexBufferAt() 顶点着色器所使用数据的最小单位为 32 位数据。距顶点流的偏移量以 32 位的倍数指定(:GPU的寄存器被设计为128位,也就是32+32+32+32,即一个寄存器最多能放4个Number。)[备注1] [引自]
  • VertexBuffer3D 最多可以为每个点提供 64 个 32 位值(256 字节)数据(但在这种情况下,单个顶点着色器无法使用所有数据。Y.Boy注:因为顶点寄存器最大数量才8个,每个是32位,总共才32字节)。即:uploadFromVector() 方法的参数numVertices最大值可以为64。[引自]
  • 资源限制 [备注2] [引自]
  • 寄存器数量限制 [备注3] [引自]


AGAL操作码


AGAL中文全称:Adobe 图形汇编语言(Adobe Graphics Assembly Language)。以下列出所有操作码。

本文内容取自:AGAL 字节码格式

名称 Opcode 操作 说明
mov 0×00 移动 将数据从 source1 移动到 destination,按组件
add 0×01 相加 destination = source1 + source2,按组件
sub 0×02 相减 destination = source1 – source2,按组件
mul 0×03 相乘 destination = source1 * source2,按组件
div 0×04 除以 destination = source1 / source2,按组件
rcp 0×05 倒数 destination = 1/source1,按组件
min 0×06 最小值 destination = minimum(source1,source2),按组件
max 0×07 最大值 destination = maximum(source1,source2),按组件
frc 0×08 分数 destination = source1 – (float)floor(source1),按组件
sqt 0×09 平方根 destination = sqrt(source1),按组件
rsq 0x0a 平方根倒数 destination = 1/sqrt(source1),按组件
pow 0x0b destination = pow(source1,source2),按组件
log 0x0c 对数 destination = log_2(source1),按组件
exp 0x0d 指数 destination = 2^source1,按组件
nrm 0x0e 标准化 destination = normalize(source1),按组件(仅生成一个 3 组件结果,目标必须掩码为 .xyz 或更小)
sin 0x0f 正弦 destination = sin(source1),按组件
cos 0×10 余弦 destination = cos(source1),按组件
crs 0×11 叉积 destination.x = source1.y * source2.z – source1.z * source2.y
destination.y = source1.z * source2.x – source1.x * source2.z
destination.z = source1.x * source2.y – source1.y * source2.x
(仅生成一个 3 组件结果,目标必须掩码为 .xyz 或更小)
dp3 0×12 点积 destination = source1.x*source2.x + source1.y*source2.y + source1.z*source2.z
dp4 0×13 点积 destination = source1.x*source2.x + source1.y*source2.y + source1.z*source2.z + source1.w*source2.w
abs 0×14 取绝对值 destination = abs(source1),按组件
neg 0×15 求反 destination = -source1,按组件
sat 0×16 饱和 destination = maximum(minimum(source1,1),0),按组件
m33 0×17 矩阵连乘 3×3 destination.x = (source1.x * source2[0].x) + (source1.y * source2[0].y) + (source1.z * source2[0].z)
destination.y = (source1.x * source2[1].x) + (source1.y * source2[1].y) + (source1.z * source2[1].z)
destination.z = (source1.x * source2[2].x) + (source1.y * source2[2].y) + (source1.z * source2[2].z)
(仅生成一个 3 组件结果,目标必须掩码为 .xyz 或更小)
m44 0×18 矩阵连乘 4×4 destination.x = (source1.x * source2[0].x) + (source1.y * source2[0].y) + (source1.z * source2[0].z) + (source1.w * source2[0].w)
destination.y = (source1.x * source2[1].x) + (source1.y * source2[1].y) + (source1.z * source2[1].z) + (source1.w * source2[1].w)
destination.z = (source1.x * source2[2].x) + (source1.y * source2[2].y) + (source1.z * source2[2].z) + (source1.w * source2[2].w)
destination.w = (source1.x * source2[3].x) + (source1.y * source2[3].y) + (source1.z * source2[3].z) + (source1.w * source2[3].w)
m34 0×19 矩阵连乘 3×4 destination.x = (source1.x * source2[0].x) + (source1.y * source2[0].y) + (source1.z * source2[0].z) + (source1.w * source2[0].w)
destination.y = (source1.x * source2[1].x) + (source1.y * source2[1].y) + (source1.z * source2[1].z) + (source1.w * source2[1].w)
destination.z = (source1.x * source2[2].x) + (source1.y * source2[2].y) + (source1.z * source2[2].z) + (source1.w * source2[2].w)(仅生成一个 3 组件结果,目标必须掩码为 .xyz 或更小)
kil 0×27 丢弃(仅适用于片段着色器) 如果单个标量源组件小于零,则将丢弃片段并不会将其绘制到帧缓冲区。(目标寄存器必须全部设置为 0)
tex 0×28 纹理取样(仅适用于片段着色器) destination 等于从坐标 source1 上的纹理 source2 进行加载。在这种情况下,source2 必须采用取样器格式。
sge 0×29 大于等于时设置 destination = source1 >= source2 ? 1 : 0,按组件
slt 0x2a 小于时设置 destination = source1 < source2 ? 1 : 0,按组件
seq 0x2c 相等时设置 destination = source1 == source2 ? 1 : 0,按组件
sne 0x2d 不相等时设置 destination = source1 != source2 ? 1 : 0,按组件

Flash嵌入了字体却不显示的那些原因(二)


一年前,写了一篇《Flash嵌入了字体却不显示的那些原因》:http://riaoo.com/?p=2401

最近又发现了一种导致字体不显示的原因了。这次嵌入了字体却不显示的现象是:编写代码把textField的字体设为某种字体,设置textField.text属性能正确显示文本,但设置textField.htmlText属性时,如果html字符串里没有使用”font”标签来设置字体,就不能显示字体了,它会重置为设置字体前的默认字体。

例如:在fla里文本框的字体是宋体,我编写程序在运行时把文本框的字体设为某种特殊字体(该字体已正确嵌入到swf里),设置text属性都能正确显示,但如果我设置textField.htmlText属性值是”<b>Y.Boy</b>“,那么,这个textField的字体会重置为宋体。原因很简单:htmlText值里没有使用”font”标签来使用特殊字体。