Sprite有一个graphics可以用来绘制基本图形,比如我们要画下面这个图形:
对应的AS3代码为:
package { import flash.display.Sprite; public class Arrow extends Sprite { public function Arrow():void { init(); } private function init():void{ graphics.lineStyle(1,0,1); graphics.beginFill(0xffff99); graphics.drawCircle(0,0,2);//中心点 graphics.moveTo(0,50); graphics.lineTo(100,50); graphics.lineTo(100,0); graphics.lineTo(150,75); graphics.lineTo(100,150); graphics.lineTo(100,100); graphics.lineTo(0,100); graphics.lineTo(0,50); graphics.endFill(); } } }
把它加到舞台上,并自动跟着鼠标转动(下列代码写在第一帧):
var _arrow:Arrow = new Arrow(); addChild(_arrow); _arrow.x=stage.stageWidth/2-50; _arrow.y=stage.stageHeight/2-75; this.addEventListener(Event.ENTER_FRAME,EnterFrameHandler); function EnterFrameHandler(e:Event):void { var dx:Number=mouseX-_arrow.x; var dy:Number=mouseY-_arrow.y; //trace("dy=" + dy + ",dx=" + dx); var angle:Number=Math.atan2(dy,dx); _arrow.rotation=angle*180/Math.PI; }
这里用到了反正切函数,其原理示意图如下:
即以鼠标所在点与Arrow图形中心点为参考,构建一个三角形,利用对边比邻边得到正切,然后利用反正切求出角度,最终让图形旋转该角度,下面是效果:
但是好象有点问题,相信您也看出来了,因为我们绘制图形时,默认是以坐标原点为中心,而非图形中心点为中心,所以在跟随鼠标旋转时,总感觉有些错位,没关系,只要调整一下Arrow.cs即可
package { import flash.display.Sprite; public class Arrow extends Sprite { public function Arrow():void { init(); } private function init():void{ graphics.lineStyle(1,0,1); graphics.beginFill(0xffff99); graphics.drawCircle(0,0,2);//中心点 graphics.moveTo(-75,-25); graphics.lineTo(25,-25); graphics.lineTo(25,-75); graphics.lineTo(75,0); graphics.lineTo(25,75); graphics.lineTo(25,25); graphics.lineTo(-75,25); graphics.lineTo(-75,-25); graphics.endFill(); } } }
另一个很有用的三角函数就是正弦Sin函数--对边比斜边
当Sin函数的角度参数从0度变化到360度时,正弦函数的值会在1到-1之间来回摆动,如果在动画中需要来回振荡的情况,正弦函数就派上用场了
package{ import flash.display.Sprite; //小球 类 public class Ball extends Sprite{ private var radius:Number ;//半径 private var color:uint;//颜色 public function Ball(r:Number=50,c:uint=0xff0000){ this.radius = r; this.color = c; init(); } private function init():void{ graphics.beginFill(color); graphics.drawCircle(0,0,radius); graphics.endFill(); } } }
这里我们先定义一个基本的小球类Ball,在接下来的动画里,我们让小球沿正弦轨迹运行,同时另一个小球模拟“心跳”运动(即改变大小)
var angle:Number = 0; //参数常量 const Y_SPEED = 0.1; //y轴移动速度 const X_SPEED = 1; //x轴移动速度 const AMPLITUDE = 50.0; //最大振幅 const X_START = 0; //x轴的起始点 //变量 var ySpeed:Number = Y_SPEED; var xSpeed:Number = X_SPEED; var amplitude:Number = AMPLITUDE; var b:Ball = new Ball(5,0xff0000); addChild(b); b.x = X_START; var heart:Ball = new Ball(50,0x0000ff); addChild(heart); heart.x = stage.stageWidth/2; heart.y = stage.stageHeight/2; heart.alpha = 0.3; addEventListener(Event.ENTER_FRAME,EnterFrameHandler); function EnterFrameHandler(e:Event){ b.y = stage.stageHeight/2 + Math.sin(angle) * amplitude; angle += ySpeed; b.x += xSpeed; heart.scaleX = heart.scaleY = 1 + Math.sin(angle) * 0.5; graphics.lineStyle(1,0xefefef,1); graphics.lineTo(b.x,b.y); //x,y,振幅 逐渐加大 xSpeed += 0.08; ySpeed += 0.003; amplitude += 1; if (b.x > stage.stageWidth + b.width){ //超出舞台后,还原参数 b.x = X_START; xSpeed = X_SPEED; ySpeed = Y_SPEED; amplitude = AMPLITUDE; } }
甚至还可以同时把正弦函数应用到多个属性:
//参数常量 const Y_SPEED = 0.07; //y轴变化速度 const X_SPEED = 0.10; //x轴变化速度 const AMPLITUDE = 150.0; //最大振幅 const X_START = stage.stageWidth/2; //x轴的起始点 const Y_START = stage.stageHeight/2; //y轴的起始点 //变量 var ySpeed:Number = Y_SPEED; var xSpeed:Number = X_SPEED; var amplitude:Number = AMPLITUDE; var angleX = 0; var angleY = 0; var b:Ball = new Ball(5,0xff0000); addChild(b); b.x = X_START; b.y = Y_START; graphics.moveTo(b.x,b.y); addEventListener(Event.ENTER_FRAME,EnterFrameHandler); function EnterFrameHandler(e:Event){ b.y = Y_START + Math.sin(angleY) * amplitude; b.x = X_START + Math.sin(angleX) * amplitude; angleX += xSpeed; angleY += ySpeed; //angleX += Math.random()/10; //angleY += Math.random()/5; graphics.lineStyle(1,0xefefef,1); graphics.lineTo(b.x,b.y); }
如果把代码中的二行注释启用,即让x,y的变化速度改成随机,结果可能更有趣: