AS3.0打造随风吹散效果
2010年07月29日
在这篇教程中,我们会自定义一个类,它能将一张图片分解成1000多个碎片,并模拟被风吹散的效果。我使用了FlashDevelop来创建一个AS3项目。
[b]最终效果预览[/b]
点击Flash舞台看风吹效果
[b]了解FlashDevelop[/b]
FlashDevelop是一个Flash和Flex的代码编辑器。当你在使用Flash的时候你也可以用它来编辑类文件,或者直接用FlashDevelop来创建as3工程,而不需要使用Flash―这正是本教程要做的。
因此,先下载FlashDevelop并安装它。不幸的是,FlashDevelop只能在Windows下运行。苹果系统可以选择FDT和FlexBuilder(ok,现在已经叫Flash Builder)但也不是免费的。你可以使用Flash,我也将解释使用Flash怎么做到。
[b]步骤1:创建一个项目[/b]
打开FlashDevelop并点击Porject>New Project
[b]步骤2:建立[/b]
选择ActionScript3>AS3 Project。输入项目名称“WindEffect”,选择一个文件夹保存项目。保证“Create Directory For Project”检查框被选择,然后单击OK按钮。
如果你打算使用Flash CS3/CS4。那么就创建一个新的Flash文件,并且设置舞台的宽高为550x250px。设置背景色为白色。保存为“windEffect.fla”,然后随便你喜欢保存在什么地方。
[b]步骤3:找张图片[/b]
如果是FlashDevelop,打开项目目录,复制或者拖一张windEffect.jpg图片到\bin\folder目录。
如果是使用Flash ide,复制或者拖一张windEffect.jpg图片到windEffect.fla文件同目录下。
[b]步骤4:安装TweenLite(一个补间动画类库)[/b]
我们要使用TweenLite来做补间动画。你可以在这里(http://www.greensock.com/tweenlite/)下载最新版。我已经把它包含在源文件中了。
对于FlashDevelop来说,将greensock.swc复制到项目的\lib\folder\目录下。然后单击View>
roject Manager。
[b]步骤5:外链库[/b]
不过在FlashDevelop,单击lib文件夹旁边的“+”号展开它。然后右键单击greensock.swc并选择“Add To Library”。
在Flash中,复制或者拖拽“com”目录到windEffect.fla同目录下。
[b]步骤6:文档类[/b]
在FlashDevelop中,再次打开project manager(参考步骤4),展开src文件夹,并且双击Main.as。在完成导入以及类定义之后,使用元数标签设置舞台属性
[SWF (width = 550, height = 250, frameRate = 30, backgroundColor = 0)]
在init()方法中,注释“entry point”之后,添加如下代码:
stage.scaleMode = StageScaleMode.NO_SCALE; //不伸展舞台
var effect:WindEffect = new WindEffect('windEffect.jpg'); //我们马上要创建WindEffect类
addChild (effect);
复制代码这就是Main文档类
在Flash,在fla文件同目录下新建的Main.as文件。加入如下代码:
package
{
import flash.display.Sprite;
import flash.display.StageScaleMode;
import flash.events.Event;
public class Main extends Sprite
{
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
stage.scaleMode = StageScaleMode.NO_SCALE; //don't stretch the stage
var effect:WindEffect = new WindEffect ('windEffect.jpg'); //we will create the WindEffect class soon
addChild (effect);
}
}
}
复制代码打开Flash,给文档类赋值“Main”
(如果对文档类不太明白可以看这篇教程http://active.tutsplus.com/tutor ... ent-class-in-flash/)
如果你现在试着去运行它。你将会得到一个错误,因为我们还没有创建WindEffect类。
[b]步骤7:创建WindEffect类[/b]
在FlashDevelop中,单击View>
roject Manager,右键单击src文件夹,并选择Add>New Class
[b]步骤8:设置类[/b]
命名类名为 WindEffect,单击browse按钮选择flash.displaySprite为基类。单击OK完成。
[b]步骤9:导入其他类[/b]
在package大括号内导入所有必须的类,在Import flash.display.Sprite之下,类定义之前。并保存
import com.greensock.easing.Strong;
import com.greensock.TweenLite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.net.URLRequest;
复制代码在Flash中,新建一个ActionScript文件,命名为“WindEffect.as”,并保存在项目根目录下。它和fla文件,com目录与Main.as文件在同一个目录中。
添加如下代码:
package
{
import com.greensock.easing.Strong;
import com.greensock.TweenLite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.net.URLRequest;
public class WindEffect extends Sprite
{
public function WindEffect ()
{
}
}
}
复制代码[b]步骤10:加入变量[/b]
加入一个私有的变量,名为“_pictureArray”。这是这个类中唯一的变量。它的主要作用是保存所有小sprite,每个笑sprite都记录着图像的某一块图形数据。
在括号内添加如下代码:
public class WindEffect extends Sprite
{
//这用来保存所有运动的碎片.
private var _pictureArray:Array;
}
复制代码[b]步骤11:添加构造[/b]
在_pictureArray声明下面添加:
public class WindEffect extends Sprite
{
//这用来保存所有运动的碎片.
private var _pictureArray:Array;
public function WindEffect ($url:String)
{
//我们在构造函数中调用载入图片方法。
loadPicture ($url);
}
}
复制代码[b]步骤12:操纵图片[/b]
在构造函数中调用loadPicture()方法。我们实例化一个Loader来加载windEffect.jpg。我们还添加一个COMPLKETE事件来侦听加载是否完成。
在WindEffect()之后添加如下代码(注意,参数$url是从Main.as中传过来的图片的路径)
private function loadPicture ($url:String):void
{
//创建Loader并侦听载入情况。
//加载图片
var loader:Loader = new Loader;
loader.contentLoaderInfo.addEventListener (Event.COMPLETE, onLoadComplete); //when it's loaded, call the onLoadComplete () function
loader.load (new URLRequest ($url));
}
复制代码[b]步骤13:载入[/b]
当图片完全导入的时候,这个方法就被调用了。在loadPicture()下面添加如下代码,并保存。
private function onLoadComplete (e:Event):void
{
//for testing
addChild (e.target.content);
}
复制代码[b]步骤14:测试[/b]
接着按CTRL+Enter组合键进行测试,图片就会出现在舞台的左上角。
现在,我们已经知道它能正常的加载,那么就删除addChild方法,并将它替换为如下代码:
createEffect (e.target.content);
你的WindEffect类看起来应该是这样的:
package
{
import com.greensock.easing.Strong;
import com.greensock.TweenLite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.net.URLRequest;
[SWF (width = 550, height = 250, frameRate = 30, backgroundColor = 0)]
public class WindEffect extends Sprite
{
private var _pictureArray:Array;
public function WindEffect ($url:String)
{
loadPicture ($url);
}
private function loadPicture ($url:String):void
{
var loader:Loader = new Loader;
loader.contentLoaderInfo.addEventListener (Event.COMPLETE, onLoadComplete);
loader.load (new URLRequest ($url));
}
private function onLoadComplete (e:Event):void
{
createEffect (e.target.content);
}
}
}
复制代码[b]步骤15:设置变量[/b]
createEffect()方法将传递一个图像参数,它本质上是一个位图(Bitmap),之后它会被分解为1250块。
首先,我们计算出让图像处在舞台正中央的x,y坐标。我们将坐标保存至局部变量centerWidth和centerHeight中
因为图片的尺寸为300x100,所以我决定分割的比例是:横50,竖25。这样划分会有一个很好的性能,我们将它们保存至局部变量“numberOfColumns”与“numberOfRows”中。这样图片就被分割成1250块均等的矩形,然后我们把矩形的宽高保存至“sizeWidth”与“sizeHeight”中。“numberOfBoxes”变量用来保存矩形的数目。
接着我们实例化_pictureArray数组,这样我们就能将那些矩形存进去。接下来的这些代码放在onLoadComplete()方法后面。
private function createEffect ($bitmap:Bitmap):void
{
//居中x坐标
var centerWidth:Number = (stage.stageWidth - $bitmap.width) * .5;
//居中y坐标
var centerHeight:Number = (stage.stageHeight - $bitmap.height) * .5;
var numberOfColumns:uint = 50;
var numberOfRows:uint = 25;
var sizeWidth:uint = $bitmap.width / numberOfColumns;
var sizeHeight:uint = $bitmap.height / numberOfRows;
var numberOfBoxes:uint = numberOfColumns * numberOfRows;
_pictureArray = [];
}
复制代码[b]步骤16:嵌套循环[/b]
在实例化_ pictureArray后,我们将使用嵌套循环来实现一个二维数组。第一层循环处理x坐标遍历所有列,第二层循环将处理y坐标,遍历所有行。
在实例化_pictureArray后,将下面的代码放入createEffect()方法内,保存。
for (var i:uint = 0; i bitmapdata
var tempBitmapData:BitmapData = new BitmapData (sizeWidth, sizeHeight);
//1 个临时的矩形 (x,y,width,height)
//我们通过i*sizeWidth作为x坐标的参数,j*sizeHeight作为y坐标的参数。
//还有sizeWidth以及sizeHeight作为宽与高的参数。
var sourceRect:Rectangle = new Rectangle (i * sizeWidth, j * sizeHeight, sizeWidth, sizeHeight);
trace (sourceRect);//测试
复制代码[b]步骤19:进一步测试[/b]
测试影片。可以观察到每次迭代创建的矩形情况,以便调整。
正如你所看到的,在第一个例子显示x=0,y=0下一个是x=0,y=4。这就是我们从图像上取下来的小图片的区域。接下来移除test函数。
[b]步骤20:BitmapData.copyPixels()[/b]
然后,我们使用BitmapData.copyPixels ()方法依据soureceRect来复制图像上的图形数据。这个方法的参数是需要复制的目标位图图像,需要复制的矩形区域以及目标点(它表示将在其中放置新像素的矩形区域的左上角)。
tempBitmapData.copyPixels ($bitmap.bitmapData, sourceRect, new Point);
复制代码然后我们创建一个临时位图来放置我们刚才复制的BitmapData,接着再创建一个临时Sprite来放置临时位图。
再然后我们把所有的Sprite都放入到_pictureArray中。在这之后,我们将Sprite以原有的坐标放置到舞台上,还原原始图像。
最后根据centerWidth和centerHeight调整一下位置让整副图能在舞台上居中。
添加下面的代码,并再次保存。
//创建一个临时位图来放置我们复制的BitmapData数据
var tempBitmap:Bitmap = new Bitmap (tempBitmapData);
//创建一个临时的Sprite来放置上面的bitmap,以便有交互功能。
var tempSprite:Sprite = new Sprite;
//将bitmap放入Sprite的目的是产生交互,因为bitmap是没有交互功能的。
tempSprite.addChild (tempBitmap);
//将临时Sprite加入数组
_pictureArray.push (tempSprite);
//加入舞台
//校对中心位置
tempSprite.x = i * sizeWidth + centerWidth;
tempSprite.y = j * sizeHeight + centerHeight;
addChild (tempSprite);
复制代码[b]步骤21:第三次测试[/b]
请继续测一次,你将看到图像被正确的饿放置到了舞台上。甚至看不出它已经被分割成了1250份。
在嵌套循环的结束括号后面,我们加入如下代码:
stage.addEventListener (MouseEvent.CLICK, blowWind);
复制代码我们为舞台增加一个鼠标点击(MouseEvent.CLICK)事件监听器。这将触发我们将在下一步创建的blowWind()函数,
你的WindEffect类看起来应该像这样:
package
{
import com.greensock.easing.Strong;
import com.greensock.TweenLite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.net.URLRequest;
public class WindEffect extends Sprite
{
private var _pictureArray:Array;
public function WindEffect ($url:String)
{
loadPicture ($url);
}
private function loadPicture ($url:String):void
{
var loader:Loader = new Loader;
loader.contentLoaderInfo.addEventListener (Event.COMPLETE, onLoadComplete);
loader.load (new URLRequest ($url));
}
private function onLoadComplete (e:Event):void
{
createEffect (e.target.content);
}
private function createEffect ($bitmap:Bitmap):void
{
var centerWidth:Number = (stage.stageWidth - $bitmap.width) * .5;
var centerHeight:Number = (stage.stageHeight - $bitmap.height) * .5;
var numberOfColumns:uint = 50;
var numberOfRows:uint = 25;
var sizeWidth:uint = $bitmap.width / numberOfColumns;
var sizeHeight:uint = $bitmap.height / numberOfRows;
var numberOfBoxes:uint = numberOfColumns * numberOfRows;
_pictureArray = [];
for (var i:uint = 0; i BitmapData = new BitmapData (sizeWidth, sizeHeight);
var sourceRect:Rectangle = new Rectangle (i * sizeWidth, j * sizeHeight, sizeWidth, sizeHeight);
tempBitmapData.copyPixels ($bitmap.bitmapData, sourceRect, new Point);
var tempBitmap:Bitmap = new Bitmap (tempBitmapData);
var tempSprite:Sprite = new Sprite;
tempSprite.addChild (tempBitmap);
_pictureArray.push (tempSprite);
tempSprite.x = i * sizeWidth + centerWidth;
tempSprite.y = j * sizeHeight + centerHeight;
addChild (tempSprite);
}
}
stage.addEventListener (MouseEvent.CLICK, blowWind);
}
}
}
复制代码[b]步骤22:创建随风飘散的效果[/b]
首先移除鼠标点击(MouseEvent.CLICK)事件监听器,因为我们只需要它触发一次。接着在createEffect()方法后添加如下代码:
private function blowWind (e:MouseEvent):void
{
stage.removeEventListener (MouseEvent.CLICK, blowWind);
}
复制代码我们需要通过_pictureArray数组来控制所有加入数组中的的Sprite产生动画。
TweenLite很胜任这项工作,可以用它来实现随风飘散的效果。
它的参数是:1目标对象(MovieClip或者其它对象),2时间长度(单位秒),3对象,通过属性值,来存贮各种属性参数用于缓动.(如果你使用 TweenLite.from() 方法,这里的参数表示缓动的初始值)以及其他你需要应用补间的属性。
举个例子:TweenLite.to (target, duration, {x:100, y:100, rotation:30, ease:Strong.easeIn, onComplete:trace, onCompleteParams:['hello']}).
上面例子的最后两个参数用来响应当补间结束时的函数。OnComplete参数是补间结束时响应的函数名trace,onCompleteParams则传递一个字符串“hello”到trace函数中去。
在移除事件监听器后加入如下代码:
for (var i:uint = 0; i Sprite的x坐标移到舞台外部
[b]y:_pictureArray[ i ].y+ getRandomRange (-100,100,false)。[/b]这个意思是将目标对象的y坐标增加一个-100至100的随机值,扩展动画效果。
[b]rotation:getRandomRange (-90,90),[/b]将目标对象随机旋转,范围在-90度至90度之间。
[b]ease:Strong.easeIn[/b],这是缓动类型,慢慢开始,突然加快。
[b]onComplete:removeSprite[/b]当补间动画结束时调用removeSprite方法将Sprite移除
[b]onCompleteParams[/b]:这是给removeSprite传递要被移除的Sprite。
[b]步骤23:removeSprite()方法[/b]
这是TweenLite在补间动画结束的时候调用的方法。用与移除运动结束的Sprite。
将下面的代码添加到blowWind()方法后面
private function removeSprite ($sprite:Sprite):void
{
removeChild ($sprite);
}
复制代码[b]步骤24:getRandomInRange()方法[/b]
我想你肯定熟悉这个(如果不熟悉可以看这篇教程http://active.tutsplus.com/tutor ... ed-range-using-as3/)我的版本有一个选项能控制返回整数(int,uint)还是浮点(fractions)。
添加如下代码。如果你使用FlashDevelop,你可以将它保存为一个自定义代码片段,这样就能很容的在其它类或者项目中使用。我已经将它定义为静态方法。
public static function getRandomInRange ($min:Number, $max:Number, $rounded:Boolean = true):Number
{
if ($rounded) return Math.round (Math.random () * ($max - $min) + $min);
else return Math.random () * ($max - $min) + $min;
}
复制代码好了,运行一下该影片。如果有什么错误,对照源文件中的WindEffect类检查一下。
[b]总结[/b]
创建酷效果的关键是学习和掌握图像处理以及补间动画类,例如TweenLite。
感谢阅读!
2010年07月29日
在这篇教程中,我们会自定义一个类,它能将一张图片分解成1000多个碎片,并模拟被风吹散的效果。我使用了FlashDevelop来创建一个AS3项目。
[b]最终效果预览[/b]
点击Flash舞台看风吹效果
[b]了解FlashDevelop[/b]
FlashDevelop是一个Flash和Flex的代码编辑器。当你在使用Flash的时候你也可以用它来编辑类文件,或者直接用FlashDevelop来创建as3工程,而不需要使用Flash―这正是本教程要做的。
因此,先下载FlashDevelop并安装它。不幸的是,FlashDevelop只能在Windows下运行。苹果系统可以选择FDT和FlexBuilder(ok,现在已经叫Flash Builder)但也不是免费的。你可以使用Flash,我也将解释使用Flash怎么做到。
[b]步骤1:创建一个项目[/b]
打开FlashDevelop并点击Porject>New Project
[b]步骤2:建立[/b]
选择ActionScript3>AS3 Project。输入项目名称“WindEffect”,选择一个文件夹保存项目。保证“Create Directory For Project”检查框被选择,然后单击OK按钮。
如果你打算使用Flash CS3/CS4。那么就创建一个新的Flash文件,并且设置舞台的宽高为550x250px。设置背景色为白色。保存为“windEffect.fla”,然后随便你喜欢保存在什么地方。
[b]步骤3:找张图片[/b]
如果是FlashDevelop,打开项目目录,复制或者拖一张windEffect.jpg图片到\bin\folder目录。
如果是使用Flash ide,复制或者拖一张windEffect.jpg图片到windEffect.fla文件同目录下。
[b]步骤4:安装TweenLite(一个补间动画类库)[/b]
我们要使用TweenLite来做补间动画。你可以在这里(http://www.greensock.com/tweenlite/)下载最新版。我已经把它包含在源文件中了。
对于FlashDevelop来说,将greensock.swc复制到项目的\lib\folder\目录下。然后单击View>
roject Manager。
[b]步骤5:外链库[/b]
不过在FlashDevelop,单击lib文件夹旁边的“+”号展开它。然后右键单击greensock.swc并选择“Add To Library”。
在Flash中,复制或者拖拽“com”目录到windEffect.fla同目录下。
[b]步骤6:文档类[/b]
在FlashDevelop中,再次打开project manager(参考步骤4),展开src文件夹,并且双击Main.as。在完成导入以及类定义之后,使用元数标签设置舞台属性
[SWF (width = 550, height = 250, frameRate = 30, backgroundColor = 0)]
在init()方法中,注释“entry point”之后,添加如下代码:
stage.scaleMode = StageScaleMode.NO_SCALE; //不伸展舞台
var effect:WindEffect = new WindEffect('windEffect.jpg'); //我们马上要创建WindEffect类
addChild (effect);
复制代码这就是Main文档类
在Flash,在fla文件同目录下新建的Main.as文件。加入如下代码:
package
{
import flash.display.Sprite;
import flash.display.StageScaleMode;
import flash.events.Event;
public class Main extends Sprite
{
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
stage.scaleMode = StageScaleMode.NO_SCALE; //don't stretch the stage
var effect:WindEffect = new WindEffect ('windEffect.jpg'); //we will create the WindEffect class soon
addChild (effect);
}
}
}
复制代码打开Flash,给文档类赋值“Main”
(如果对文档类不太明白可以看这篇教程http://active.tutsplus.com/tutor ... ent-class-in-flash/)
如果你现在试着去运行它。你将会得到一个错误,因为我们还没有创建WindEffect类。
[b]步骤7:创建WindEffect类[/b]
在FlashDevelop中,单击View>
roject Manager,右键单击src文件夹,并选择Add>New Class
[b]步骤8:设置类[/b]
命名类名为 WindEffect,单击browse按钮选择flash.displaySprite为基类。单击OK完成。
[b]步骤9:导入其他类[/b]
在package大括号内导入所有必须的类,在Import flash.display.Sprite之下,类定义之前。并保存
import com.greensock.easing.Strong;
import com.greensock.TweenLite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.net.URLRequest;
复制代码在Flash中,新建一个ActionScript文件,命名为“WindEffect.as”,并保存在项目根目录下。它和fla文件,com目录与Main.as文件在同一个目录中。
添加如下代码:
package
{
import com.greensock.easing.Strong;
import com.greensock.TweenLite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.net.URLRequest;
public class WindEffect extends Sprite
{
public function WindEffect ()
{
}
}
}
复制代码[b]步骤10:加入变量[/b]
加入一个私有的变量,名为“_pictureArray”。这是这个类中唯一的变量。它的主要作用是保存所有小sprite,每个笑sprite都记录着图像的某一块图形数据。
在括号内添加如下代码:
public class WindEffect extends Sprite
{
//这用来保存所有运动的碎片.
private var _pictureArray:Array;
}
复制代码[b]步骤11:添加构造[/b]
在_pictureArray声明下面添加:
public class WindEffect extends Sprite
{
//这用来保存所有运动的碎片.
private var _pictureArray:Array;
public function WindEffect ($url:String)
{
//我们在构造函数中调用载入图片方法。
loadPicture ($url);
}
}
复制代码[b]步骤12:操纵图片[/b]
在构造函数中调用loadPicture()方法。我们实例化一个Loader来加载windEffect.jpg。我们还添加一个COMPLKETE事件来侦听加载是否完成。
在WindEffect()之后添加如下代码(注意,参数$url是从Main.as中传过来的图片的路径)
private function loadPicture ($url:String):void
{
//创建Loader并侦听载入情况。
//加载图片
var loader:Loader = new Loader;
loader.contentLoaderInfo.addEventListener (Event.COMPLETE, onLoadComplete); //when it's loaded, call the onLoadComplete () function
loader.load (new URLRequest ($url));
}
复制代码[b]步骤13:载入[/b]
当图片完全导入的时候,这个方法就被调用了。在loadPicture()下面添加如下代码,并保存。
private function onLoadComplete (e:Event):void
{
//for testing
addChild (e.target.content);
}
复制代码[b]步骤14:测试[/b]
接着按CTRL+Enter组合键进行测试,图片就会出现在舞台的左上角。
现在,我们已经知道它能正常的加载,那么就删除addChild方法,并将它替换为如下代码:
createEffect (e.target.content);
你的WindEffect类看起来应该是这样的:
package
{
import com.greensock.easing.Strong;
import com.greensock.TweenLite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.net.URLRequest;
[SWF (width = 550, height = 250, frameRate = 30, backgroundColor = 0)]
public class WindEffect extends Sprite
{
private var _pictureArray:Array;
public function WindEffect ($url:String)
{
loadPicture ($url);
}
private function loadPicture ($url:String):void
{
var loader:Loader = new Loader;
loader.contentLoaderInfo.addEventListener (Event.COMPLETE, onLoadComplete);
loader.load (new URLRequest ($url));
}
private function onLoadComplete (e:Event):void
{
createEffect (e.target.content);
}
}
}
复制代码[b]步骤15:设置变量[/b]
createEffect()方法将传递一个图像参数,它本质上是一个位图(Bitmap),之后它会被分解为1250块。
首先,我们计算出让图像处在舞台正中央的x,y坐标。我们将坐标保存至局部变量centerWidth和centerHeight中
因为图片的尺寸为300x100,所以我决定分割的比例是:横50,竖25。这样划分会有一个很好的性能,我们将它们保存至局部变量“numberOfColumns”与“numberOfRows”中。这样图片就被分割成1250块均等的矩形,然后我们把矩形的宽高保存至“sizeWidth”与“sizeHeight”中。“numberOfBoxes”变量用来保存矩形的数目。
接着我们实例化_pictureArray数组,这样我们就能将那些矩形存进去。接下来的这些代码放在onLoadComplete()方法后面。
private function createEffect ($bitmap:Bitmap):void
{
//居中x坐标
var centerWidth:Number = (stage.stageWidth - $bitmap.width) * .5;
//居中y坐标
var centerHeight:Number = (stage.stageHeight - $bitmap.height) * .5;
var numberOfColumns:uint = 50;
var numberOfRows:uint = 25;
var sizeWidth:uint = $bitmap.width / numberOfColumns;
var sizeHeight:uint = $bitmap.height / numberOfRows;
var numberOfBoxes:uint = numberOfColumns * numberOfRows;
_pictureArray = [];
}
复制代码[b]步骤16:嵌套循环[/b]
在实例化_ pictureArray后,我们将使用嵌套循环来实现一个二维数组。第一层循环处理x坐标遍历所有列,第二层循环将处理y坐标,遍历所有行。
在实例化_pictureArray后,将下面的代码放入createEffect()方法内,保存。
for (var i:uint = 0; i bitmapdata
var tempBitmapData:BitmapData = new BitmapData (sizeWidth, sizeHeight);
//1 个临时的矩形 (x,y,width,height)
//我们通过i*sizeWidth作为x坐标的参数,j*sizeHeight作为y坐标的参数。
//还有sizeWidth以及sizeHeight作为宽与高的参数。
var sourceRect:Rectangle = new Rectangle (i * sizeWidth, j * sizeHeight, sizeWidth, sizeHeight);
trace (sourceRect);//测试
复制代码[b]步骤19:进一步测试[/b]
测试影片。可以观察到每次迭代创建的矩形情况,以便调整。
正如你所看到的,在第一个例子显示x=0,y=0下一个是x=0,y=4。这就是我们从图像上取下来的小图片的区域。接下来移除test函数。
[b]步骤20:BitmapData.copyPixels()[/b]
然后,我们使用BitmapData.copyPixels ()方法依据soureceRect来复制图像上的图形数据。这个方法的参数是需要复制的目标位图图像,需要复制的矩形区域以及目标点(它表示将在其中放置新像素的矩形区域的左上角)。
tempBitmapData.copyPixels ($bitmap.bitmapData, sourceRect, new Point);
复制代码然后我们创建一个临时位图来放置我们刚才复制的BitmapData,接着再创建一个临时Sprite来放置临时位图。
再然后我们把所有的Sprite都放入到_pictureArray中。在这之后,我们将Sprite以原有的坐标放置到舞台上,还原原始图像。
最后根据centerWidth和centerHeight调整一下位置让整副图能在舞台上居中。
添加下面的代码,并再次保存。
//创建一个临时位图来放置我们复制的BitmapData数据
var tempBitmap:Bitmap = new Bitmap (tempBitmapData);
//创建一个临时的Sprite来放置上面的bitmap,以便有交互功能。
var tempSprite:Sprite = new Sprite;
//将bitmap放入Sprite的目的是产生交互,因为bitmap是没有交互功能的。
tempSprite.addChild (tempBitmap);
//将临时Sprite加入数组
_pictureArray.push (tempSprite);
//加入舞台
//校对中心位置
tempSprite.x = i * sizeWidth + centerWidth;
tempSprite.y = j * sizeHeight + centerHeight;
addChild (tempSprite);
复制代码[b]步骤21:第三次测试[/b]
请继续测一次,你将看到图像被正确的饿放置到了舞台上。甚至看不出它已经被分割成了1250份。
在嵌套循环的结束括号后面,我们加入如下代码:
stage.addEventListener (MouseEvent.CLICK, blowWind);
复制代码我们为舞台增加一个鼠标点击(MouseEvent.CLICK)事件监听器。这将触发我们将在下一步创建的blowWind()函数,
你的WindEffect类看起来应该像这样:
package
{
import com.greensock.easing.Strong;
import com.greensock.TweenLite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.net.URLRequest;
public class WindEffect extends Sprite
{
private var _pictureArray:Array;
public function WindEffect ($url:String)
{
loadPicture ($url);
}
private function loadPicture ($url:String):void
{
var loader:Loader = new Loader;
loader.contentLoaderInfo.addEventListener (Event.COMPLETE, onLoadComplete);
loader.load (new URLRequest ($url));
}
private function onLoadComplete (e:Event):void
{
createEffect (e.target.content);
}
private function createEffect ($bitmap:Bitmap):void
{
var centerWidth:Number = (stage.stageWidth - $bitmap.width) * .5;
var centerHeight:Number = (stage.stageHeight - $bitmap.height) * .5;
var numberOfColumns:uint = 50;
var numberOfRows:uint = 25;
var sizeWidth:uint = $bitmap.width / numberOfColumns;
var sizeHeight:uint = $bitmap.height / numberOfRows;
var numberOfBoxes:uint = numberOfColumns * numberOfRows;
_pictureArray = [];
for (var i:uint = 0; i BitmapData = new BitmapData (sizeWidth, sizeHeight);
var sourceRect:Rectangle = new Rectangle (i * sizeWidth, j * sizeHeight, sizeWidth, sizeHeight);
tempBitmapData.copyPixels ($bitmap.bitmapData, sourceRect, new Point);
var tempBitmap:Bitmap = new Bitmap (tempBitmapData);
var tempSprite:Sprite = new Sprite;
tempSprite.addChild (tempBitmap);
_pictureArray.push (tempSprite);
tempSprite.x = i * sizeWidth + centerWidth;
tempSprite.y = j * sizeHeight + centerHeight;
addChild (tempSprite);
}
}
stage.addEventListener (MouseEvent.CLICK, blowWind);
}
}
}
复制代码[b]步骤22:创建随风飘散的效果[/b]
首先移除鼠标点击(MouseEvent.CLICK)事件监听器,因为我们只需要它触发一次。接着在createEffect()方法后添加如下代码:
private function blowWind (e:MouseEvent):void
{
stage.removeEventListener (MouseEvent.CLICK, blowWind);
}
复制代码我们需要通过_pictureArray数组来控制所有加入数组中的的Sprite产生动画。
TweenLite很胜任这项工作,可以用它来实现随风飘散的效果。
它的参数是:1目标对象(MovieClip或者其它对象),2时间长度(单位秒),3对象,通过属性值,来存贮各种属性参数用于缓动.(如果你使用 TweenLite.from() 方法,这里的参数表示缓动的初始值)以及其他你需要应用补间的属性。
举个例子:TweenLite.to (target, duration, {x:100, y:100, rotation:30, ease:Strong.easeIn, onComplete:trace, onCompleteParams:['hello']}).
上面例子的最后两个参数用来响应当补间结束时的函数。OnComplete参数是补间结束时响应的函数名trace,onCompleteParams则传递一个字符串“hello”到trace函数中去。
在移除事件监听器后加入如下代码:
for (var i:uint = 0; i Sprite的x坐标移到舞台外部
[b]y:_pictureArray[ i ].y+ getRandomRange (-100,100,false)。[/b]这个意思是将目标对象的y坐标增加一个-100至100的随机值,扩展动画效果。
[b]rotation:getRandomRange (-90,90),[/b]将目标对象随机旋转,范围在-90度至90度之间。
[b]ease:Strong.easeIn[/b],这是缓动类型,慢慢开始,突然加快。
[b]onComplete:removeSprite[/b]当补间动画结束时调用removeSprite方法将Sprite移除
[b]onCompleteParams[/b]:这是给removeSprite传递要被移除的Sprite。
[b]步骤23:removeSprite()方法[/b]
这是TweenLite在补间动画结束的时候调用的方法。用与移除运动结束的Sprite。
将下面的代码添加到blowWind()方法后面
private function removeSprite ($sprite:Sprite):void
{
removeChild ($sprite);
}
复制代码[b]步骤24:getRandomInRange()方法[/b]
我想你肯定熟悉这个(如果不熟悉可以看这篇教程http://active.tutsplus.com/tutor ... ed-range-using-as3/)我的版本有一个选项能控制返回整数(int,uint)还是浮点(fractions)。
添加如下代码。如果你使用FlashDevelop,你可以将它保存为一个自定义代码片段,这样就能很容的在其它类或者项目中使用。我已经将它定义为静态方法。
public static function getRandomInRange ($min:Number, $max:Number, $rounded:Boolean = true):Number
{
if ($rounded) return Math.round (Math.random () * ($max - $min) + $min);
else return Math.random () * ($max - $min) + $min;
}
复制代码好了,运行一下该影片。如果有什么错误,对照源文件中的WindEffect类检查一下。
[b]总结[/b]
创建酷效果的关键是学习和掌握图像处理以及补间动画类,例如TweenLite。
感谢阅读!