




已阅读5页,还剩12页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
镂空遮罩这几天写游戏的新手引导模块,需要做一个镂空遮罩,就是盖着整个场景,只让用户点击镂空的一个圆形区域。这个事看起来很简单。其实就是很简单啊!可是因为我把问题想得太复杂了,浪费了好多时间,特此文章一篇。也希望遇到同样问题的人,不再跳进这个坑。先是上网搜索了,发现都是用混合模式的方法:1.先创建一个Sprite画一个矩形盖着整个场景,blendMode设置为Layer,2.再创建一个Sprite画一个小圆,blendMode设置为Erase。3.将小圆添加到矩形里。 OK,镂空图案出来了。中间一个圆确实是透明的,可是测试的时候发现,这个方法根本是个坑。因为即使中间的圆形区域看起来是透明的,却还是可以点击的!根本没有穿透。整个场景被盖得严严实实的。然后又继续上网搜索,看了几篇坑更深的博文,“详细分析”了镂空遮罩这个东西在Flash Player似乎是不可实现的,并且不记得在哪看见了“模拟鼠标事件”的字眼。好吧,既然这样。那我就模拟鼠标点击事件吧。继续用混合模式的方法,制作一个全部盖着的遮罩。然后监听,中间那个圆形的鼠标事件获取点击位置,再然后克隆下这个事件想办法从遮罩后面的某个显示对象上抛出去。那要怎么确定从哪个对象上抛事件呢?我查了下API,发现DisplayObject有个不太常用的函数:getObjectsUnderPoint()。测试了下,发现它能拿到指定坐标下的所有显示对象列表,并且从外向内,从低层到顶层地排序。也就列表是最后一个元素是该坐标下最顶部的最小的一个显示对象。嗯,感觉有点靠谱了。我就直接用最后一个显示对象抛出克隆的鼠标事件。放到工程里测试了下,发现果然可以。但是,只是部分可以,有的地方怎么点都没反应。我又断点调试看了下。原来那个方法返回的只是显示对象列表,但并不是所有显示对象都能冒泡鼠标事件的。能冒泡鼠标事件的对象必须是InteractiveObject的子类。而InteractiveObject是DisplayObject的子类。问题就出在这。DisplayObject的子类里有个Shape,它不是Interactive的子类。所以在它上面抛出鼠标事件,一点反应都没有。好吧,那我再判断下,如果它不是InteractiveObject,就用它的父级抛出鼠标事件。嗯,感觉又靠谱了。测试了下,怎么还是不行啊?再断点调试,发现列表最顶端的元素,它的父级的父级的父级,mouseChildren和mouseEnabled都是false,也就是说,这个元素,它本应该是被穿过的,它下一层的元素才有可能是可以抛出鼠标事件的对象。这下纠结了啊,下一个元素有可能是它的父级,有可能是它同级的,也有可能是同级的子项。并且不是它自身的mouseEnabled为true就算了。每一层的父级,若有一个mouseChildren为false,则子项的mouseEnabled全都相当于false。即使自身的mouseEnabled为false,它也有可能作为父级的点击区域而存在。这坑已经越来越深了。我纠结了一下午,都在理这其中的判定顺序。就在我即将突破的时候。同事来凑热闹了,了解了情况后说:果然纠结啊,我也想试试。然后他就回去用Flash pro画了一个mc出来,杯具就这样发生了。他回去只写了几行测试代码。叫我过去看,结果居然就搞定了。原来用绘图函数,直接drawRect(),再drawEllipse(),第一个Rect就会被第二个Ellipse抠出个镂空区域来,画出来的镂空区域就是可以穿过点击的。没错,就是这么简单。下面上代码:?123456789101112131415161718192021222324252627282930313233343536373839404142packageimport flash.display.Sprite;import flash.events.MouseEvent;/* 镂空遮罩测试* author DOM*/public class HollowTest extends Spritepublic function HollowTest()super();var bg:Sprite = new Sprite;bg.graphics.beginFill(0x009aff);bg.graphics.drawRect(0,0,500,400);bg.graphics.endFill();bg.addEventListener(MouseEvent.CLICK,onBgClick);addChild(bg);var hollowMask:Sprite = new Sprite;hollowMask.graphics.beginFill(0x009900);hollowMask.graphics.drawRect(150,100,200,200);hollowMask.graphics.drawEllipse(200,150,100,100);hollowMask.graphics.endFill();hollowMask.addEventListener(MouseEvent.CLICK,onMaskClick);addChild(hollowMask);private function onMaskClick(event:MouseEvent):voidtrace(maskClick!);private function onBgClick(event:MouseEvent):voidtrace(bgClick!); 后来整理了下,封装了个镂空遮罩组件出来,可以直接设置它的宽高和镂空位置,它会自动重绘。还是上代码吧:?123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188package module.newGuide.viewimport flash.display.Sprite;import flash.events.Event;/* 镂空遮罩工具类* author DOM*/public class HollowMask extends Sprite/* 构造函数* param width 镂空圆形的宽度* param height 镂空圆形的高度*/ public function HollowMask(hollowWidth:Number=100,hollowHeight:Number=100)super();this._hollowWidth = hollowWidth;this._hollowHeight = hollowHeight;this.redrawRequest = true;private var _maskColor:uint = 0x000000;/* 遮罩的颜色*/ public function get maskColor():uintreturn _maskColor;public function set maskColor(value:uint):voidif(_maskColor=value)return;_maskColor = value;redrawRequest = true;private var _maskAlpha:Number = 0.5;/* 遮罩的透明度*/public function get maskAlpha():Numberreturn _maskAlpha;public function set maskAlpha(value:Number):voidif(_maskAlpha=value)return;_maskAlpha = value;redrawRequest = true;/* 移动镂空区域到指定的坐标* param x 目标点x坐标* param y 目标点y坐标* param speed 移动速度,单位为像素,若小于等于0,则不执行缓动。*/ public function moveHollowTo(x:Number,y:Number,speed:Number = 0):voidmoveSpeed = speed;if(speed=0)removeMoveEventListener();_hollowX = x;_hollowY = y;drawBackground();elsetargetX = x;targetY = y;addMoveEventListener();/* 缓动事件监听已添加标志 */ private var moveEventAttached:Boolean = false;/* 添加缓动事件监听*/ private function addMoveEventListener():voidif(moveEventAttached)return;moveEventAttached = true;this.addEventListener(Event.ENTER_FRAME,onMoveHollow);/* 移除缓动事件监听*/ private function removeMoveEventListener():voidif(!moveEventAttached)return;moveEventAttached = false;removeEventListener(Event.ENTER_FRAME,onMoveHollow);/* 移动速度,像素 */ private var moveSpeed:Number = 0;/* 目标点x坐标 */ private var targetX:Number = 0;/* 目标点y坐标 */ private var targetY:Number = 0;/* 缓动处理函数*/ private function onMoveHollow(event:Event):voidvar offsetX:Number = targetX - _hollowX;var offsetY:Number = targetY - _hollowY;var distance:Number = Math.sqrt(offsetX*offsetX+offsetY*offsetY);if(distance=0|distance=moveSpeed)_hollowX = targetX;_hollowY = targetY;removeMoveEventListener();else_hollowX += offsetX*moveSpeed/distance;_hollowY += offsetY*moveSpeed/distance;drawBackground();private var _hollowX:Number = 0;/* 镂空区域的x坐标位置*/ public function get hollowX():Numberreturn _hollowX;public function set hollowX(value:Number):voidif(_hollowX = value)return;_hollowX = value;redrawRequest = true;private var _hollowY:Number = 0;/* 镂空区域的y坐标位置*/public function get hollowY():Numberreturn _hollowY;public function set hollowY(value:Number):voidif(_hollowY = value)return;_hollowY = value;redrawRequest = true;private var _hollowWidth:Number = 100;/* 镂空圆形区域宽度*/public function get hollowWidth():Numberreturn _hollowWidth;public function set hollowWidth(value:Number):voidif(_hollowWidth=value)return;_hollowWidth = value;redrawRequest = true;private var _hollowHeight:Number = 100;/* 镂空圆形区域高度*/public function get hollowHeight():Numberreturn _hollowHeight;public function set hollowHeight(value:Number):voidif(_hollowHeight=value)return;_hollowHeight = value;redrawRequest = true;private var _width:Number = 100;override public function get width():Numberreturn _width;override public function set width(value:Number):voidif(_width=value)return;_width = value;redrawRequest = true;private var _height:Number = 100;override public function get height():Numberreturn _height;override public function set height(value:Number):voidif(_height = value)return;_height = value;redrawRequest = true;private var _redrawRequest:Boolean = false;/* 需要重绘背景的标志*/private function set redrawRequest(value:Boolean):voidif(_redrawRequest=value)return;_redrawRequest = value;addEventListener(Event.ENTER_FRAME,onEnterFrame);/* 延迟一帧来集中处理,减少不必要的重绘次数*/private function onE
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026届重庆市大渡口区化学九上期末综合测试试题含解析
- 知情同意告知培训
- 2026届新疆伊犁州名校化学九上期中经典试题含解析
- 2026届福建省福州市台江区化学九年级第一学期期中质量检测试题含解析
- 2026届内蒙古鄂尔多斯附属学校化学九上期中调研模拟试题含解析
- 2025年炉外精炼工职业技能考试题库及答案(完整版)
- 2026届山东省德州七中学九上化学期中经典试题含解析
- 2026届吉林省长春市第一五三中学九年级化学第一学期期中考试试题含解析
- 夫妻个人债务合同范本8篇
- 类第号上海证券交易所证券投资咨询协议
- 2025四川安和精密电子电器股份有限公司招聘NPI工程师1人备考练习题库及答案解析
- 9 古代科技 耀我中华 课件(共2课时) 部编版道德与法治五年级上册
- 潍坊市2026届高三开学调研监测考试数学试题及答案
- 力帆集团摩托车营销策略优化研究:基于市场竞争与消费者洞察
- 2025喀什经济开发区兵团分区招聘(10人)考试参考试题及答案解析
- 2025江西南昌市西湖城市建设投资发展集团有限公司及下属子公司招聘40人考试参考试题及答案解析
- 2025年体育组织行业研究报告及未来行业发展趋势预测
- 2024年永州市工会社会工作者招聘笔试真题
- 推进文旅医养融合发展的策略及实施路径
- 弹跳的小球教学课件
- 2025年山东快递工程专业职称考试(快递设施设备知识·技术员、助理工程师)历年参考题库含答案详解(5卷)
评论
0/150
提交评论