关于tink的碰撞检测类【2】

article/2025/8/28 9:08:34

分析算法的思路:

 

Step1:假设stage(黑色)上有4个显示对象red_mc,green_mc,blue_mc,yellow_mc,层级关系是stage>root>red_mc,stage>root>yellow_mc>blue_mc>green_mc。要检测碰撞的对象是red_mc和green_mc。如图


                                  图1

 

补充约定:为方便表述,这里约定显示对象的“初始状态”为相对父级容器坐标系未进行旋转,缩放,即对象的transform.matrix对象是[a=1,b=0,c=0,d=1]。

 

Step2:一开始,图1中的4个mc都处于初始状态。但这样的碰撞检测不考验算法,因此对它们做缩放,旋转,平移处理(我直接在flashIDE里完成的),使得red_mc和green_mc的空间位置足够复杂。如图:



                                   图2
补充知识:draw()方法的一个细节

  如下代码(文档类):
   varbmd1:BitmapData = new BitmapData(150,150);
   bmd1.draw(red_mc);
   varbmp1:Bitmap = new Bitmap(bmd1);
   this.addChild(bmp1);

  若red_mc处于初始状态(即图1中的red_mc),效果如下:



                                   图3
十分正常。但是,若用同样地代码来draw变形后的red_mc(即图2中的red_mc),会是什么样子呢?图2中red_mc尺寸太大,这块儿150*150的白色像素会不会只能draw入red_mc的一部分呢?效果如下:


                                   图4

看来,仍旧是以初始状态的red_mc为绘制源。

这就是draw(X)方法的一个细节:不管X怎样变形,平移,都选取X的初始状态作为绘制源。此外,当X处于层层容器嵌套之下时(green_mc就是这种情况),不管它n多父级的变形操作对X形状产生怎样影响,draw也一样选取X的初始状态为绘制源。

 

Step3:前两步作为准备,现在开始碰撞检测的第一步,利用flash自带的hitTestObject()函数做预判断。若这一步判断false肯定没戏了。

补充知识:

1.hitTestObject()是基于AABB包围体的碰撞检测,即检测虚线框的碰撞。(red_mc的虚线框看似并未仅包住red_mc,这是因为red_mc


                                 图5

进行过旋转变换。)

2.hitTestObject()检测碰撞时,并不关心对象是否在显示列表内。这点很重要。

 

Step4.通过上步的预判断,再进一步检测:获取两个包围体的交叠矩形区域,用rect1存储相关信息(x,y,width,height),判断rect1区域内red_mc和green_mc是否有像素重叠。若true便碰上了。

补充知识:显示对象的matrix属性

matrix本身的a,b,c,d没什么好说,这里记下matrix操作的细节。

1.red_mc.transform.matrix,这个记录矩阵(习惯称它记录矩阵,文档上称“变换矩阵”),是red_mc相对于父级容器坐标系的记录矩阵。就像通常所说red_mc.x也是red_mc相对于父级坐标系的x轴偏移。

 

2.要想获得red_mc相对于再上一级,即parent.parent的记录矩阵,该如何呢?直接用parent的matrix乘上red_mc的matrix就好了。

 

3.若想获取red_mc相对于stage的记录矩阵呢?理论上是root.transform.matrix*........(各级父容器的矩阵逐级相乘)......*red_mc.transform.matrix。很累,flash为此提供了concatenatedMatrix属性,就是显示对象相对于stage的记录矩阵。(矩阵乘法是不能用*号的,应该是concat,我是想写快点儿)

 

4.假若要获取red_mc相对于root的记录矩阵呢?直接逐级相乘没问题。不过,concatenated属性提供了一个简洁思路------varrootM:Matrix=root.transform.matrix.clone();

         var rootM1:Matrix=red_mc.transform.concatenatedMatrix;

         rootM.invert();//取得root的逆矩阵

          rootM1.concatenatedMatrix.concat(rootM);//这样,rootM1就转化为相对于root的

 

5.matrix的concat()方法似有bug

当a,d任意为0时,计算的结果就不大对,例如下面两个矩阵

var A:Matrix=newMatrix(1,1,2,2,0,0);

var B:Matrix=newMatrix(0,0,1,1,1,0);

A.concat(B);

trace(A);//输出的ty不是2,我用笔算了几遍,ty都是2

当a,d都不为0时,计算结果没有问题,以后还是放心用吧,因为a,d任意为0,显示对象便不存在了,应不会存在这种情况。

自己写了个矩阵运算类,是很无脑的算法:行对列相乘。很慢很稳妥。是不是内置的矩阵乘法运算采用另外算法,才会有这样的bug呢?

 

6.matrix的concat()方法用起来要小心顺序

A.concat(B),对应的数学式为(矩阵B*矩阵A),矩阵乘法不满足交换律,这个地方跟常规思路又不同(至少跟我想的顺序相反),因此操作时应小心。

 

7.不要直接修改显示对象matrix的a,b,c,d,tx,ty属性,也不要直接应用scale,rotate等操作。因为任何设置都是无效的。

如:varA:Matrix=red_mc.taransform.matrix;//A引用的是red_mc.taransform.matrix的一份拷贝

   A.scale(0.5,0.5);//编译不会报错,但这个操作只修改A,对red_mc.taransform.matrix不造成修改

   A.a=2;//同上

正确的操作是这样的:

  varA:Matrix=red_mc.transform.matrix.clone();

  //varA:Matrix=red_mc.transform.matrix也行

 A.scale(0.5,0.5);

 A.a=2;

 red_mc.tansform.matrix=A;//创建一个合适矩阵,交付给red_mc.transform.matrix引用。

 

8.想对matrix执行scale操作时,用scale方法:

A.sacle(0.5,0.5);

不要写:A.a/=A.b/=2;当matrix的b,c属性不为0,这个操作完成的并不是scale功能。

 

补充知识:BlendMode.DIFFERENCE

文档讲的很清楚:

将显示对象的原色与背景颜色进行比较,然后从较亮的原色值中减去较暗的原色值。此设置通常用于得到更明亮的颜色。

例如,如果显示对象的某个像素的 RGB 值为0xFFCC33,背景像素的 RGB 值为 0xDDF800,则显示像素的结果 RGB 值为 0x222C33(因为 0xFF -0xDD = 0x22,0xF8 - 0xCC = 0x2C,且 0x33 - 0x00 = 0x33)。

 

补充知识:draw()方法的matrix参数有何效果

文档说:用于缩放、旋转位图或转换位图的坐标

下面用代码和效果图说明:

   varbmd1:BitmapData = new BitmapData(200,200);
   bmd1.draw(red_mc,newMatrix(1,0,0,1,0,0));//先不对绘制源做处理,看看正常的样子
   varbmp1:Bitmap = new Bitmap(bmd1);
   this.addChild(bmp1);

                                       图6

很正常,跟图4吻合

再看:

   varbmd1:BitmapData = new BitmapData(200,200);
   bmd1.draw(red_mc,newMatrix(1,0,0,1,110,110));//让绘制源沿x,y轴正方向平移了(110,110)的向量
   varbmp1:Bitmap = new Bitmap(bmd1);
   this.addChild(bmp1);

                                       图7
果然,绘制源相对注册点偏移了(110,110)

再看:

   varbmd1:BitmapData = new BitmapData(200,200);
   bmd1.draw(red_mc,new Matrix(2, 0, 0, 2, 0, 0));
   varbmp1:Bitmap = new Bitmap(bmd1);
   this.addChild(bmp1);


                                            图8
果然缩放了两倍

这便是matrix参数的功能。

问:如何才能draw到图8中舞台下部的red_mc的形貌呢?

答:肉眼看到的red_mc的形貌,是它在stage坐标系中的形貌,因此将draw参数设置为red_mc.transform.concatenatedMatrix,这样绘制源便从初始状态变换到相对舞台的形貌。

试一下:

   varbmd1:BitmapData = new BitmapData(200, 200);
   //为了便于区分,施加一个colorTransform让draw到的像素变为蓝色
   bmd1.draw(red_mc,a_mc.transform.concatenatedMatrix,newColorTransform(1,1,1,-255,-255,255));
   varbmp1:Bitmap = new Bitmap(bmd1);
   this.addChild(bmp1);


                                         图9

什么也没有?因为像素块太小了,red_mc经过矩阵变换,已经跑到了它外面去。

将像素块增大,看看:

   varbmd1:BitmapData = new BitmapData(300, 300);
   //为了便于区分,施加一个colorTransform让draw到的像素变为蓝色
   bmd1.draw(a_mc,a_mc.transform.concatenatedMatrix,newColorTransform(1,1,1,1,-255,-255,255,255));
   varbmp1:Bitmap = new Bitmap(bmd1);
   this.addChild(bmp1);


                                        图10
这下好啦!很准。

但,假如像素块儿尺寸因为某种原因不能修改,该怎么办?那就再折磨draw()方法的matrix参数,让red_mc平移到舞台原点:

   varbmd1:BitmapData = new BitmapData(200, 200);
   //为了便于区分,施加一个colorTransform让draw到的像素变为蓝色
   var m1:Matrix= a_mc.transform.concatenatedMatrix;
   m1.tx += 0 -m1.tx;
   m1.ty += 0 -m1.ty;
   bmd1.draw(a_mc,m1,newColorTransform(1,1,1,1,-255,-255,255,255));
   varbmp1:Bitmap = new Bitmap(bmd1);
   this.addChild(bmp1);

效果:

                                           图11

就是要这个样子。

 

刚才说到Step4:获取两个包围体的交叠矩形区域,用rect1存储相关信息(x,y,width,height),判断rect1区域内red_mc和green_mc是否有像素重叠。如图:

               

                                           图12
判断rect1区域内red_mc和green_mc是否有像素重叠的思路:

new出来一块儿跟rect1等大的黑色像素块。用一种colorTransform去drawrect1区域内的red_mc,再用另一种colorTransform去draw rect1区域内的green_mc,同时采用blendMode.DIFFERENCE混合模式,一旦出现特定颜色,则有像素重叠。

 

至于如何准确的draw到rect1区域内的red_mc/green_mc的像素,在补充里已经给出思路。

现在再看tink的那个类应该很简单了。并且,个人认为他的类存在一些错误,下篇讨论

http://chatgpt.dhexx.cn/article/FqkXsoPA.shtml

相关文章

tkinter:Toplevel

一、概述 Toplevel 组件可以提供单独的容器。 二、代码 import tkinter as tk# 主顶层 win tk.Tk() win.title("主窗口") win.geometry("400x200") tk.Label(win, text"Toplevel-主窗口").pack(pady20)# 子顶层1 依赖于主窗口;如…

$nextTick

$nextTick ● Vue 是异步渲染 ● data 改变后&#xff0c;DOM不会立刻渲染 ● $nextTick 会在 DOM 渲染之后被触发&#xff0c;以获取最新 DOM 节点 先看不用nextTick的情况 <template><div><button click"add">添加3项目</button><…

stick to it

无论何种选择&#xff0c;坚持才是最美的荡气回肠&#xff0c;加油&#x1f4aa; 你大好青春&#xff0c;你怕什么&#xff0c;往前跑&#xff01;

ticklength

设置图片刻度线长度 ‘ticklength’ 0.05 set(gca,xminortick,on); set(gca,ticklength,[0.05 0.025]); set(gca,tickdir,out);x1:8; plot(x) set(gca,‘xminortick’,‘on’);%style 5 set(gca,‘ticklength’,[0.05 0.025]);%style 6 set(gca,‘tickdir’,‘out’);%style …

如何下载免费版的PDF编辑器

想要将PDF文件进行编辑的方法机器是很简单只要我们利用好PDF编辑器就可以轻松的将他进行操作&#xff0c;但是将PDF文件进行编辑的软件大部分的都不是免费的&#xff0c;想要将PDF文件进行免费使用的话需要我们如何去进行下载&#xff1f;小编就向你你们简单讲解一下如何去进行…

迅捷CAD格式转换器专业版

迅捷CAD编辑器是一款应用于图纸DWG格式文件的编辑软件&#xff0c;主要为DWG、DXF等文件格式图纸提供浏览、编辑功能 迅捷CAD转换器支持功能 PDF转CAD CAD转PDF CAD转JPG CAD转PNG CAD转SVG CAD版本转换 DWG转DXF DXF转DWG 本版本已经破解&#xff0c;直接安装以后打开安装就使…

PDF转换器汉化版

PDF转换器汉化版 作为一款快捷高效的PDF阅读转换软件——迅捷PDF转换器(PDF转换器汉化版)全中文界面&#xff0c;高速、快捷、功能强大。目前包括PDF转Word、Excel、PDFTXT、PPT、HTML、EPUB、Office转PDF八种格式转换&#xff0c;给用户转换文本格式提供了多种选择性。同时&am…

pdf类型转换器打印机

pdf类型转换器打印机 商业活动期间经常需要利用平板电脑阅览文件&#xff0c;为了使打印效果更好&#xff0c;阅读效果更佳。就会选用专业迅捷pdf类型转换器打印机进行打印&#xff0c;来实现多种格式打印效果。 什么是pdf类型转换器打印机?迅捷pdf类型转换器打印机(pdf类型转…

PDF编辑器中文版免费下载哪里可以下载?

PDF文件格式是一种高质量的文件格式&#xff0c;也可以说是用的比较多的格式。很多PDF编辑器中文版免费下载下来的软件都无法打开PDF文件&#xff0c;有些是打开了PDF文件但是无法去进行编辑PDF文件。使用迅捷PDF编辑器就可以完成对文件的编辑&#xff01; 1.首先我们进入官网的…

编辑实测:迅捷PDF转换器怎么将PDF转换成JPG

网络上有很多的PDF转换成JPG的问题&#xff0c;而自然也有很多的解决方法&#xff0c;编辑统计表明&#xff0c;PDF转换成JPG使用迅捷PDF转换器进行相应的转换的用户不胜枚举。这些是不是刷出来的数字?迅捷PDF转换器真的有那么好用吗?在这里&#xff0c;随编辑一起来亲自测试…

在线PDF编辑链接

一个在线网站&#xff0c;足以解决PDF编辑问题 迅捷PDF转换器免费版——直接看图链接: 上图中这么多的PDF编辑功能还不能够解决大家的PDF编辑问题吗&#xff01; PS&#xff1a;唯一的缺点&#xff0c;网站中也明确提到了&#xff0c;超出2M的文件&#xff0c;无法进行上传&am…

PDF转换器下载

PDF转换器下载 PDF是现今非常流行的阅读格式&#xff0c;借助网络平台&#xff0c;正规的PDF格式的电子书已问世&#xff0c;大家可以借助PDF高质量的阅读性和效果性&#xff0c;来搜集自己的喜欢的资料和书籍。但PDF文件格式也并不是没有缺点&#xff0c;无法编辑和修改是PDF最…

pdf在线翻译_网页版pdf转换器|pdf转换word免费

之前分享了一款 pdf转换 软件&#xff0c;后台看到下载数据非常不错&#xff0c;由此看来这类软件很受欢迎。今天给大家在分享几个网页版的pdf转换工具&#xff0c;每一个功能都非常全面。 一. 迅捷PDF转换器(https://app.xunjiepdf.com/) 该网站支持PDF转Word、Word转PDF、PDF…

pdf 模版 汉字和数字_PDF怎么添加数字签名?这款编辑器软件很多人都说好用

PDF文件怎么添加数字签名&#xff1f;其实&#xff0c;要给PDF文件添加数字签名&#xff0c;我们可以选择把这份文件转换成PDF格式的文件&#xff0c;再通过PDF编辑器给这份PDF文件添加数字签名。 那么&#xff0c;给PDF文件添加数字签名&#xff0c;我们可以选择哪一款PDF编辑…

6款强烈推荐的PDF阅读器

1、迅捷PDF编辑器&#xff08;无捆绑、免费、快&#xff09; 总的来说&#xff1a;这是一款国产界面简洁、功能强大的PDF编辑和阅读软件。 软件下载&#xff1a;迅捷PDF编辑器 优点&#xff1a; 1、体积小&#xff0c;安装包区区1.2M大小&#xff0c;没有捆绑&#xff08;难能…

PDF文件编辑并去除水印

我相信很多博友肯定被这个问题烦恼过&#xff0c;并且当初我自己也因为这个事情熬的掉了好几根头发&#xff0c;这件事就是PDF文件编辑过后会留下很严重的水印&#xff0c;并且无法除去&#xff0c;想去除就得花钱购买会员&#xff0c;想白嫖都没有办法&#xff0c;接下来我就为…

如何查找求职简历模板及pdf编辑器去水印

下面介绍三个方法找寻适合自己的简历模板 一、网站&#xff0c;填写简历信息&#xff0c;自动生成模板 社招 https://xyzp.haitou.cc/ https://www.lagou.com/校招 https://www.zhiyeapp.com/二、使用PanDownload下载简历模板 http://pandownload.com/1、安装完成后&#x…

PDF格式转换器下载免费版

目前而言&#xff0c;不少编辑人员在针对PDF和Word文件格式的选择上&#xff0c;绝大多数的情况下更加倾向于后者&#xff0c;其中最为主要的原因还是在于Word文件格式有着 极为优秀的编辑功能。而事实上&#xff0c;要想将PDF文件进行编辑并不是一件简单地事情&#xff0c;这往…

免费PDF阅读器都是坑?这些开源神器我可是恨不得所有人都知道

最近帮我妈妈下了个PDF&#xff0c;但结果发现在手机上看的时候没有自适应&#xff0c;看起来就非常不方便 而我一时间我竟然还没想到帮她装哪个PDF阅读器来解决 于是后来我就好好研究了一下这个问题&#xff0c;今天来分享一下 ▍1 关于PDF阅读器的两点问题 PDF格式太过自…

四款亲试好用的PDF编辑器推荐,看看哪款最适合你

首先&#xff0c;我想说明一点&#xff0c;这几款都不是免费的&#xff0c;我测试过十几款市面上所谓的免费的PDF编辑器&#xff0c;也没有遇到过一款真正免费的PDF编辑器。虽然不是完全免费的&#xff0c;但是很多都是有免费试用期限的&#xff0c;你试用后觉得不错可以再续费…