Flash/Flex学习笔记(57):实用技巧
布朗运动:
01 |
var numDots: uint = 50 ; |
02 |
var friction: Number = 0.9 ; |
03 |
var dots: Array ; |
04 |
var life: uint = 0 ; |
05 |
|
06 |
functioninit(){ |
07 |
graphics.lineStyle( 0 , 0xffffff ,. 5 ); |
08 |
dots=newArray(); |
09 |
for ( var i: uint = 0 ;i<numDots;i++){ |
10 |
var dot:Ball=newBall( 2 , 0x00ff00 ); |
11 |
dot.x=Math.random()*stage.stageWidth; |
12 |
dot.y=Math.random()*stage.stageHeight; |
13 |
dot.vx= 0 ; |
14 |
dot.vy= 0 ; |
15 |
dots.push(dot); |
16 |
addChild(dot); |
17 |
checkBound(dot); |
18 |
} |
19 |
addEventListener(Event.ENTER_FRAME,enterFrameHandler); |
20 |
} |
21 |
|
22 |
//检查边界 |
23 |
functioncheckBound(b:Ball){ |
24 |
if (b.x<b.width/ 2 ){ |
25 |
b.x=b.width/ 2 ; |
26 |
} |
27 |
elseif(b.x>stage.stageWidth-b.width/ 2 ){ |
28 |
b.x=stage.stageWidth-b.width/ 2 ; |
29 |
} |
30 |
if (b.y<b.height/ 2 ){ |
31 |
b.y=b.height/ 2 ; |
32 |
} |
33 |
elseif(b.y>stage.stageHeight-b.height/ 2 ){ |
34 |
b.y=stage.stageHeight-b.height/ 2 ; |
35 |
} |
36 |
} |
37 |
|
38 |
functionenterFrameHandler(e:Event): void { |
39 |
//trace(life); |
40 |
if (life>= 200 ){ |
41 |
graphics.clear(); |
42 |
graphics.lineStyle( 0 , 0xffffff ,. 5 ); |
43 |
life= 0 ; |
44 |
} |
45 |
for ( var i: uint = 0 ;i<numDots;i++){ |
46 |
var dot:Ball=dots[i]; |
47 |
graphics.moveTo(dot.x,dot.y); |
48 |
dot.vx+=Math.random()- 0.5 ; |
49 |
dot.vy+=Math.random()- 0.5 ; |
50 |
dot.x+=dot.vx; |
51 |
dot.y+=dot.vy; |
52 |
dot.vx*=friction; |
53 |
dot.vy*=friction; |
54 |
checkBound(dot); |
55 |
graphics.lineTo(dot.x,dot.y); |
56 |
} |
57 |
life++; |
58 |
} |
59 |
|
60 |
init(); |
矩形分布:
01 |
var dotNumber: uint = 500 ; |
02 |
var dots: Array ; |
03 |
var centerX: uint =stage.stageWidth/ 2 ; |
04 |
var centerY: uint =stage.stageHeight/ 2 ; |
05 |
var limitX: uint = 50 ; |
06 |
var limitY: uint = 100 ; |
07 |
|
08 |
functioninit(): void { |
09 |
dots=newArray(); |
10 |
for ( var i: uint = 0 ;i<dotNumber;i++){ |
11 |
var dot:Ball=newBall( 3 *Math.random(), 0x00ff00 ); |
12 |
dot.x=centerX+(Math.random()* 2 - 1 )*limitX; |
13 |
dot.y=centerY+(Math.random()* 2 - 1 )*limitY; |
14 |
addChild(dot); |
15 |
dots.push(dot); |
16 |
} |
17 |
addEventListener(Event.ENTER_FRAME,enterframeHandler); |
18 |
} |
19 |
|
20 |
functionenterframeHandler(e:Event): void { |
21 |
for ( var i: uint = 0 ;i<dotNumber;i++){ |
22 |
var dot:Ball=dots[i]; |
23 |
dot.x=centerX+(Math.random()* 2 - 1 )*limitX; |
24 |
dot.y=centerY+(Math.random()* 2 - 1 )*limitY; |
25 |
/*varix:Number=dot.x; |
26 |
variy:Number=dot.y; |
27 |
dot.y=ix; |
28 |
dot.x=iy*/ |
29 |
} |
30 |
} |
31 |
|
32 |
init(); |
圆形随机分布:
01 |
var dotNumber: uint = 500 ; |
02 |
var dots: Array ; |
03 |
var centerX: uint =stage.stageWidth/ 2 ; |
04 |
var centerY: uint =stage.stageHeight/ 2 ; |
05 |
var radius: uint = 75 ; |
06 |
|
07 |
functioninit(): void { |
08 |
dots=newArray(); |
09 |
for ( var i: uint = 0 ;i<dotNumber;i++){ |
10 |
var dot:Ball=newBall( 3 *Math.random(), 0x00ff00 ); |
11 |
var angle: Number = 2 *Math.random()*Math.PI; |
12 |
var r: Number =Math.random()*radius; |
13 |
dot.x=centerX+r*Math.cos(angle); |
14 |
dot.y=centerY+r*Math.sin(angle); |
15 |
addChild(dot); |
16 |
dots.push(dot); |
17 |
} |
18 |
addEventListener(Event.ENTER_FRAME,enterframeHandler); |
19 |
} |
20 |
|
21 |
functionenterframeHandler(e:Event): void { |
22 |
for ( var i: uint = 0 ;i<dotNumber;i++){ |
23 |
var dot:Ball=dots[i]; |
24 |
var angle: Number = 2 *Math.random()*Math.PI; |
25 |
var r: Number =Math.random()*radius; |
26 |
dot.x=centerX+r*Math.cos(angle); |
27 |
dot.y=centerY+r*Math.sin(angle); |
28 |
} |
29 |
} |
30 |
|
31 |
init(); |
更均匀的圆形随机分布:
01 |
var dotNumber: uint = 200 ; |
02 |
|
03 |
var centerX: uint =stage.stageWidth/ 2 ; |
04 |
var centerY: uint = 100 ; |
05 |
var radius: uint = 50 ; |
06 |
|
07 |
functioninit(): void { |
08 |
|
09 |
for ( var i: uint = 0 ;i<dotNumber;i++){ |
10 |
var dot:Ball=newBall( 2 , 0x00ff00 ); |
11 |
var angle: Number = 2 *Math.random()*Math.PI; |
12 |
var r: Number =Math.random()*radius; |
13 |
dot.x=centerX+r*Math.cos(angle); |
14 |
dot.y=centerY+r*Math.sin(angle); |
15 |
addChild(dot); |
16 |
|
17 |
} |
18 |
|
19 |
//更均匀的随机分布 |
20 |
for (i= 0 ;i<dotNumber;i++){ |
21 |
var dot1:Ball=newBall( 2 , 0x00ff00 ); |
22 |
var angle1: Number = 2 *Math.random()*Math.PI; |
23 |
var r1: Number =Math.sqrt(Math.random())*radius; //关键在这里,对Math.random()取平方根后,分布变得更均匀了 |
24 |
dot1.x=centerX+r1*Math.cos(angle1); |
25 |
dot1.y=centerY+ 200 +r1*Math.sin(angle1); |
26 |
addChild(dot1); |
27 |
|
28 |
} |
29 |
|
30 |
} |
31 |
|
32 |
|
33 |
init(); |
偏向分布:(即在指定的区域内,中心位置分布最密集,离中心越远,分布越稀疏)
01 |
var dotNumber: uint = 600 ; |
02 |
var centerX: uint =stage.stageWidth/ 2 ; |
03 |
var maxWidth: uint = 75 ; |
04 |
var balls: Array =newArray(); |
05 |
|
06 |
functioninit(): void { |
07 |
|
08 |
for ( var i: uint = 0 ;i<dotNumber;i++){ |
09 |
var dot:Ball=newBall( 2 , 0x00ff00 ); |
10 |
|
11 |
//在y轴方向上随便取二个值,然后计算平均值做为y坐标 |
12 |
var y1=stage.stageHeight*Math.random(); |
13 |
var y2=stage.stageHeight*Math.random(); |
14 |
|
15 |
var ty=(y1+y2)/ 2 ; |
16 |
|
17 |
//x轴做类似的处理 |
18 |
var x1=centerX+(Math.random()* 2 - 1 )*maxWidth; |
19 |
var x2=centerX+(Math.random()* 2 - 1 )*maxWidth; |
20 |
|
21 |
var tx=(x1+x2)/ 2 ; |
22 |
|
23 |
|
24 |
dot.x=tx; |
25 |
dot.y=ty; |
26 |
|
27 |
addChild(dot); |
28 |
|
29 |
balls.push(dot); |
30 |
} |
31 |
stage.frameRate= 1 ; |
32 |
addEventListener(Event.ENTER_FRAME,enterFrameHandler); |
33 |
} |
34 |
|
35 |
init(); |
36 |
|
37 |
|
38 |
functionenterFrameHandler(e:Event){ |
39 |
for ( var i: uint = 0 ;i<dotNumber;i++){ |
40 |
var dot:Ball=balls[i]; |
41 |
|
42 |
|
43 |
var y1=stage.stageHeight*Math.random(); |
44 |
var y2=stage.stageHeight*Math.random(); |
45 |
|
46 |
var ty=(y1+y2)/ 2 ; |
47 |
|
48 |
|
49 |
var x1=centerX+(Math.random()* 2 - 1 )*maxWidth; |
50 |
var x2=centerX+(Math.random()* 2 - 1 )*maxWidth; |
51 |
|
52 |
var tx=(x1+x2)/ 2 ; |
53 |
|
54 |
|
55 |
dot.x=tx; |
56 |
dot.y=ty; |
57 |
|
58 |
|
59 |
} |
60 |
} |
多次迭代的偏向分布(类似星云分布)
01 |
var dotNumber: uint = 100 ; |
02 |
var iterations: uint = 6 ; |
03 |
var balls: Array =newArray(); |
04 |
|
05 |
functioninit(): void { |
06 |
|
07 |
for ( var i: uint = 0 ;i<dotNumber;i++){ |
08 |
var dot:Ball=newBall( 2 , 0x00ff00 ); |
09 |
|
10 |
var xpos: Number = 0 ; |
11 |
var ypos: Number = 0 ; |
12 |
for ( var j: uint = 0 ;j<iterations;j++){ |
13 |
xpos+=stage.stageWidth*Math.random(); |
14 |
ypos+=stage.stageHeight*Math.random(); |
15 |
} |
16 |
|
17 |
dot.x=xpos/iterations; |
18 |
dot.y=ypos/iterations; |
19 |
|
20 |
addChild(dot); |
21 |
|
22 |
balls.push(dot); |
23 |
} |
24 |
|
25 |
stage.frameRate= 1 ; |
26 |
addEventListener(Event.ENTER_FRAME,enterFrameHandler); |
27 |
} |
28 |
|
29 |
init(); |
30 |
|
31 |
|
32 |
functionenterFrameHandler(e:Event){ |
33 |
for ( var i: uint = 0 ;i<dotNumber;i++){ |
34 |
var dot:Ball=balls[i]; |
35 |
|
36 |
|
37 |
var xpos: Number = 0 ; |
38 |
var ypos: Number = 0 ; |
39 |
for ( var j: uint = 0 ;j<iterations;j++){ |
40 |
xpos+=stage.stageWidth*Math.random(); |
41 |
ypos+=stage.stageHeight*Math.random(); |
42 |
} |
43 |
|
44 |
dot.x=xpos/iterations; |
45 |
dot.y=ypos/iterations; |
46 |
|
47 |
|
48 |
} |
49 |
} |
Timer类的重绘设置:
01 |
var ball:Ball=newBall(); |
02 |
var vx: Number = 5 ; |
03 |
var timer=newTimer( 20 ); |
04 |
|
05 |
stage.frameRate= 1 ; //设置flash动画的帧数为1帧/秒 |
06 |
|
07 |
ball.y=stage.stageHeight/ 2 ; |
08 |
ball.vx= 5 ; |
09 |
addChild(ball); |
10 |
|
11 |
timer.addEventListener(TimerEvent.TIMER,TimerHandler); |
12 |
|
13 |
functionTimerHandler(e:TimerEvent): void { |
14 |
ball.x+=ball.vx; |
15 |
if (ball.x>stage.stageWidth+ball.width/ 2 ){ |
16 |
ball.x=-ball.width/ 2 ; |
17 |
} |
18 |
e.updateAfterEvent(); //事件触发后,重绘整个stage(建议大家去掉这一行,再看看效果) |
19 |
} |
20 |
|
21 |
timer.start(); |
注意:timer类的计时并不象c#中那样精确,因为跟帧速有关联。
基于时间的动画:
Flash动画是基于帧的(即每进入一帧时,舞台上的对象才会重绘,并触发Enter_Frame事件),这跟Silverlight是基于时间的设计完全不同。一般情况下,这也不是什么问题,但是这样会在不同配置的机器上可能产生不一致的播放效果,比如“一个简单的小球从左运动到右”的简单动画,如果在ENTER_FRAME事件中,用ball.x+=ball.vx来处理,在老爷机上,可能swf动画只能达到每秒10帧的播放速度,而在4核的高配置机器上,能达到每秒100帧的播放速度。 问题就来了:假如ball.vx为5,则在老爷机上,小球最终每秒移动了5*10=50像素,而在高配置机器上,小球每秒移动了5*100=500像素,这与开发者期望的并不一样,下面的代码演示了如何制作基于时间的动画,最终让小球在不同配置的机器上运动速度达到一致。(注:在这一点上,不得不承认Silverlight的设计要优于Flash)
01 |
var ball:Ball=newBall(); |
02 |
var vx: Number = 5 ; |
03 |
|
04 |
stage.frameRate= 100 ; //通常在基于时间的动画中,帧数可以设置得高一点(尽管机器最终可能达不到这个帧数.) |
05 |
|
06 |
ball.y=stage.stageHeight/ 2 ; |
07 |
ball.vx= 10 ; |
08 |
addChild(ball); |
09 |
|
10 |
var timer=getTimer(); |
11 |
|
12 |
addEventListener(Event.ENTER_FRAME,enterFrameHandler); |
13 |
|
14 |
functionenterFrameHandler(e:Event): void { |
15 |
var elapsed: Number =getTimer()-timer; //计算每帧之间间隔的时间差(以毫秒为单位) |
16 |
|
17 |
ball.x+=(ball.vx*elapsed/ 1000 ); //将毫秒换算成秒,再乘“速度”,最终的效果即:如果帧数低,动画播放得太慢,则一次多移动一些距离;反之则少移动一些距离,起到了动态调整的目的. |
18 |
if (ball.x>stage.stageWidth+ball.width/ 2 ){ |
19 |
ball.x=-ball.width/ 2 ; |
20 |
} |
21 |
|
22 |
timer=getTimer(); |
23 |
} |
大家可以尝试把上面的帧数设置,改成200或50,然后再测试下播放效果,会发现小球的移动速度是一致的,不受帧数的影响。(但帧数建议不要低于10,因为人眼的视觉暂留极限大概是0.1秒,低于这个值动画看起来会很卡)
另外,这里对比给出Silverlight的对比代码:
01 |
usingSystem; |
02 |
usingSystem.Windows; |
03 |
usingSystem.Windows.Controls; |
04 |
usingSystem.Windows.Interop; |
05 |
usingSystem.Windows.Threading; |
06 |
|
07 |
namespaceSilverlightApplication1 |
08 |
{ |
09 |
publicpartialclassMainPage:UserControl |
10 |
{ |
11 |
DispatcherTimertmr; |
12 |
Ballb; |
13 |
|
14 |
publicMainPage() |
15 |
{ |
16 |
InitializeComponent(); |
17 |
this .Loaded+=newRoutedEventHandler(MainPage_Loaded); |
18 |
} |
19 |
|
20 |
voidMainPage_Loaded(objectsender,RoutedEventArgse) |
21 |
{ |
22 |
Settingssettings=Application.Current.Host.Settings; |
23 |
settings.EnableFrameRateCounter= true ; |
24 |
settings.MaxFrameRate=1; |
25 |
|
26 |
b=newBall(); //ball是一个自定义控件,里面就一个圆 |
27 |
c.Children.Add(b); |
28 |
b.SetValue(Canvas.LeftProperty,c.Width/2); |
29 |
b.SetValue(Canvas.TopProperty,c.Height/2); |
30 |
|
31 |
tmr=newDispatcherTimer(); |
32 |
tmr.Interval=newTimeSpan(0,0,0,0,20); |
33 |
tmr.Tick+=newEventHandler(tmr_Tick); |
34 |
tmr.Start(); |
35 |
} |
36 |
|
37 |
voidtmr_Tick(objectsender,EventArgse) |
38 |
{ |
39 |
double_left=( double )b.GetValue(Canvas.LeftProperty); |
40 |
b.SetValue(Canvas.LeftProperty,_left+5); |
41 |
} |
42 |
} |
43 |
} |
相同质量的小球碰撞:
Flash/Flex学习笔记(43):动量守恒与能量守恒 里,我们学习了如何用AS3.0来模拟小球的运量守恒,但计算也是很复杂的,对于相同质量的碰撞,其实可以实现得更简单一些。基本原理是,两个物体沿着碰撞的线路交换它们的速度(想深究的同学们,可以自己去解方程验证)。这样我们在处理这种特殊情况时,就可以简化一部分计算,完整代码如下:(注意加★的部分)
001 |
package { |
002 |
|
003 |
importflash.display.Sprite; |
004 |
importflash.events.Event; |
005 |
importflash.geom.Point; |
006 |
|
007 |
publicclassSameMassextendsSprite{ |
008 |
|
009 |
private var balls: Array ; |
010 |
private var numBalls: uint = 8 ; |
011 |
private var bounce: Number =- 1.0 ; |
012 |
|
013 |
publicfunctionSameMass(){ |
014 |
init(); |
015 |
} |
016 |
|
017 |
privatefunctioninit(): void { |
018 |
balls=newArray(); |
019 |
for ( var i: uint = 0 ;i<numBalls;i++){ |
020 |
//varradius:Number=Math.random()*40+10; |
021 |
var radius: Number = 20 ; //★★★★★把所有质量强制为相同 |
022 |
var ball:Ball=newBall(radius,Math.random()* 0xffffff ); |
023 |
ball.mass=radius; |
024 |
ball.x=i* 100 ; |
025 |
ball.y=i* 50 ; |
026 |
ball.vx=Math.random()* 10 - 5 ; |
027 |
ball.vy=Math.random()* 10 - 5 ; |
028 |
addChild(ball); |
029 |
balls.push(ball); |
030 |
} |
031 |
addEventListener(Event.ENTER_FRAME,onEnterFrame); |
032 |
} |
033 |
|
034 |
privatefunctiononEnterFrame(event:Event): void { |
035 |
for ( var i: uint = 0 ;i<numBalls;i++){ |
036 |
var ball:Ball=balls[i]; |
037 |
ball.x+=ball.vx; |
038 |
ball.y+=ball.vy; |
039 |
checkWalls(ball); |
040 |
} |
041 |
|
042 |
for (i= 0 ;i<numBalls- 1 ;i++){ |
043 |
var ballA:Ball=balls[i]; |
044 |
for ( var j: Number =i+ 1 ;j<numBalls;j++){ |
045 |
var ballB:Ball=balls[j]; |
046 |
checkCollision(ballA,ballB); |
047 |
} |
048 |
} |
049 |
} |
050 |
|
051 |
|
052 |
//舞台边界检测 |
053 |
functioncheckWalls(b:Ball){ |
054 |
if (b.x<b.radius){ |
055 |
b.x=b.radius; |
056 |
b.vx*=bounce; |
057 |
} |
058 |
elseif(b.x>stage.stageWidth-b.radius){ |
059 |
b.x=stage.stageWidth-b.radius; |
060 |
b.vx*=bounce; |
061 |
} |
062 |
if (b.y<b.radius){ |
063 |
b.y=b.radius; |
064 |
b.vy*=bounce; |
065 |
} |
066 |
elseif(b.y>stage.stageHeight-b.radius){ |
067 |
b.y=stage.stageHeight-b.radius; |
068 |
b.vy*=bounce; |
069 |
} |
070 |
} |
071 |
|
072 |
privatefunctionrotate(x: Number ,y: Number ,sin: Number ,cos: Number ,reverse: Boolean ):Point{ |
073 |
var result:Point=newPoint(); |
074 |
if (reverse){ |
075 |
result.x=x*cos+y*sin; |
076 |
result.y=y*cos-x*sin; |
077 |
} |
078 |
else { |
079 |
result.x=x*cos-y*sin; |
080 |
result.y=y*cos+x*sin; |
081 |
} |
082 |
returnresult; |
083 |
} |
084 |
|
085 |
privatefunctioncheckCollision(ball0:Ball,ball1:Ball): void { |
086 |
var dx: Number =ball1.x-ball0.x; |
087 |
var dy: Number =ball1.y-ball0.y; |
088 |
var dist: Number =Math.sqrt(dx*dx+dy*dy); |
089 |
if (dist<ball0.radius+ball1.radius){ |
090 |
//计算角度和正余弦值 |
091 |
var angle: Number =Math.atan2(dy,dx); |
092 |
var sin: Number =Math.sin(angle); |
093 |
var cos: Number =Math.cos(angle); |
094 |
//旋转ball0的位置 |
095 |
var pos0:Point=newPoint( 0 , 0 ); |
096 |
//旋转ball1的速度 |
097 |
var pos1:Point=rotate(dx,dy,sin,cos, true ); |
098 |
//旋转ball0的速度 |
099 |
var vel0:Point=rotate(ball0.vx,ball0.vy,sin,cos, true ); |
100 |
//旋转ball1的速度 |
101 |
var vel1:Point=rotate(ball1.vx,ball1.vy,sin,cos, true ); |
102 |
/*//碰撞的作用力 |
103 |
varvxTotal:Number=vel0.x-vel1.x; |
104 |
vel0.x=((ball0.mass-ball1.mass)*vel0.x+2*ball1.mass*vel1.x)/(ball0.mass+ball1.mass); |
105 |
vel1.x=vxTotal+vel0.x;*/ |
106 |
//★★★★★改成速度交换★★★★★ |
107 |
var temp:Point=vel0; |
108 |
vel0=vel1; |
109 |
vel1=temp; |
110 |
|
111 |
//更新位置 |
112 |
var absV: Number =Math.abs(vel0.x)+Math.abs(vel1.x); |
113 |
var overlap: Number =(ball0.radius+ball1.radius)-Math.abs(pos0.x-pos1.x); |
114 |
pos0.x+=vel0.x/absV*overlap; |
115 |
pos1.x+=vel1.x/absV*overlap; |
116 |
//将位置旋转回来 |
117 |
var pos0F: Object =rotate(pos0.x,pos0.y,sin,cos, false ); |
118 |
var pos1F: Object =rotate(pos1.x,pos1.y,sin,cos, false ); |
119 |
//将位置调整为屏幕的实际位置 |
120 |
ball1.x=ball0.x+pos1F.x; |
121 |
ball1.y=ball0.y+pos1F.y; |
122 |
ball0.x=ball0.x+pos0F.x; |
123 |
ball0.y=ball0.y+pos0F.y; |
124 |
//将速度旋转回来 |
125 |
var vel0F: Object =rotate(vel0.x,vel0.y,sin,cos, false ); |
126 |
var vel1F: Object =rotate(vel1.x,vel1.y,sin,cos, false ); |
127 |
ball0.vx=vel0F.x; |
128 |
ball0.vy=vel0F.y; |
129 |
ball1.vx=vel1F.x; |
130 |
ball1.vy=vel1F.y; |
131 |
} |
132 |
} |
133 |
} |
134 |
} |
声音的使用:
声音的使用其实没什么特别的,跟图片,视频等其它资源都差不多.
如上图,在导入一个声音时,可以指定一个类名,然后在代码中,就可以new一个该类的实例了。除此之外,还可以直接加载远程声音,完整代码如下:
01 |
var bgMusic=newSound(newURLRequest( "http://210.51.38.234/music/sophie_zelmani_Going_Home.mp3" )); |
02 |
var stf:SoundTransform=newSoundTransform(); |
03 |
stf.volume= 0.3 ; |
04 |
bgMusic.play( 0 , 0 ,stf); |
05 |
|
06 |
var bing:Bing=newBing(); |
07 |
var ball:Ball=newBall( 30 ); |
08 |
ball.vx= 5 ; |
09 |
ball.vy= 5 ; |
10 |
ball.x=stage.stageWidth/ 2 ; |
11 |
ball.y=stage.stageHeight/ 2 ; |
12 |
addChild(ball); |
13 |
|
14 |
addEventListener(Event.ENTER_FRAME,EnterFrameHandler); |
15 |
|
16 |
functionEnterFrameHandler(e:Event): void { |
17 |
ball.x+=ball.vx; |
18 |
ball.y+=ball.vy; |
19 |
|
20 |
if (ball.x>=stage.stageWidth-ball.radius){ |
21 |
ball.x=stage.stageWidth-ball.radius; |
22 |
ball.vx*=- 1 ; |
23 |
bing.play(); |
24 |
} |
25 |
elseif(ball.x<=ball.radius){ |
26 |
ball.x=ball.radius; |
27 |
ball.vx*=- 1 ; |
28 |
bing.play(); |
29 |
} |
30 |
|
31 |
if (ball.y>=stage.stageHeight-ball.radius){ |
32 |
ball.y=stage.stageHeight-ball.radius; |
33 |
ball.vy*=- 1 ; |
34 |
bing.play(); |
35 |
} |
36 |
elseif(ball.y<=ball.radius){ |
37 |
ball.y=ball.radius; |
38 |
ball.vy*=- 1 ; |
39 |
bing.play(); |
40 |
} |
41 |
} |
AnimationinActionScript3.0/MakingThingsMove!一书终于全部啃完了,感谢作者“KeithPeters”大师写出这么好的书,感谢[FL基理文]历时4个月的用心翻译!强烈推荐给想研究Silverlight/Flash动画的朋友们,里面的很多思想和处理方法都是动画编程通用的,并不局限于某一种特定的语言!“师傅领进门,修行在各人”,以后在动画编程的道路上能走多远,就只能看自己的造化了。