Flash/Flex学习笔记(18):画线及三角函数的基本使用

Sprite有一个graphics可以用来绘制基本图形,比如我们要画下面这个图形:

对应的AS3代码为:

view source

print?

01
package {

02
import flash.display.Sprite;

03

04
public class Arrow extends Sprite {

05
public function Arrow():void {

06
init();

07
}       

08
private function init():void{               

09
graphics.lineStyle(1,0,1); 

10
graphics.beginFill(0xffff99);

11
graphics.drawCircle(0,0,2);//中心点

12
graphics.moveTo(0,50); 

13
graphics.lineTo(100,50);

14
graphics.lineTo(100,0);

15
graphics.lineTo(150,75);

16
graphics.lineTo(100,150);

17
graphics.lineTo(100,100);

18
graphics.lineTo(0,100);

19
graphics.lineTo(0,50);

20
graphics.endFill();         

21
}

22
}

23
}

把它加到舞台上,并自动跟着鼠标转动(下列代码写在第一帧):

view source

print?

01
var _arrow:Arrow = new Arrow();

02
addChild(_arrow);

03
_arrow.x=stage.stageWidth/2-50;

04
_arrow.y=stage.stageHeight/2-75;

05

06
this.addEventListener(Event.ENTER_FRAME,EnterFrameHandler);

07

08
function EnterFrameHandler(e:Event):void {

09
var dx:Number=mouseX-_arrow.x;

10
var dy:Number=mouseY-_arrow.y;

11
//trace("dy=" + dy + ",dx=" + dx);

12
var angle:Number=Math.atan2(dy,dx);

13
_arrow.rotation=angle*180/Math.PI;  

14
}

这里用到了反正切函数,其原理示意图如下:

即以鼠标所在点与Arrow图形中心点为参考,构建一个三角形,利用对边比邻边得到正切,然后利用反正切求出角度,最终让图形旋转该角度,下面是效果:

但是好象有点问题,相信您也看出来了,因为我们绘制图形时,默认是以坐标原点为中心,而非图形中心点为中心,所以在跟随鼠标旋转时,总感觉有些错位,没关系,只要调整一下Arrow.cs即可

view source

print?

01
package {

02
import flash.display.Sprite;

03

04
public class Arrow extends Sprite {

05
public function Arrow():void {

06
init();

07
}       

08
private function init():void{               

09
graphics.lineStyle(1,0,1); 

10
graphics.beginFill(0xffff99);

11
graphics.drawCircle(0,0,2);//中心点

12
graphics.moveTo(-75,-25); 

13
graphics.lineTo(25,-25);

14
graphics.lineTo(25,-75);

15
graphics.lineTo(75,0);

16
graphics.lineTo(25,75);

17
graphics.lineTo(25,25);

18
graphics.lineTo(-75,25);

19
graphics.lineTo(-75,-25);

20
graphics.endFill();         

21
}

22
}

23
}

另一个很有用的三角函数就是正弦Sin函数--对边比斜边

当Sin函数的角度参数从0度变化到360度时,正弦函数的值会在1到-1之间来回摆动,如果在动画中需要来回振荡的情况,正弦函数就派上用场了

view source

print?

01
package{

02
import flash.display.Sprite;

03

04
//小球 类

05
public class Ball extends Sprite{

06

07
private var radius:Number ;//半径

08
private var color:uint;//颜色

09

10
public function Ball(r:Number=50,c:uint=0xff0000){

11
this.radius = r;

12
this.color = c;

13
init();

14
}

15

16
private function init():void{

17
graphics.beginFill(color);

18
graphics.drawCircle(0,0,radius);

19
graphics.endFill();

20
}

21
}

22
}

这里我们先定义一个基本的小球类Ball,在接下来的动画里,我们让小球沿正弦轨迹运行,同时另一个小球模拟“心跳”运动(即改变大小)

view source

print?

01
var angle:Number = 0;

02

03
//参数常量

04
const Y_SPEED = 0.1; //y轴移动速度

05
const X_SPEED = 1; //x轴移动速度

06
const AMPLITUDE = 50.0; //最大振幅

07
const X_START = 0; //x轴的起始点

08

09
//变量

10
var ySpeed:Number = Y_SPEED;

11
var xSpeed:Number = X_SPEED;

12
var amplitude:Number = AMPLITUDE;

13

14
var b:Ball = new Ball(5,0xff0000);

15
addChild(b);

16
b.x = X_START;

17

18
var heart:Ball = new Ball(50,0x0000ff);

19
addChild(heart);

20
heart.x = stage.stageWidth/2;

21
heart.y = stage.stageHeight/2;

22
heart.alpha = 0.3;

23

24
addEventListener(Event.ENTER_FRAME,EnterFrameHandler);

25

26
function EnterFrameHandler(e:Event){

27
b.y = stage.stageHeight/2 + Math.sin(angle) * amplitude;

28
angle += ySpeed;

29
b.x += xSpeed;

30

31
heart.scaleX = heart.scaleY = 1 + Math.sin(angle) * 0.5;

32

33
graphics.lineStyle(1,0xefefef,1);

34
graphics.lineTo(b.x,b.y);

35

36

37
//x,y,振幅 逐渐加大

38
xSpeed += 0.08;

39
ySpeed += 0.003;

40
amplitude += 1;

41

42
if (b.x > stage.stageWidth + b.width){

43
//超出舞台后,还原参数

44
b.x = X_START;

45
xSpeed = X_SPEED;

46
ySpeed = Y_SPEED;

47
amplitude = AMPLITUDE;

48
}   

49

50
}

甚至还可以同时把正弦函数应用到多个属性:

view source

print?

01
//参数常量

02
const Y_SPEED = 0.07; //y轴变化速度

03
const X_SPEED = 0.10; //x轴变化速度

04
const AMPLITUDE = 150.0; //最大振幅

05
const X_START = stage.stageWidth/2; //x轴的起始点

06
const Y_START = stage.stageHeight/2; //y轴的起始点

07

08
//变量

09
var ySpeed:Number = Y_SPEED;

10
var xSpeed:Number = X_SPEED;

11
var amplitude:Number = AMPLITUDE;

12
var angleX = 0;

13
var angleY = 0;

14

15
var b:Ball = new Ball(5,0xff0000);

16
addChild(b);

17

18
b.x = X_START;

19
b.y = Y_START;

20

21
graphics.moveTo(b.x,b.y);

22

23
addEventListener(Event.ENTER_FRAME,EnterFrameHandler);

24

25
function EnterFrameHandler(e:Event){    

26

27
b.y = Y_START + Math.sin(angleY) * amplitude;

28
b.x = X_START + Math.sin(angleX) * amplitude;

29

30
angleX += xSpeed;

31
angleY += ySpeed;

32

33
//angleX += Math.random()/10;

34
//angleY += Math.random()/5;

35

36
graphics.lineStyle(1,0xefefef,1);

37
graphics.lineTo(b.x,b.y);

38
}

如果把代码中的二行注释启用,即让x,y的变化速度改成随机,结果可能更有趣:

posted @ 2010-11-22 16:42  模西的哥哥  阅读(281)  评论(0编辑  收藏  举报