Flash/Flex学习笔记(18):画线及三角函数的基本使用
Sprite有一个graphics可以用来绘制基本图形,比如我们要画下面这个图形:
对应的AS3代码为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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(); } } } |
把它加到舞台上,并自动跟着鼠标转动(下列代码写在第一帧):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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之间来回摆动,如果在动画中需要来回振荡的情况,正弦函数就派上用场了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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,在接下来的动画里,我们让小球沿正弦轨迹运行,同时另一个小球模拟“心跳”运动(即改变大小)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | 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; } } |
甚至还可以同时把正弦函数应用到多个属性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | //参数常量 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
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
出处:http://yjmyzz.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
· Sdcb Chats 技术博客:数据库 ID 选型的曲折之路 - 从 Guid 到自增 ID,再到
· 语音处理 开源项目 EchoSharp
· 《HelloGitHub》第 106 期
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 使用 Dify + LLM 构建精确任务处理应用
2009-03-31 WCF运行错误:“此集合已经包含方案 http 的地址”的解决办法