以前曾写过一个书架效果的分析( http://blog.5d.cn/user12/dzxz/200612/336721.html ),现在改成AS3版本,算AS3的练习作业吧。
最终效果:
之前的文件是反编译而来的,分析之后将相关注释写在了fla文件中,熟悉AS2 的朋友们可以先下载看看。
转换成As3并不像我一开始想的那么简单,因为要从类的角度重新整理分析出最终效果里所包含的有用元素。
完成之后将自己的分析过程总结如下:
1、寻找对象。
在一个书架效果中,页面是基本单位,页面之间只有运动上的相关性,内容上无相关性,于是可以将页面做为一个基础类来进行设计。
2、寻找属性。
在过去的编程中,少不了用到全局属性、局部属性,在以类为代码单元的设计中,类中的全局属性可以用静态变量来替代,局部属性就是普通的类自定义变量。对照原来的代码,可以找到的全局属性包括:
menu --- 手动与自动翻页的标志
overAt ---- 当前显示的页面
pageTimer ---- 当前页面的计数器,统计当前页面已经显示了多长时间。
局部属性包括:
pageID --- 当前页面的ID编号,用来确定显示的顺序及运动的方向,可以在实例化时进行动态的指定。
3、寻找程序逻辑。
所有的页面根据 overAt 的值进行相应的运动,当pageID 小于 overAt 时,表示该页面位于需要显示页面的左方,它还需要继续向左移动。当pageID 大于 overAt 时,表示该页面应该向右移动。对于overAt 的监视是在 EnterFrame 事件中进行的。
鼠标滑入滑出时,只需要修正一下 menu 的值,以及页面计时器的数值,从而进入自动翻页的状态。
4、寻找模式。
在这个例子中不涉及数据加载(有兴趣可以添加上),不存在复杂的互动,所以模式似乎也用需要去考虑了。只是在类链接时有一点问题,就是AS3中不允许一个类文件链接多个元件中去,因此,我采用的办法是新造5个类来继承定义好的类,用这5个类去分别链接5个页面元件,在子类中刚好初始化一下相关属性,就是指定页面的ID,这样整个“系统”就可以正常运转了。
类文件如下:
package dzxz.bookcase
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
/**
* ...
* @ 独自行走
*/
public class BookCase extends MovieClip
{
static var menu:Boolean = false; // 手动\自动切换
static var overAt:Number = 1; // 当前显示的页面
static var pageTimer = 100; // 页面计时器
static var bookWidth:Number = 30; // 书本的厚度
static var pageWidth:Number = 370; // 页面的宽度
public var leftPsn:Number; // 当前页面的左界位置
public var rightPsn:Number; // 当前页面的右边界位置
public var pageID:Number; // 页面的 ID 编号,用于页面判定及 位置换算
private var prevPsn:Number; // 前一次的位置
public function elasticMove( dest:Number )
{
var t:Number = x;
var a:Number = 1.765000E+000;
var b:Number = -7.800000E-001;
x = a * ( x - dest) + b * (prevPsn - dest ) + dest;
prevPsn = t;
}
public function BookCase()
{
prevPsn = x;
}
public function initPage( num:Number)
{
pageID = num; //指定当前的页号
leftPsn = (num - 1) * bookWidth; // 换算出运动的起始位置
rightPsn = leftPsn + pageWidth; // 换算出运动的结束位置
addEventListener(MouseEvent.ROLL_OVER, onRollOver);
addEventListener(MouseEvent.ROLL_OUT, onRollOut);
addEventListener(MouseEvent.CLICK, onClick );
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
function onEnterFrame(evt:Event )
{
if ( pageID > overAt)
{
//move to right
elasticMove( rightPsn );
} else
{
//move to left
elasticMove( leftPsn );
}
if ( pageTimer % 150 == 0 ) {
//自动翻页效果,当到达一定的时间间隔时就自动翻页。
if ( overAt == 5 ) {
//如果已经翻到了最后一页,下次就翻回第一页。
overAt = 1;
pageTimer = 1;
} else {
//自动向后翻页。
overAt++;
}// end else if
trace( pageID, overAt);
}
if (menu == false && pageID == overAt ) {
//设置自动翻页的时间累积参数。
//第二个判断条件用来限定仅对当前页面进行时间累计,其它页面的 enterFrame 事件中不进行累计.
++pageTimer;
}
}
function onRollOver(evt:MouseEvent )
{
overAt = pageID; //指向当前页面
pageTimer = 1;
menu = true;
//trace( pageID, overAt );
}
function onRollOut(evt:MouseEvent )
{
menu = false;
pageTimer = 100;
}
function onClick(evt:MouseEvent )
{
// 点击之后打开相关网页
// getURL();
}
}
}
字类定义示例
package dzxz.bookcase
{
import dzxz.bookcase.BookCase;
/**
* ...
* @ 独自行走
*/
public class Page1 extends BookCase
{
public function Page1()
{
initPage(1)
rightPsn = leftPsn ;
}
}
}
原来的效果中,当页面移动到左边或是右边以后,会显示出一个书本的样子,这一步需要在元件自行设计好,做一段过渡动画,在BookCase中,加入一些代码,当pageID 不等于 overAt 时,元件向前播放,直到第一帧,当pageID 等于 overAt 时,元件向后播放,直到最后一帧。就是这么个逻辑,期待你能够自己完成这一步,我就不多写了。
源文件下载 压缩包下载