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

简介: Sprite有一个graphics可以用来绘制基本图形,比如我们要画下面这个图形: 对应的AS3代码为: package { import flash.display.Sprite; public class Arrow extends Sprite { public f...

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

img_98978ab383c97ac069b1b4edebf7bb5d.gif

对应的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;	
}

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

img_075b1e6db6e43bcd859cfa455ed4a4f1.gif

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

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

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的变化速度改成随机,结果可能更有趣:

目录
相关文章
|
4月前
|
前端开发
css 实用技巧 —— 使用border属性绘图(三角形、梯形、对话框尖角)
css 实用技巧 —— 使用border属性绘图(三角形、梯形、对话框尖角)
72 1
【Three.js入门】图形用户界面GUI、BufferGeometry创建矩形、随机生成多个随机颜色的三角形
【Three.js入门】图形用户界面GUI、BufferGeometry创建矩形、随机生成多个随机颜色的三角形
239 0
|
前端开发
零基础CSS入门教程(13)——边框样式
可以通过border-style设置边框样式,常用的有solid实线、dotted点线、dashed虚线三种。大家想必发现了,我们在设定边框样式时,一般都会同时设定边框样式、宽度、颜色,如果逐一定义,比较麻烦。我们前几个小结学习了有序列表无序列表,我们这一小节学习一下边框样式很重要的一个知识点。我们本小节学习了边框样式,内容有点多,大家要学会熟练使用,我们在开发中很常用。可以通过border-width调整边框的宽度,单位一般使用px像素。可以使用bolder-color指定边框的颜色,
零基础CSS入门教程(13)——边框样式
|
前端开发
零基础CSS入门教程(15)——颜色值
我们可以通过RGB,R代表红色,G代表绿色,B代表蓝色,来确定颜色值。实际上,在光学中,红、绿、蓝三种颜色被称为三原色,也就是说这三种光学颜色混合后,可以产生各种各样的颜色。基于三原色的原理,我们也可以通过设置红、绿、蓝颜色的比例,来确定一个特定的颜色。我们学会了颜色值,我们就可以自己去定义自己喜欢的颜色,使我们的页面五彩缤纷。世界是五彩缤纷的,不论是皑皑的白雪、还是飘落的秋叶,世界因色彩而绚丽。之前我们已经学习过设置文本的颜色,设置背景色,以及设置边框的颜色。同样,网页也因为合理搭配色彩,而美观。
零基础CSS入门教程(15)——颜色值
|
前端开发 容器
Silverlight & Blend动画设计系列十二:三角函数(Trigonometry)动画之自由旋转(Free-form rotation)
原文:Silverlight & Blend动画设计系列十二:三角函数(Trigonometry)动画之自由旋转(Free-form rotation)   说到对象的旋转,或许就会联想到对象角度的概念。
980 0
|
数据库
ObjectArx学习笔记-画线并修改颜色改进写法
1、创建工程CreateEnts 2、添加类CCreateEnt,在文件CreateEnt.h中添加函数声明,在CreateEnt.cpp添加函数实现代码: static AcDbObjectId CreateLine(); AcDbObjectId CCreateEnt::CreateLine() { AcGePoint3d ptStart(0,0,0); AcGePoint3
987 0
|
内存技术
Flash/Flex学习笔记(56):矩阵变换
先回顾一下Silvelright中的矩阵变换[转]WPF中的MatrixTransform,简单点讲:矩阵变换能改变对象的x,y坐标,x或y方向上的缩放,以及对象在x,y轴上的旋转(扭曲变形) 上面这个是WPF/Silverlight中的3*3变换矩阵,其中X,Y用于改变对象的坐标;M11,M22用于对象在x,y轴上的缩放;而M12,M21用于y轴,x轴上的扭曲。
869 0
|
内存技术
Flash/Flex学习笔记(51):3维旋转与透视变换(PerspectiveProjection)
Flash/Flex学习笔记(49):3D基础 里已经介绍了3D透视的基本原理,不过如果每次都要利用象该文中那样写一堆代码,估计很多人不喜欢,事实上AS3的DisplayObject类已经内置了z坐标、rotationX、rotationY、rotationZ属性,再加上PerspectiveProjection类用于处理透视转换,基本上可以满足大多数的3D要求。
1054 0
|
Java Spring 内存技术
Flash/Flex学习笔记(41):碰撞检测
碰撞检测基本上可能分为二类:对象与对象的碰撞检测、对象与点的碰撞检测 为了方便测试,先写一个box类(生成一个小矩形) package { import flash.display.Sprite; public class Box extends Sprite { ...
870 0