AS3.0打造随风吹散效果
2010年07月29日
在这篇教程中,我们会自定义一个类,它能将一张图片分解成1000多个碎片,并模拟被风吹散的效果。我使用了FlashDevelop来创建一个AS3项目。
最终效果预览
点击Flash舞台看风吹效果
了解FlashDevelop
FlashDevelop是一个Flash和Flex的代码编辑器。当你在使用Flash的时候你也可以用它来编辑类文件,或者直接用FlashDevelop来创建as3工程,而不需要使用Flash―这正是本教程要做的。
因此,先下载FlashDevelop并安装它。不幸的是,FlashDevelop只能在Windows下运行。苹果系统可以选择FDT和FlexBuilder(ok,现在已经叫Flash Builder)但也不是免费的。你可以使用Flash,我也将解释使用Flash怎么做到。
步骤1:创建一个项目
打开FlashDevelop并点击Porject>New Project
步骤2:建立
选择ActionScript3>AS3 Project。输入项目名称“WindEffect”,选择一个文件夹保存项目。保证“Create Directory For Project”检查框被选择,然后单击OK按钮。
如果你打算使用Flash CS3/CS4。那么就创建一个新的Flash文件,并且设置舞台的宽高为550x250px。设置背景色为白色。保存为“windEffect.fla”,然后随便你喜欢保存在什么地方。
步骤3:找张图片
如果是FlashDevelop,打开项目目录,复制或者拖一张windEffect.jpg图片到\bin\folder目录。
如果是使用Flash ide,复制或者拖一张windEffect.jpg图片到windEffect.fla文件同目录下。
步骤4:安装TweenLite(一个补间动画类库)
我们要使用TweenLite来做补间动画。你可以在这里(http://www.greensock.com/tweenlite/)下载最新版。我已经把它包含在源文件中了。
对于FlashDevelop来说,将greensock.swc复制到项目的\lib\folder\目录下。然后单击View>
roject Manager。
步骤5:外链库
不过在FlashDevelop,单击lib文件夹旁边的“+”号展开它。然后右键单击greensock.swc并选择“Add To Library”。
在Flash中,复制或者拖拽“com”目录到windEffect.fla同目录下。
步骤6:文档类
在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类。
步骤7:创建WindEffect类
在FlashDevelop中,单击View>
roject Manager,右键单击src文件夹,并选择Add>New Class
步骤8:设置类
命名类名为 WindEffect,单击browse按钮选择flash.displaySprite为基类。单击OK完成。
步骤9:导入其他类
在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 ()
{
}
}
}
复制代码步骤10:加入变量
加入一个私有的变量,名为“_pictureArray”。这是这个类中唯一的变量。它的主要作用是保存所有小sprite,每个笑sprite都记录着图像的某一块图形数据。
在括号内添加如下代码:
public class WindEffect extends Sprite
{
//这用来保存所有运动的碎片.
private var _pictureArray:Array;
}
复制代码步骤11:添加构造
在_pictureArray声明下面添加:
public class WindEffect extends Sprite
{
//这用来保存所有运动的碎片.
private var _pictureArray:Array;
public function WindEffect ($url:String)
{
//我们在构造函数中调用载入图片方法。
loadPicture ($url);
}
}
复制代码步骤12:操纵图片
在构造函数中调用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));
}
复制代码步骤13:载入
当图片完全导入的时候,这个方法就被调用了。在loadPicture()下面添加如下代码,并保存。
private function onLoadComplete (e:Event):void
{
//for testing
addChild (e.target.content);
}
复制代码步骤14:测试
接着按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);
}
}
}
复制代码步骤15:设置变量
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 = [];
}
复制代码步骤16:嵌套循环
在实例化_ 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);//测试
复制代码步骤19:进一步测试
测试影片。可以观察到每次迭代创建的矩形情况,以便调整。
正如你所看到的,在第一个例子显示x=0,y=0下一个是x=0,y=4。这就是我们从图像上取下来的小图片的区域。接下来移除test函数。
步骤20:BitmapData.copyPixels()
然后,我们使用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);
复制代码步骤21:第三次测试
请继续测一次,你将看到图像被正确的饿放置到了舞台上。甚至看不出它已经被分割成了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);
}
}
}
复制代码步骤22:创建随风飘散的效果
首先移除鼠标点击(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坐标移到舞台外部
y:_pictureArray[ i ].y+ getRandomRange (-100,100,false)。这个意思是将目标对象的y坐标增加一个-100至100的随机值,扩展动画效果。
rotation:getRandomRange (-90,90),将目标对象随机旋转,范围在-90度至90度之间。
ease:Strong.easeIn,这是缓动类型,慢慢开始,突然加快。
onComplete:removeSprite当补间动画结束时调用removeSprite方法将Sprite移除
onCompleteParams:这是给removeSprite传递要被移除的Sprite。
步骤23:removeSprite()方法
这是TweenLite在补间动画结束的时候调用的方法。用与移除运动结束的Sprite。
将下面的代码添加到blowWind()方法后面
private function removeSprite ($sprite:Sprite):void
{
removeChild ($sprite);
}
复制代码步骤24:getRandomInRange()方法
我想你肯定熟悉这个(如果不熟悉可以看这篇教程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类检查一下。
总结
创建酷效果的关键是学习和掌握图像处理以及补间动画类,例如TweenLite。
感谢阅读!
发表评论
-
Windows Phone开发(三)-- 导航原理分析
2012-01-20 01:56 660Windows Phone开发(三)-- 导 ... -
在 Android 平台上应用 Berkeley DB 11gR2 SQL(drop-in模式)(转http://www.cnmsdn.com/html/201004/1270362092ID3134.html)
2012-01-20 01:56 636在 Android 平台上应用 Ber ... -
Android: 你必须掌握的Android命令
2012-01-20 01:56 1025Android: 你必须掌握的Android命令 2011年 ... -
Windows Installer的简单应用
2012-01-20 01:56 678Windows Installer的简单应 ... -
Visual Studio 2010瘦身精简方法
2012-01-20 01:55 927Visual Studio 2010瘦身精简 ... -
一段话一个故事 【微小说】
2012-01-19 09:42 640一段话一个故事 【微小说】 2011年12月17日 生日 ... -
微小说 ≈
2012-01-19 09:42 700微小说 ≈ 2011年1 ... -
校园生活中有哪些搞笑又雷人的小事?
2012-01-19 09:42 589校园生活中有哪些搞笑又雷人的小事? 2012年01月02日 ... -
为期三月
2012-01-19 09:42 690为期三月 2012年01月05日 用一句话开头,一句 ... -
Qt 学习笔记 --Qt SDK 的下载安装与配置
2012-01-17 02:17 656Qt 学习笔记 --Qt SDK 的下 ... -
Android环境搭建(jdk1.6+eclipes3.4.1+Android sdk2.3+adt0.9.7)
2012-01-17 02:17 1166Android环境搭建(jdk1.6+eclipes3.4.1 ... -
Android 3.0 SDK安装教程及系统环境搭建
2012-01-17 02:17 1194Android 3.0 SDK安装教程及系统环境搭建 201 ... -
[书籍资料] MeeGo开发教程汇总{ MeeGo SDK, qemu,Qt,appUp,python }
2012-01-17 02:17 1532[书籍资料] MeeGo开发教程汇总{ MeeGo SDK, ... -
Kinect for Windows SDK可望成微软下一个金矿
2012-01-17 02:17 561Kinect for Windows SDK可望成微软下一个金 ... -
转:开源C++库比较
2012-01-15 21:55 748转:开源C++库比较 2012年01月13日 原文: ... -
java一个学期的成果
2012-01-15 21:55 501java一个学期的成果 2012年01月13日 ... -
linux 客户端 Socket 非阻塞connect编程(转)
2012-01-15 21:54 586linux 客户端 Socket 非阻塞connect编程(转 ... -
Socket编程指南及程序示例(转载)SVN
2012-01-15 21:54 773Socket编程指南及程序示例(转载)SVN 2009年12 ...
相关推荐
flash as3.0图片过渡效果 过渡效果随机变换 图片过渡效果 as3.0外部文档 as3.0图片过渡效果 as3.0图片过渡效果 TweenManager
as3.0+翻书效果as3.0+翻书效果as3.0+翻书效果
AS3.0 ZIP压缩解压源代码 AS3.0 ZIP压缩解压源代码
用as3.0代码实现的翻转效果(翻牌效果),非常实用,内附源代码
时钟源代码 Flash as3.0 想用as3.0创建一个时钟么,这个源代码可以帮助你轻易解决这个问题
as3.0 滑动技巧 模仿iphone滑动,有缓冲效果。横竖版效果都有
使用ActionScript 3.0代码编写的简单例子,AS3.0+Flash,适用于初学者,通过学习实例,能更好的掌握as
flash as3.0实现简单计时器功能 as3.0类编程实现计时器功能 计时器源代码
as3.0 播放器 源码 as3.0 播放器 源码 as3.0 播放器 源码
AS3.0缓动特效AS3.0缓动特效AS3.0缓动特效AS3.0缓动特效AS3.0缓动特效AS3.0缓动特效AS3.0缓动特效AS3.0缓动特效AS3.0缓动特效
flash as3.0舞台产生电流的效果
as3.0菜单类 flash as3.0 oop
课堂上做的作业 设计首页点击进入抽奖环节,分为1、2、3等奖 获奖人数可设定 简单容易修改 图片换一下即可改为年会抽奖、班级抽奖等抽奖活动
as3.0 翻书效果 开源
本手册为在 ActionScript™ 3.0 中开发应用程序提供了基础。为了充分理解所介绍的理念和 技巧,您应已熟悉了一般的编程概念,如数据类型、变量、循环和函数。您还应了解面向对 象编程的基本概念,如类和继承。如果...
as3.0 开发小游戏,对初学as3.0有帮助
as3.0图片切换随机效果(10种)
as3.0精髓 教程 as3.0学习教程
ActionScript3.0 cookbook中文版和AS3.0的API
模仿可口可乐网站的加载进度条,flash+as3.0。