存档
11个以上的手把手游戏开发教程
Flash是个非常灵活的游戏建立工具,大多数时候我们从网上可以找到flash游戏AS3资源比如Zuma-like Flash Game With AS3 Source Code,对于想建立自己游戏的初学者来说,手把手教程是个好的选择。很多网站都提供了免费或付费的 flash教程,这儿收集了十一个以上的flash游戏开发手把手教程。慢用!
Flash 里的高等数学函数
许多flash用户想利用自然运动法则做些真正酷的东西。能在屏幕上基于几何运算来移动物件不是很不错吗?不幸的是,flash 4能提供的高等数学函数只有Int()和Random()。两个都很有用不过我们真正需要的是Exp(), Sqrt(), Sin(), and Cos(),对不?不过,你很幸运。这个教程教你如何做出这东西并附带一段简单的代码。不用担心,即使你不懂泰勒级数,你也仍能够拷贝对的代码过去自己的flash影片中。
下载 (195.96 KB)
昨天 19:26
AS3特色运动:小行星360度运动
如果我们要谈特色运动的话,最重要的莫过于基于旋转的360度运动。我不知道它是不是有特别的名字,我所知的就有360度运动,旋转运动,定向运动到小行星风格运动。从任何角度来看,它都属于游戏史上由来已久的运动风格,也必然是如今flash游戏工业的有益选择。那么做这种基于角度的运动有多难呢?一点也不难。
基地保卫者
游戏目标是通过射击来袭的飞机和它们扔下的炸弹来保卫埋在草丛下的TNT。如果有炸弹落到草地上,就会留下一个坑。当炸弹接触到TNT的时候游戏失败。飞机将会越来越快的出现,扔炸弹的速度也一样。击中一架飞机或者炸弹得一分。
下载 (69.92 KB)
昨天 19:26
创建一个纵向射击手
我们将创建一个让我们的超级英雄Pawel射杀穿屏而过飞龙的游戏。我提供了所有FLA所需的图片,不过你需要把图片摆到对的地方。相对于其他面面俱到的垂直射击游戏教程,这个教程更多的是在解释某些设计工作的代码。
下载 (44.26 KB)
昨天 19:26
Flash竞速游戏教程
这个教程将是其他一系列此类教程的开始。
下载 (27.8 KB)
昨天 19:26
游戏创建教程
这个教程是一篇手把手的长篇文章的第一部分,它将指导你经历创建Flash游戏的全过程,包括输入管理,基本物理,碰撞检测还有更多。
下载 (9.73 KB)
昨天 19:26
如何用XML和ActionScript在Flash 8里做一个动态杀人游戏?
在这个针对Flash8和AS2的详细课程里,我将向你展示如何创建一个完整的动态杀人游戏。这个课程本来准备给中高级As用户的。如果你完全是新手,我建议你了解多点ActionScript再回到这里来学习。作为该课程的延续,你需要知道基本的As概念,比如变量,if/else条件逻辑,for循环,函数基础,路径,动态文本域和影片剪辑事件。
下载 (49.17 KB)
昨天 19:26
通过简单的避让游戏教程学习AS3
很多Flash开发者发现从AS2到AS3的跳跃是非常令人畏缩的,相反很多其他语言的程序员却发现AS3很直观,而很讨厌AS2。这个教程不需要你知道AS2,甚至不需要你用过Flash。如果已经有某些语言的编程基础的话你将会发现很简单,像变量,if声明体,循环,和函数,没有基础也不用担心。我将指出AS2和AS3之间的主要不同,以便Flash开发者做好转换,不过我不会集中精力讲这些。
下载 (30.08 KB)
昨天 19:27
做一个基础塔防的Flash游戏
游戏概念很简单:有条路,路上走着些奴隶。你必须在他们到达路端前杀掉所有奴隶。你可以建立设施来杀奴隶,并赚钱升级武器,同时奴隶也会变得更强大移动更快。
下载 (195.34 KB)
昨天 19:27
Flash游戏里的射击目标
这是基础空间射击游戏教程的续篇,就是用导弹摧毁小行星的那个。如果你没有跟过这个教程,可以下载FLA。
下载 (50.56 KB)
昨天 19:27
As的简单猜拳游戏
我们都玩过这样的游戏:标记0到1000之间的数,让其他人猜。简单的反馈高了还是低了的信息最后指向答案。
下载 (23.27 KB)
AS程序员实用工具类
字符串:
QueueLoader
QueueLoader是一个顺序载入资源并监控的as类库。还能加载图片,SWF,MP3,XML……QueueLoader是为AS3设计的,并且开源了。
URL-Prioritization Class
Url prioritization class它支持Loader,URLLoader以及Sound对象(也许有一天能支持NetStream对象)。它允许你设置请求的优先级以便这些对象能正确的顺序执行,还能查看当前的执行请求和载入请求。
MusicBuilder & SoundObject
这是一组类,包括MusicBuilder,SoundObject,SOCollection,Timer。这些类允许你使用multiple streaming mp3声音文件建立自己的音乐。它使用了一个新的Timer类,能够精确计算到毫秒,现在你能无缝的循环播放你的MP3文件。
SoundController Class
SoundController class管理声道。当当前声道达到最大值的时候,SoundController类会停止最早的声音,因此你可以播放新的声音。这类似“队列”的结构。当你添加新的声音,最早的声音被删除。
Sound Manager Class
这是个单例,可以在你的游戏/项目的任何地方被使用。只需要将你所有的声音文件注册到这个单例中,然后通过ID使用它们。
Using the Sound, SoundChannel, SoundTransform classes
正如你所见,这篇东东谈的是如何使用Sound, SoundChannel, SoundTransform类
声音类:
As 3 Inflector
这个转换器支持单/复数转换,驼峰,下划线,人性化(首字母大写等)
AS3 StringTokenizer
在java.util包内有一个非常有用的工具,就是StringTokenizer类。AS的StringTokenizer类是一个很方便的类,它提供一个简单的机制,使用特定的个人标记来分割字符串。
ActionScript 3 Inflector class for pluralizing and singularizing words
这个转换器支持大多数的单词的单复数转换。它本质上是Rails inflector类的端口
zeh.compression.LZW (AS2)
LZW是一个静态类,它允许使用Lempel-Ziv-Welch – or LZW – algorithm进行字符串压缩。它提供了一个快速引擎进行良好的压缩。这个引擎能够循环分割,很利于发送大量可压缩数据到服务器。比如说一张图片的点阵。
Sprintf.as
格式化字符串是一个很便利的功能,但杯具的是Flash AS库中没有。这个类增加了sprintf(把格式数据写成串)功能
文本类:
TextMetrics–寻找子串坐标,行宽等
你是否需要在动态TextField中找出换行?是否需要精确定位x/y,宽/高进行高亮显示。或者需要知道每行的宽度?gs.utils.text.TextMetrics类可以帮到你。
HTMLStyle
这是为了简化Flex中的html-text开发的组件。HTMLStyle使用几乎相同的标签,也使用与ActionScript代码。
AS3 AutoComplete class
ActionScript工程中的AS3 AutoComplete类。
Flash Text Search Engine Class
一个轻量级的多功能ActionScript文本搜索引擎。你可以简单的使用它,或者使用专家功能例如排除字符,大小写等。
Playing with Text in AS3
这篇教程将教你AS3中基本的文本格式处理。你应该会创建Textfield,改变它的颜色和属性,定位,嵌入字体。我们将使用TextField类和 TextFormat类去完成这些任务。
ActionScript Spellchecker for Flash Textfields
这个类允许你使用TextField中的拼写检查功能。现在,你能右键单击拼错的单词并且从字典中加载上下文的建议。
TextAnim
TextAnim是一个可扩展的,用来创建文本动画的类。思路是将文字打散成序列块,然后就可以自由的做你想要的动画。至于选择哪种补间引擎就无所谓了:Tweener,BTween,GTween,Tweensy,TweenLite……
颜色类:
Color Name Class
它根据SVG1.0定义颜色名和16进制的值。
ColorMatrix Class for AS3
和as2版本相比,作者增加了一些新的方法并尽可能的做了优化。
TweenMax
TweenMax扩展至快速轻便的TweenLite引擎。这次又增加了许多有用的功能像timeScale,AS#事件调用,终点设置,yoyo(tween动作 不停地往复循环 指示补间动画按与其补间属性最后一次增加的方向相反的方向播放),重复,延迟重复,四舍五入等。(我想这可能可以用来做颜色的过渡动画)。
Actionscript 3 Color Sampler Class
显示对象的颜色取样引擎。定义一个BitmapData的取样区(宽,高,x,y)并计算该区域的平均值。能够在该区域内取得RGB的红绿蓝通道,色调,饱和度和亮度的数值。
AdvancedColor
AdvancedColor对象主要是扩展了内置的颜色对像,它还提供了静态的方法,能够让颜色的值在色彩模式之间转换。
ColorFader:
在指定的时间内渐变到一个指定的16进制颜色。
Designer Class
用这个易使用的类去控制flash中的绘图API。用简单的AS命令就能绘制圆形,方形或者比较复杂的梯形。
Bitmap类:
Bitmap在我们的开发中使用率很高,这意味着掌握它很重要.实际上,有很多现成的类可以帮助我们更简单的操作Bitmap对象。接下来我们收集了8个关于Bitmap的类供大家参考,希望大家会喜欢。
AS3 Scale9 Bitmap
一个创建9宫的类。
AS3 bitmap mosaic class
很有趣的类,将图片进行马赛克处理
Active Window Blur
这个有点像flex中Alert后模糊的背景。
Animated Bitmap Class
这是一个动画播放类
CollisionDetection Class
这是一个用来检测碰撞的类
DistortImage Class
用来进行图像扭曲变形的类
ImageLoader
图片的加载管理类,有点像对象池的概念。
Reflection class
倒影类
(转)AS3声音合成(4)-音调类
为了让代码可重用性更深入些,我把它移到自己的类里,叫做 Tone。我也做了些优化和其他小伎俩。最重要的是我并非在每一个SAMPLE_DATA事件里计算下一批伴随封套的样本,而是在前一个封套里预先计算所有样本,并储存在一个矢量数列里。下面是这个类:
- 01 package
- 02 {
- 03 import flash.media.Sound;
- 04 import flash.events.SampleDataEvent;
- 05 import flash.events.Event;
- 06
- 07 public class Tone
- 08 {
- 09 protected const RATE:Number = 44100;
- 10 protected var _position:int = 0;
- 11 protected var _sound:Sound;
- 12 protected var _numSamples:int = 2048;
- 13 protected var _samples:Vector.<number>;
- 14 protected var _isPlaying:Boolean = false;
- 15
- 16 protected var _frequency:Number;
- 17
- 18 public function Tone(frequency:Number)
- 19 {
- 20 _frequency = frequency;
- 21 _sound = new Sound();
- 22 _sound.addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleData);
- 23 _samples = new Vector.<number>();
- 24 createSamples();
- 25 }
- 26
- 27 protected function createSamples():void
- 28 {
- 29 var amp:Number = 1.0;
- 30 var i:int = 0;
- 31 var mult:Number = frequency / RATE * Math.PI * 2;
- 32 while(amp > 0.01)
- 33 {
- 34 _samples[i] = Math.sin(i * mult) * amp;
- 35 amp *= 0.9998;
- 36 i++;
- 37 }
- 38 _samples.length = i;
- 39 }
- 40
- 41 public function play():void
- 42 {
- 43 if(!_isPlaying)
- 44 {
- 45 _position = 0;
- 46 _sound.play();
- 47 _isPlaying = true;
- 48 }
- 49 }
- 50
- 51 protected function onSampleData(event:SampleDataEvent):void
- 52 {
- 53 for (var i:int = 0; i < _numSamples; i++)
- 54 {
- 55 if(_position >= _samples.length)
- 56 {
- 57 _isPlaying = false;
- 58 return;
- 59 }
- 60 event.data.writeFloat(_samples[_position]);
- 61 event.data.writeFloat(_samples[_position]);
- 62 _position++;
- 63 }
- 64 }
- 65
- 66 public function set frequency(value:Number):void
- 67 {
- 68 _frequency = value;
- 69 createSamples();
- 70 }
- 71 public function get frequency():Number
- 72 {
- 73 return _frequency;
- 74 }
- 75 }
- 76 }
复制代码
留意我在构造函数里调用createSamples()。这就创建了乐曲所有所需样本的矢量版本,包括了假封套的振幅。在频率setter里,样本被重建,结果就是在onSampleData掌控方法中,我只是拿_samples矢量里的这么多值赋予了字节数组,直到矢量末尾。
也要注意到振幅也随着样本——不是随着SAMPLE_DATA事件——而减少,因此它需要每次需要减少的数值越来越小。这将给出一个更平滑的封套,虽然我也不觉得这有多引人注意。
这儿有个短代码展示它如何工作:
- 1 import flash.events.MouseEvent;
- 2
- 3 var tone:Tone = new Tone(800);
- 4 stage.addEventListener(MouseEvent.CLICK, onClick);
- 5 function onClick(event:MouseEvent):void
- 6 {
- 7 tone.frequency = 300 + mouseY;
- 8 tone.play();
- 9 }
复制代码
它创建了一个音调。每当你点击舞台,它会根据y轴坐标计算出一个心的音调频率给鼠标并播放出来。够简单了吧。
不过这个类还太不完善了。只是某个进化的开局。我想增加对更灵活或者说更复杂的封套的支持,增加一个stop方法,还有其他参数来改变声音。尽管如此,愚以为,这已经相当有用了。
(转)AS3声音合成(3)——视觉化和封套
在第一和第二部分里,我们学习了如何利用Sound对象来合成声音,还有如何创建不同频率的声音。本贴将只是绕到一些你可以玩的小花样上讲讲。
第一个就是让你播放的声波可视化。在SAMPLE_DATA事件掌控器里,你已经可以通过生成2048个样本来创建波形。当你可以做到那些的时候,继续深入绘制一些以其为基础的线条也不成其为难事。看这儿:
- 01 import flash.media.Sound;
- 02 import flash.events.SampleDataEvent;
- 03 import flash.events.MouseEvent;
- 04 import flash.utils.Timer;
- 05 import flash.events.TimerEvent;
- 06
- 07 var position:int = 0;
- 08 var n:Number = 0;
- 09 var sound:Sound = new Sound();
- 10 sound.addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleData);
- 11 sound.play();
- 12
- 13 function onSampleData(event:SampleDataEvent):void
- 14 {
- 15 graphics.clear();
- 16 graphics.lineStyle(0, 0×999999);
- 17 graphics.moveTo(0, stage.stageHeight / 2);
- 18 for(var i:int = 0; I < 2048; i++)
- 19 {
- 20 var phase:Number = position / 44100 * Math.PI * 2;
- 21 position ++;
- 22 var sample:Number = Math.sin(phase * 440 * Math.pow(2, n / 12));
- 23 event.data.writeFloat(sample); // left
- 24 event.data.writeFloat(sample); // right
- 25 graphics.lineTo(I / 2048 * stage.stageWidth, stage.stageHeight / 2 – sample * stage.stageHeight / 8);
- 26 }
- 27 }
- 28
- 29 var timer:Timer = new Timer(500);
- 30 timer.addEventListener(TimerEvent.TIMER, onTimer);
- 31 timer.start();
- 32 function onTimer(event:TimerEvent):void
- 33 {
- 34 n = Math.floor(Math.random() * 20 – 5);
- 35 timer.delay = 125 * (1 + Math.floor(Math.random() * 7));
- 36 }
复制代码
我所做的,不过是清空了 graphics,设置了线条风格,并把它移到了屏幕中央左边的位置。然后让它随着样本值起伏着穿过屏幕。这让你看到以下图片:
下载 (17.37 KB)
2010-7-30 21:50
你可以看到波随着每一个新的音符变化着它的频率。
下一个把戏我是不久之前从Andre Michelle学到的。你会注意到那正弦波感觉非常平而苍白。很明显的电脑产物。这是因为波的振幅,或峰谷值,总是保持在:-1.0到1.0之间。和真实世界里的声音比起来显得不够自然。当你敲打一个钢琴键盘的时候,你会注意到声音开始会非常响亮,按住不放的话,它会调降到一个稳定的值,而当你放开它,声音会渐弱消失。这个音量变化就是所谓的声音封套。它一般具有四段描述,简称为ADSR。解释来自Wikipedia:
击打时间是指初始时从无声到峰值的水平徒增时间。
衰落时间是指从击打水平降到指定维持水平之间变化的时间。
维持水平是指音阶在大部分时间里的振幅。
释放时间是指当键被释放之后从维持水平到零的消亡时间。
Andre Michelle’s的很多声音实验和玩具都配有非常好听悦耳的铃声,所以我知道他是用了某些封套,不过我清楚封套编码很复杂。于是我向他请教。他说了一两句话作为解答,而那些我以为都是废话。基本上,你所需要的就是用全振幅开始声音并随着时间减弱它。就是这么简单。你可以丢掉那些关于击打,衰落还有维持的概念,而只是编码释放期。
在这个版本的项目里,我们只是设置了一个amp变量,值设成1.0。通过每一个SAMPLE_DATA事件,一点一点的改变振幅。并以其与样本值相乘。当新的音出现时,重设amp为1.0。
- 01 import flash.media.Sound;
- 02 import flash.events.SampleDataEvent;
- 03 import flash.events.MouseEvent;
- 04 import flash.utils.Timer;
- 05 import flash.events.TimerEvent;
- 06
- 07 var position:int = 0;
- 08 var n:Number = 0;
- 09 var amp:Number = 1.0;
- 10 var sound:Sound = new Sound();
- 11 sound.addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleData);
- 12 sound.play();
- 13
- 14 function onSampleData(event:SampleDataEvent):void
- 15 {
- 16 graphics.clear();
- 17 graphics.lineStyle(0, 0×999999);
- 18 graphics.moveTo(0, stage.stageHeight / 2);
- 19 for(var I:int = 0; I < 2048; I++)
- 20 {
- 21 var phase:Number = position / 44100 * Math.PI * 2;
- 22 position ++;
- 23 var sample:Number = Math.sin(phase * 440 * Math.pow(2, n / 12)) * amp;
- 24 event.data.writeFloat(sample); // left
- 25 event.data.writeFloat(sample); // right
- 26 graphics.lineTo(I / 2048 * stage.stageWidth, stage.stageHeight / 2 – sample * stage.stageHeight / 8);
- 27 }
- 28 amp *= 0.7;
- 29 }
- 30
- 31 var timer:Timer = new Timer(500);
- 32 timer.addEventListener(TimerEvent.TIMER, onTimer);
- 33 timer.start();
- 34 function onTimer(event:TimerEvent):void
- 35 {
- 36 amp = 1.0;
- 37 n = Math.floor(Math.random() * 20 – 5);
- 38 timer.delay = 125 * (1 + Math.floor(Math.random() * 7));
- 39 }
复制代码
这儿,我每次事件都将amp乘以0.7。这次给出了一个悦耳的铃声。小范围改动值以取得不同的曲风。或者你甚至可以做些有趣的颤音比如:
- 1 amp = 0.5 + Math.cos(position * 0.001) * 0.5;
复制代码
以上,为本次全文。
(转)AS3里的声音合成(2)-波
该贴将展示如何使用AS3 的Sound对象生成特殊频率的正弦波。这里假设你已经阅读,或者熟悉该系列里的第一篇文章的数据。
声音的基础
声音本身基本上是空气压力的改变。很粗糙的一种说法。空气由不同的分子组成。他们并不是平均分配的。在更多压力的地方他们会聚集得更紧密,而其他地方他们之间的距离就拉大了。当某些东西如吉他弦振动时,它迅速的向前向后以特定的速度运动。当向一个方向运动时,它推动空气里的分子向同方向的其他分子靠近。接着就造成了一股密集的空气。之后弦向相反方向运动,造成了一小点真空的范围。非完全真空,只是较少分子的区域而已。它又一次运动回来,造成了另一边的密集空气。密集与松垮的空气区域在房间里传播最终撞击到你的耳膜。耳膜随之起伏。结果就是你的耳膜开始无限接近于与吉他弦相同频率的振动。这导致一些骨头开始振动,接着是神经,接着有个信息进入你的大脑,你说:“哦,这是升C大调”。录音的时候,你使用一个麦克风作为某种电子耳朵。它有某种膜或者其他什么可动的部分来产生振动以产生电子信号,以便用某种方式记录下来。重播的时候,电子信号重生并让扬声器以相同频率振动。这就使得空气以相同的方式被推动挤压,产生和当初吉他弦一样的声音让你听到。
合成声音
但是,我们讲声音合成的时候,完全是很肤浅的事。Flash,你的电脑声卡,还有你的耳机或者扬声器将生成正确的电子信号并振动空气。但是你需要计算出振动的幅度还有速度。
在教程第一部分,我们生成了随机值让扬声器或者耳机毫无规律的振动,最终是呈现出类似无线电的噪音。生成一种实际的音频需要多一点的工作,最好多一点对此的了解。
数字声音
模拟声音的世界里,如树脂唱片或者八轨磁带(这里揭露了我的年龄),声音被平滑编码的方式,是通过唱片里撞击成的凹槽中或者通过改变磁带里的磁场来实现的。数字声音则是以一定的时间间隔采集声音压力样本值。
举个最简单的声音形式的例子来说,一个正弦波,这儿有个平滑的模拟版本:
下载 (24.95 KB)
2010-7-28 23:31
这儿是同一个波,表现的是50个样本:
下载 (13.87 KB)
2010-7-28 23:31
你也看到了,采样版本不如平滑波精确。但是,在高质量的数字声音里,样本数多到已经不可能被普通大众分辨出有什么不同。当你在合成声音的时候,你将要每秒处理44,100个样本。记住这个数字,我们将用它做一些运算。
现在,我们需要做的就是用一系列形成正弦波的值来生成样本点,就像你在上面所看到的。正弦波的最高峰是1.0,最低值是-1.0,中间值是0.0。为了便于上手,我们将生成一个完整秒的单独正弦波。为了记录我们的位置,我们使用一个叫做position变量。我们初始化它为0,随着它的每一次的增加而创建一个新的样本。因此在音频的第一秒里,position将从0到44100变化。
如果我们如果我们将位值除以44100,我们将获得从一秒里0.0到1.0的变化。而如果我们把它乘以2PI,我们将得到从0到2PI的值,刚好是我们赋予函数Math.sin用于产生正弦波所需要的。这是到目前为止的代码:
Actionscript:
- import flash.media.Sound;
- import flash.events.SampleDataEvent;
- import flash.events.MouseEvent;
- var position:int = 0;
- var sound:Sound = new Sound();
- sound.addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleData);
- sound.play();
- function onSampleData(event:SampleDataEvent):void
- {
- for(var i:int = 0; i < 2048; i++)
- {
- var phase:Number = position / 44100 * Math.PI * 2;
- position ++;
- var sample:Number = Math.sin(phase);
- event.data.writeFloat(sample); // left
- event.data.writeFloat(sample); // right
- }
- }
复制代码
运行文件,你将每秒都生成一个完整周期的正弦波。当然,1赫兹的声波低于人类听力底线。为了得到特殊频率的声音,只需要乘以你想听到的倍数。人类大概可以听到25到25,000赫兹的声音。标准音阶里中央A是 440赫兹。我们试一下。改变计算样本的那一行为:
Actionscript:
- var sample:Number = Math.sin(phase * 440);
复制代码
那是A.。网上你可以找到以下的类似图表。
- A 440
- B flat 466
- B 494
- C 523
- C sharp 554
- D 587
- D sharp 622
- E 659
- F 698
- F sharp 740
- G 784
- A flat 831
- A 880
复制代码
或者,如果你想得到更数学化的表示,那么高于或低于440的每一个音阶n的频率计算公式为:
- 440 * 2^(n / 12)
复制代码
我们可以通过设置变量n来呈现各音阶,通过上面的公式来按时提升频率。
Actionscript:
- import flash.media.Sound;
- import flash.events.SampleDataEvent;
- import flash.events.MouseEvent;
- import flash.utils.Timer;
- import flash.events.TimerEvent;
- var position:int = 0;
- var n:Number = 0;
- var sound:Sound = new Sound();
- sound.addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleData);
- sound.play();
- function onSampleData(event:SampleDataEvent):void
- {
- for(var i:int = 0; i < 2048; i++)
- {
- var phase:Number = position / 44100 * Math.PI * 2;
- position ++;
- var sample:Number = Math.sin(phase * 440 * Math.pow(2, n / 12));
- event.data.writeFloat(sample); // left
- event.data.writeFloat(sample); // right
- }
- }
- var timer:Timer = new Timer(500);
- timer.addEventListener(TimerEvent.TIMER, onTimer);
- timer.start();
- function onTimer(event:TimerEvent):void
- {
- n++;
- }
复制代码
相应的,我们可以借助于Math.random做一个可怜的人造作曲家:
Actionscript:
- function onTimer(event:TimerEvent):void
- {
- n = Math.floor(Math.random() * 20 – 5);
- timer.delay = 125 * (1 + Math.floor(Math.random() * 8));
- }
复制代码
这就产生了不同音阶的音,还有每个音的不同的时长(从八分之一秒到一秒)。
仅仅凭此,你就可以开始着手自己的音序器或者小型钢琴或者其他类型的乐器。稍后,我将尝试贴出关于其他波形的东东,集合波,封套,和其他话题。
(转)AS3里的声音合成(1)——基础,噪音
我早就想就此话题写些东西了。最近我对于该领域仍然没有一整套的好资料而烦恼。我想要给点成套的东西出来。
我们将从了解声音对象的基本机制入手,如何写代码,制造些随机噪音。然后,我们开始生成实时的波形,并把他们混合在一起,等等。
开门见山
Flash 10 有合成声音的能力。Flash 9实际上也可以hack来用,不过10里面标准化了。
说说工作原理。创建一个新的Sound对象并增加一个针对SAMPLE_DATA事件的侦听器(SampleDataEvent.SAMPLE_DATA)事件发生的前提是没有更多声音数据传入。然后你可以开始播放了。
Actionscript:
- 1. var sound:Sound = new Sound();
- 2. sound.addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleData);
- 3. sound.play();
复制代码
此时此刻,你实际上并没有声音文件供装载播放——比如MP3,WAV等等,也没有附着任何声音流数据,所以没有任何东西可以放,而SAMPLE_DATA事件因此马上触发。所以我们需要个相关的掌控函数。
Actionscript:
- 1. function onSampleData(event:SampleDataEvent):void
- 2. {
- 3. }
复制代码
我们此时的目标是给这个Sound对象一些声音数据用来播放。该怎么做呢?首先,传递给函数的 SampleDataEvent是字节数组型的参数。我们要用一些代表声音的字节数组去填充它。写入数据用的是ByteArray.writeFloat 方法。一般值为-1到1
每一个你写的浮点值都会成为一个众所周知的采样点。因此形成“SampleDataEvent”。你需要写多少个采样点呢?一般在2048到8192个之间。
好了,那是一个大数目。怎么办好呢?如果你一直用低的数字如2048,声音就会在采样值之间快速的跳跃,另一方面,SAMPLE_DATA事件也会频繁触发,需要再次响应。而如果你用大的数字如8192,Sound将会用四倍于之前的时间间隔来采集那些值,因此你能执行的掌控函数的次数仅为之前的四分之一。
所以更多采样点意味着更好的性能。不过,如果你的是动态产生的声音,多采样点就意味着更长的时延。所谓的时延就是指UI或者程序发生某些变化时相配合的实际音效和视觉变化之间的时间误差。比如,你想把一个400Hz的音频在用户点击按钮的时候改成800Hz。用户点击了按钮,但是 Sound在缓冲里还有属于400Hz的8000个采样点必须先播完。之后它才会调用SAMPLE_DATA事件掌控器来要求更多数据。这时你才能转变成 800Hz的音频。因此,用户会注意到轻微的延迟出现在按钮按下和音频改变之间。如果你使用低采样的2048,延迟将会变短而不易察觉。
现在,我们只是生成一些噪音。我们将写2048个随机样本,值在-1.0到1.0之间。你需要知道的东西首先是你实际上将要写两次浮点数——一个左声道一个右声道。下面是全部程序:
Actionscript:
- 1. import flash.media.Sound;
- 2. import flash.events.SampleDataEvent;
- 3.
- 4. var sound:Sound = new Sound();
- 5. sound.addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleData);
- 6. sound.play();
- 7.
- 8. function onSampleData(event:SampleDataEvent):void
- 9. {
- 10. for(var i:int = 0; i <2048; i++)
- 11. {
- 12. var sample:Number = Math.random() * 2.0 – 1.0; // -1 to 1
- 13. event.data.writeFloat(sample); // left
- 14. event.data.writeFloat(sample); // right
- 15. }
- 16. }
复制代码
运行之后,你应该可以听到一些类似电台频率之间的那种噪音。注意我们做出来的是左右声道同值的单独样本。因为两个声道都有精确相同的样本值,我们获得了单声部的声音。如果我们要立体声,我们可以做类似下面的东西:
Actionscript:
- 1. function onSampleData(event:SampleDataEvent):void
- 2. {
- 3. for(var i:int = 0; i <2048; i++)
- 4. {
- 5. var sampleA:Number = Math.random() * 2.0 – 1.0; // -1 to 1
- 6. var sampleB:Number = Math.random() * 2.0 – 1.0; // -1 to 1
- 7. event.data.writeFloat(sampleA); // left
- 8. event.data.writeFloat(sampleB); // right
- 9. }
- 10. }
复制代码
这里我们为每个声道的每一个采样点写上不同的随机值。带上headphones听这个,你应该注意到噪音里多了些“空间”。很微妙以至于在运行时很难分辨,我们更改以便可以进行快速调节。
Actionscript:
- 1. import flash.media.Sound;
- 2. import flash.events.SampleDataEvent;
- 3. import flash.events.MouseEvent;
- 4.
- 5. var sound:Sound = new Sound();
- 6. sound.addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleData);
- 7. sound.play();
- 8.
- 9. var mono:Boolean = true;
- 10. stage.addEventListener(MouseEvent.CLICK, onClick);
- 11. function onClick(event:MouseEvent):void
- 12. {
- 13. mono = !mono;
- 14. }
- 15.
- 16. function onSampleData(event:SampleDataEvent):void
- 17. {
- 18. for(var i:int = 0; i <2048; i++)
- 19. {
- 20. var sampleA:Number = Math.random() * 2.0 – 1.0; // -1 to 1
- 21. var sampleB:Number = Math.random() * 2.0 – 1.0; // -1 to 1
- 22. event.data.writeFloat(sampleA); // left
- 23. if(mono)
- 24. {
- 25. event.data.writeFloat(sampleA); // left again
- 26. }
- 27. else
- 28. {
- 29. event.data.writeFloat(sampleB); // right
- 30. }
- 31. }
- 32. }
复制代码
我们有一个布尔值,mono,让 true/false 值紧连着一次鼠标点击。true的时候,sampleA写在左右声道。如果mono不是true,我们就把sampleA写在左声道,而sampleB写在右声道。运行并点击鼠标。改变依然细微,不过你应该可以分辨出来了。
听听看,延迟的结果,改变2048到8192。点击的时候,你就可以注意到点击和单声道立体声转换之间的明显延后,反之亦然。
关于这些样本的另一个注意事项。我说过,“一般”用2048到8192之间的值。事实上你想使用大过8192的值的话,就会得到一个实时错误说一个参数不可用。所以8192是个硬限制。你可以使用低于2048的值,不过这样的话Sound对象在经过这些样本之后就会认为声音已经结束。完成的时候不会再产生另一个SAMPLE_DATA事件。取而代之的是会产生一个COMPLETE时间。所以想让声音不停播放,需要不断提供至少2048的样本。
下一部分,我们开始创作一些简单的波形
ActionScript 3.0 性能优化小知识
最近做的很多的事情都是和Flash开发有关,尤其是在性能优化上总结到不少经验,在这里分享给大家。
和其他平台开发一样,Flash程序的运行效率非常重要,为什么总有人觉得Flash程序很卡?甚至有人觉得Flash程序的运行效率还不如IE执行JavaScript 快,原因就在于写Flash程序的人,算法、代码写得太烂,最后连Flash Player的名声都被这些人写坏掉了。
高性能的程序源自高性能的算法、代码、和结构,下面就围绕着这个主题开始展开介绍。
1、改进算法
无论对于那一种程序,好的算法总是非常重要的,而且能够极大地提高程序性能,所以任何性能的优化第一步就是从算法或者说程序逻辑的优化开始,检查自己的程序是否有多余的运算,是否在没有必要的时候做了无用功,往往从这些方面就能找到那些导致性能低下的地方。
2、优化细节代码
针对细节总是好的,有一些小技巧比如:
用 var obj:Object = {}; 要比 var obj:Object = new Object();要好;
var arr:Array = []; 要比 var arr:Array = new Array(); 要好;
for (var i:int=0, len=arr.length; i
如果不是为了保存颜色值请不要适用uint这个类型,他的速度比起 int要慢多了;
Array的遍历要比Object或者Dictionary的枚举要快得多。
if (myObj != null) 要比 if (myObj) 的速度要慢(更正, 之前把结果看反了,对不起大家~), for (var i:* in myObj) 比 for (var i:String in myObj) 要快;
Dictionary当 weak key设置为 true 的时候要比 false 慢;
var myText:String = “a” + “b” + “c”;
var myText2:String = [ "a", "b", "c" ].join(“”);
在JavaScript里面在IE下后者要更快,但是在AS里面,前者更快!
在循环体内声明变量和在循环体外声明变量其实速度上不会有太大的区别。
3、权衡程序的结构
程序的架构也非常重要,良好的结构会带来性能和程序健壮性的提升,但是有的时候又是相互矛盾的,例如代码写得过于健壮,反而会影响性能,这个地方需要开发者自己去权衡。
4、小心Flash的重绘
如果你使用的是Flash Player 的Debugger版本,那么请在检查性能瓶颈的时候不要忘记打开显示重绘区域的功能,这将帮你迅速定位到舞台上有那些地方被重绘了,找出没有显示任何东西却不断重绘的地方,这些地方肯定是有问题的。Flash Player很笨,不会说你把一个DisplayObject的visible设置成false就放弃重绘那个显示对象。所以请保证你的 MovieClip在visible=false的时候为停止状态。有一点很有意思,假设两个现实物体存在 hitTest = true 这样的关系,那么重绘的区域的面积很有可能 > 两者的面积总和!
5、以空间换时间
听起来挺虚,实则很简单,说白了就是以内存换CPU,例如将不变动的值进行保存,免去下次需要此数据的时候进行再次计算,虽然原理很简单,但是有的时候却很容易疏忽掉,而这个往往就造成你的算法效率低下的问题。
6、记得销毁你的对象
对于非常驻的对象使用完之后记得消除其引用,防止出现内存溢出的问题,往往要做到这一点需要有一个良好的编程习惯。
7、清除冗余的代码
有些代码可能你的程序一辈子也不会执行到,请把这些没有用的代码或者对象清理掉,否则内存会被偷偷的蚕食掉。
8、小心使用useBitmapCache = true
一般情况下除非你确定这个显示对象不可能发生变化那么用用也无妨,不过我更推荐自己手动的用BitmapData将该对象Draw一遍,然后让这个对象彻底消失。否则每次的变动都是巨大的性能消耗。
Flash Player 10.1 和 AIR 2 正式发布
正式版
调试版
Windows
Download the Windows Flash Player 10.1 ActiveX control content debugger (for IE) (EXE, 2.72 MB)
Download the Windows Flash Player 10.1 Plugin content debugger (for Netscape-compatible browsers) (EXE, 2.69 MB)
Download the Windows Flash Player 10.1 Projector content debugger (EXE, 5.18 90 MB)
Download the Windows Flash Player 10.1 Projector (EXE, 4.96 MB)
Adobe Flash Player 10.1 Update for Flash CS5 Professional
The Flash Player 10.1 updates are included in the ZIP file below. For instructions on how to update Flash CS5 Professional, please go to this technote.
Spark Skinning Spark 皮肤制作
可以通过编辑现存的皮肤类或者建立一个新的皮肤类来制作一个Spark组件的皮肤。更多关于MX组件的皮肤制作,请看Skinning MX components.
- 关于spark皮肤
- 从源文件中制作皮肤
- 制作Spark组件皮肤
- 制作Spark容器皮肤
- 切换皮肤
- 转换Spark皮肤
- 子组件皮肤
- 打包皮肤
