AS3 CookBook学习整理(十)
1. 在指定方向(角度)上移动
x方向的增量取的是Math.cos(angle),y方向的增量取的是Math.sin(angle)
package { import flash.display.Sprite; import flash.events.TimerEvent; import flash.utils.Timer; public class Sample0514 extends Sprite { private var circle:Sprite; private var angle:Number = 45; private var speed:int = 6; //速度为每帧6像素 public function Sample0514() { circle = new Sprite(); circle.graphics.beginFill(0xFFFF00); circle.graphics.drawCircle(50,50,30); circle.graphics.endFill(); this.addChild(circle); var timer:Timer = new Timer(30); timer.addEventListener(TimerEvent.TIMER,onTimer); timer.start(); } private function onTimer(event:TimerEvent):void { var radian:Number = angle * Math.PI / 180; circle.x += Math.cos(radian) * speed; circle.y += Math.sin(radian) * speed; } } }
2. 减速运动
x方向的移动:(mouseX - object.x) * speed;
y方向的移动:(mouseY - object.y) * speed;
物体与目标位置的距离:
var vx:Number = (mouseX - circle.x);
var vy:Number = (mouseY - circle.y);
var distance:Number = Math.sqrt(vx*vx + vy*vy);
package { import flash.display.Sprite; import flash.events.MouseEvent; import flash.events.TimerEvent; import flash.utils.Timer; public class Sample0515 extends Sprite { private var timer:Timer; private var circle:Sprite; public function Sample0515() { circle = new Sprite(); circle.graphics.beginFill(0xFFFF00); circle.graphics.drawCircle(0,0,25); circle.graphics.endFill(); this.addChild(circle); stage.addEventListener(MouseEvent.CLICK,onClick); timer = new Timer(30); timer.addEventListener(TimerEvent.TIMER,onTimer); timer.start(); } private function onClick(event:MouseEvent):void { if(circle.x != mouseX && circle.y != mouseY) { timer.start(); } } private function onTimer(event:TimerEvent):void { var vx:Number = (mouseX - circle.x); var vy:Number = (mouseY - circle.y); var distance:Number = Math.sqrt(vx*vx + vy*vy); if(distance<1) { timer.stop(); circle.x = mouseX; circle.y = mouseY; } else { circle.x += vx * 0.1; circle.y += vy * 0.1; } } } }
3. 加速运动
加速运动,就是每次移动时,坐标的增量递增
package { import flash.display.Sprite; import flash.events.Event; public class Sample0526 extends Sprite { private var circle:Sprite; private var speed:Number = 0.5; private var angle:Number = 45; public function Sample0526() { circle = new Sprite(); circle.graphics.beginFill(0xFFFF00); circle.graphics.drawCircle(50,50,20); circle.graphics.endFill(); this.addChild(circle); this.addEventListener(Event.ENTER_FRAME,onEnterFrame); } private function onEnterFrame(event:Event):void { var radian:Number = angle * Math.PI /180; speed += .3; circle.x += Math.cos(radian) * speed; circle.y += Math.sin(radian) * speed; } } }
4. 弹簧(胡克定律)
胡克的弹性定律指出:在弹性限度内,弹簧的弹力f和弹簧的长度x成正比,即f= -kx。k是物质的弹性系数,它由材料的性质所决定,负号表示弹簧所产生的弹力与其伸长(或压缩)的方向相反。
F=k·x
F -- 表示弹簧的弹力,单位是牛
k -- 劲度系数,单位是牛/米
x -- 是弹簧伸长或缩短的长度,单位是米
as实现弹簧定律的关键代码:
<1> 设定一个目标点(x1,y1)
<2> 得到物体中心点(x,y)到目标点(x1,y1)的增量(拉伸量,对应胡克定律里的x)
<3> 将增量累加到变量保存(vx,vy)
<4> 物体每次增加vx,vy(vx,vy为正值,则为远离中心点的弹簧动作;为负值,则为接近中心点的弹簧动作)
<5> 加上损耗(_vx *= 0.95; _vy * 0.95),不加损耗则为永动,类似钟摆效果。
一般在as里,设置k(劲度系数)为0.1或0.2;损耗设置为0.95(每次弹跳丢失5%的能量)
package { import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; public class Sample0601 extends Sprite { private var circle:Sprite; private var vx:Number = 0; private var vy:Number = 0; private var flag:Boolean = false; private var targetX:Number; private var targetY:Number; public function Sample0601() { circle = new Sprite(); circle.graphics.beginFill(0xFFFF00); circle.graphics.drawCircle(0,0,30); circle.graphics.endFill(); circle.x = circle.y = 100; this.addChild(circle); stage.addEventListener(MouseEvent.CLICK,onClick); stage.addEventListener(Event.ENTER_FRAME,onEnterFrame); } private function onEnterFrame(event:Event):void { if(flag) { var ax:Number = (targetX - circle.x) * .1; var ay:Number = (targetY - circle.y) * .1; vx += ax; vy += ay; circle.x += vx; circle.y += vy; vx *= .95; vy *= .95; } } private function onClick(event:MouseEvent):void { flag = true; targetX = mouseX; targetY = mouseY; } } }
5. 利用sin和cos实现旋转,循环运动或摆动
Math.sin()和Math.cos函数的返回值范围在 -1 到 1 之间,sin()是从小到大,cos()是从大到小
可以通过循环输出sin()或cos()来得到一个范围内的一串数字,例如:
for(var i:Numer = 0; i<10; i+= 0.1) { trace(Math.sin(i)*50);//将输出-50到50之间的数字 trace(Math.cos(i)*50);//将输出50到-50之间的数字 }
根据上面的规律,可以实现左右摆动(钟摆)、沿中心点转动的效果
package { import flash.display.Sprite; import flash.events.Event; public class Sample0601 extends Sprite { private var circle:Sprite; private var angle:Number = 0; public function Sample0601() { circle = new Sprite(); circle.graphics.beginFill(0xFFFF00); circle.graphics.drawCircle(0,0,20); circle.graphics.endFill(); this.addChild(circle); this.addEventListener(Event.ENTER_FRAME,onEnterFrame); } private function onEnterFrame(event:Event):void { //左右摆动 //circle.x = 200 + Math.sin(angle) * 50; //逆时针沿着中心点做圆周运动 circle.x = 200 + Math.sin(angle) * 50; circle.y = 200 + Math.cos(angle) * 50; //顺时针沿着中心点做圆周运动 //circle.x = 200 + Math.cos(angle) * 50; //circle.y = 200 + Math.sin(angle) * 50; //逆时针沿着中心点做椭圆形运动 //circle.x = 200 + Math.sin(angle) * 50; //circle.y = 200 + Math.cos(angle) * 20; //随机运动 //circle.x = 200 + Math.sin(xAngle) * xRadius; //circle.y = 200 + Math.cos(yAngle) * yRadius; //_xAngle += _xSpeed; //_yAngle += _ySpeed; angle += .2; } } }
6. 利用Math.atan2(y, x)计算两个点的夹角
已知一个点(x1, y1),通过Math.atan2(y1, x1)可以得到这个点相对于坐标原点(0, 0)X轴的夹角
假如有两个点A(x1, y1)、B(x2, y2),则可以将A点视为坐标原点(0, 0),然后通过Math.atan2(y2 - y1, x2 - x1)计算出A、B两点的夹角
一个眼珠跟随鼠标效果:
package { import flash.display.Sprite; import flash.events.Event; public class Sample0601 extends Sprite { private var circle:Sprite; private var angle:Number = 0; public function Sample0601() { circle = new Sprite(); circle.graphics.beginFill(0xFFFFFF); circle.graphics.drawCircle(0,0,30); circle.graphics.endFill(); circle.graphics.beginFill(0x000000); circle.graphics.drawCircle(20,0,5); circle.graphics.endFill(); circle.x = circle.y = 200; this.addChild(circle); this.addEventListener(Event.ENTER_FRAME,onEnterFrame); } private function onEnterFrame(event:Event):void { var dx:Number = mouseX - circle.x; var dy:Number = mouseY - circle.y; var radian:Number = Math.atan2(dy,dx); circle.rotation = radian * 180 / Math.PI; } } }
7. 弹簧(胡克定律)用来实现缩放(忽大忽小)
胡克定律也可以应用在缩放值(scale)上,生成一种匀速的缩放,一种应用是心脏扑通扑通跳动效果
package { import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; public class Sample0602 extends Sprite { private var rect:Sprite; private var vx:Number = 0; private var randomNum:Number = 1; public function Sample0602() { rect = new Sprite(); rect.graphics.beginFill(0xFFFF00); rect.graphics.drawRect(-50,-50,100,100); rect.graphics.endFill(); rect.x = 200; rect.y = 150; this.addChild(rect); rect.addEventListener(MouseEvent.CLICK,onClick); this.addEventListener(Event.ENTER_FRAME,onEnterFrame); } private function onClick(event:MouseEvent):void { randomNum = Math.random() * 2 - 0.5; } private function onEnterFrame(event:Event):void { vx += (randomNum - rect.scaleX) * 0.1; rect.scaleX += vx; rect.scaleY = rect.scaleX; vx *= .9; } } }
8. 从一种颜色匀速变化到另一种颜色
利用物体的ColorTransform属性,改变redMultiplier, greenMultiplier, blueMultiplier的值
例如:newRed = (改变颜色的redMultiplier值 - 现在的redMultiplier值) * speed;
package { import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.geom.ColorTransform; public class Sample0602 extends Sprite { private var _sprite:Sprite; private var _red2:Number = 0; private var _green2:Number = 0; private var _blue2:Number = 0; private var newRed:Number = 0; private var newGreen:Number = 0; private var newBlue:Number = 0; private var _easingSpeed:Number = 0.05; private var flag:Boolean = false; public function Sample0602() { _sprite = new Sprite( ); _sprite.graphics.beginFill(0xffffff); _sprite.graphics.drawRect(-50, -50, 100, 100); _sprite.graphics.endFill( ); _sprite.x = 100; _sprite.y = 100; addChild(_sprite); addEventListener(Event.ENTER_FRAME, onEnterFrame); addEventListener(MouseEvent.CLICK, onClick); } public function onEnterFrame(event:Event):void { if(flag) { var ctf:ColorTransform = _sprite.transform.colorTransform; var _red1:Number = ctf.redMultiplier; var _green1:Number = ctf.greenMultiplier; var _blue1:Number = ctf.blueMultiplier; newRed += (_red2 - _red1) * _easingSpeed; newGreen += (_green2 - _green1) * _easingSpeed; newBlue += (_blue2 - _blue1) * _easingSpeed; _sprite.transform.colorTransform = new ColorTransform(newRed, newGreen, newBlue); } } public function onClick(event:MouseEvent):void { _red2 = .5; _green2 = .5; _blue2 = 1; flag = true; } } }
9. 字符串拼接
可以使用str += "abc"或str.concat("abc"),区别在于前者会改变原字符串,后者不会改变原字符串而是生成一个新的字符串
package { import flash.display.Sprite; public class Sample0603 extends Sprite { public function Sample0603() { var str:String = "abc"; str += "def"; trace(str);//abcdef var newStr:String = str.concat("fox"); trace(str);//abcdef trace(newStr);//abcdeffox } } }
10. 获取字符串中的子串
可以使用
substr(startIndex, length)
substring(startIndex, endIndex)
slice(startIndex, endIndex)