六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 21|回复: 0

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

[复制链接]

升级  83.33%

51

主题

51

主题

51

主题

秀才

Rank: 2

积分
175
 楼主| 发表于 2013-1-29 09:20:57 | 显示全部楼层 |阅读模式
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的变化速度改成随机,结果可能更有趣:
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表