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)

posted @ 2010-07-15 15:19  CoderWayne  阅读(1059)  评论(0编辑  收藏  举报