zoukankan      html  css  js  c++  java
  • Flash/Flex学习笔记(18):画线及三角函数的基本使用

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

    作者:菩提树下的杨过
    出处:http://yjmyzz.cnblogs.com
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    linux杀死僵尸进程
    通过dd命令显示硬盘的读写性能
    linux 压缩与解压缩
    linux云主机cpu一直很高降不下来,系统日志报nf_conntrack: table full, dropping packet.
    vsftp配置文件详解
    linux中ping带时间及打印内容到文件
    atop工具检测linux硬件异常
    windows连接服务端的域名正常,linux却不通,(针对于负载均衡后端节点设置)
    有你的地方就是天堂
    Java 异常 —— java.io.InvalidClassException: javax.xml.namespace.QName; local class incompatible
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/1701757.html
Copyright © 2011-2022 走看看