Actionscript 3 像素完美碰撞。怎样做? (学习目的)

发布于 2024-09-08 11:51:48 字数 487 浏览 12 评论 0原文

我知道有人为此创建类(即 http://coreyoneil. com/portfolio/index.php?project=5)。但我想学习如何自己做,这样我就可以按照我需要的方式创造我需要的一切。

我读过有关 BitMap 和 BitMapData 的内容。我应该能够将 MovieClips 绘制到位图上,这样我就可以循环像素以查找碰撞。然而,处理偏移量是很奇怪和令人困惑的。它看起来像 MyBitMap.rect 总是 x = 0 和 y = 0...而且我无法找到事物的原始位置...

我我正在考虑首先执行 hitTestObject,然后如果这是肯定的,我将研究影片剪辑矩形之间的交集以进行像素碰撞。 但还有另一个问题(影片剪辑的旋转)......

我需要一些关于如何做到这一点的启示。 请,任何帮助将不胜感激..

I know that there are people out there creating classes for this (ie http://coreyoneil.com/portfolio/index.php?project=5). But I want to learn how to do it myself so I can create everything I need the way I need.

I've read about BitMap and BitMapData. I should be able to .draw the MovieClips onto a BitMap so I could then cycle the pixels looking for the collisions. However, It's weird and confusing dealing with the offsets.. And it seams like the MyBitMap.rect has always x = 0 and y = 0... and I can't seam to find the original position of the things...

I'm thinking of doing a hitTestObject first, then if this was positive, I would investigate the intersection betwen the movieclips rectangles for the pixel collisions.
But then there is also another problem (the rotation of movieclips)...

...I need some enlightment here on how to do it.
Please, any help would be appreciated..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

A君 2024-09-15 11:51:48

如果您使用具有透明度的 BitmapData 对象,则可以使用 BitmapData.hitTest(firstPoint:Point, firstAlphaThreshold:uint, secondaryObject:Object, secondaryBitmapDataPoint:Point = null, secondaryAlphaThreshold:uint = 1):Boolean

您必须从全局坐标更改为本地 BitmapData 坐标,如果旋转,则需要一些数学运算。这很容易实现(在 wiki 上查找仿射变换以获取更多信息):

var coordTransform:Matrix = new Matrix();

coordTransform.rotate(rotationRadians);
coordTransform.translate(x, y);

coordTransform.transformPoint(/* your point */);

If you're using BitmapData objects with transparency you can use BitmapData.hitTest(firstPoint:Point, firstAlphaThreshold:uint, secondObject:Object, secondBitmapDataPoint:Point = null, secondAlphaThreshold:uint = 1):Boolean.

You'll have to change from global coords to the local BitmapData coords which will require a bit of math if it is rotated. That's easily achieved (look up affine transform for more info on wiki):

var coordTransform:Matrix = new Matrix();

coordTransform.rotate(rotationRadians);
coordTransform.translate(x, y);

coordTransform.transformPoint(/* your point */);
满意归宿 2024-09-15 11:51:48

Flash 中像素完美碰撞检测的经典参考是 Grant Skinner 的文章< /a>.它是 AS2,但逻辑与 AS3 相同(如果你用 google 一下,就有可用的端口)。

如果我没记错的话,只要两个测试对象具有相同的父对象,这个特定的实现就可以工作,但这可以修复。

关于 BitmapData x 和 y 值,我知道它可能会令人困惑;然而,它的工作方式对我来说是有意义的。 BitmapData 顾名思义:像素数据。它不是显示对象,不能出现在显示列表中;因此,如果你仔细想想,xy 与 0 不同并没有什么意义。处理这个问题最简单的方法可能是存储源对象(您从中绘制的显示对象)的 (x,y) 偏移量并将其转换到全局坐标空间,以便您可以比较任何对象,无论它们在显示列表中的位置是什么(使用类似 var globalPoint:Point = source.parent.localToGlobal(new Point(source.x,source.y)) 的内容。

A classic reference for pixel perfect collision detection in flash is this Grant Skinner's article. It's AS2, but the logic is the same for AS3 (there are ports available if you google a bit).

If I recall correctly, this particular implementation worked as long as both tested objects had the same parent, but that can be fixed.

About BitmapData x and y values, I understand it could be confusing; however, the way it works makes sense to me. A BitmapData is just what the name implies: pixel data. It's not a display object, and cannot be in the display list; so having x or y different than 0 doesn't really make sense, if you think about it. The easiest way to deal with this is probably storing the (x,y) offset of the source object (the display object you have drawn from) and translate it to the global coordinate space so you can compare any objects, no matter what's their position in the display list (using something like var globalPoint:Point = source.parent.localToGlobal(new Point(source.x,source.y)).

吐个泡泡 2024-09-15 11:51:48

我之前使用过 Troy Gilbert 的像素完美碰撞检测类(改编自 Andre Michelle、Grant Skinner 和 Boulevart),效果非常好(处理旋转、不同的父项等):

http://troygilbert.com/2007/06/pixel-perfect-collision-detection-in-actionscript3/< /a>
http://troygilbert.com/2009/08/pixel-perfect -collision-detection-revisited/

并从那里他还链接到了这个项目(我没有使用过,但看起来确实令人印象深刻):

http://www.coreyoneil.com/portfolio/index.php?project=5

I've previously used Troy Gilbert's pixel perfect collision detection class (adapted from Andre Michelle, Grant Skinner and Boulevart) which works really well (handles rotation, different parents, etc.):

http://troygilbert.com/2007/06/pixel-perfect-collision-detection-in-actionscript3/
http://troygilbert.com/2009/08/pixel-perfect-collision-detection-revisited/

and from there he has also linked to this project (which I've not used, but looks really impressive):

http://www.coreyoneil.com/portfolio/index.php?project=5

灯下孤影 2024-09-15 11:51:48

毕竟我成功了,而且我已经编写了碰撞检测、/碰撞角度和其他附加功能的类。

最令人困惑的过程可能是正确对齐位图以进行比较。当使用draw()方法将一个影片剪辑绘制到一个BitmapData中时,如果我们addChild()相应的Bitmap,我们可以看到它的一部分是不可见的。它似乎只从中心向右和向下绘制,而顶部和左侧部分则远离绘制。解决方案是在绘制方法的第二个参数中给出一个变换矩阵,用于对齐位图并使其全部被绘制。

这是我的类中的一个函数示例,用于创建用于比较的位图:

    static public function createAlignedBitmap(mc: MovieClip, mc_rect: Rectangle): BitmapData{
                var mc_offset: Matrix;
                var mc_bmd: BitmapData;

                mc_offset = mc.transform.matrix;
                mc_offset.tx = mc.x - mc_rect.x;
                mc_offset.ty = mc.y - mc_rect.y;
                mc_bmd = new BitmapData(mc_rect.width, mc_rect.height, true, 0);
                mc_bmd.draw(mc, mc_offset);

                return mc_bmd;
}

为了使用它,如果您在时间轴上,您需要执行以下操作:

className.createAlignedBitmap(myMovieClip, myMovieClip.getBounds(this))

注意 getBounds 的使用,它返回嵌入影片剪辑的矩形。这允许计算偏移矩阵。

此方法与此处显示的方法非常相似 http://www.mikechambers.com/blog/2009/06/24/using-bitmapdata-hittest-for-collision-detection/

顺便说一句,如果这对您来说很有趣,检查我稍后将发布的其他问题。

I managed to do it after all, and I already wrote my class for collision detections,/collisions angle and other extras.

The most confusing process is maybe to align the bitmaps correctly for comparing. When whe draw() a movieclip into a a BitmapData, if we addChild() the corresponding Bitmap we can see that part of it is not visible. it appears to be drawn from the center to right and down only, leaving the top and left parts away from beeing drawn. The solution is giving a transform matrix in the second argument of the draw method that aligns the bitmap and makes it all be drawn.

this is an example of a function in my class to create a bitmap for comparing:

    static public function createAlignedBitmap(mc: MovieClip, mc_rect: Rectangle): BitmapData{
                var mc_offset: Matrix;
                var mc_bmd: BitmapData;

                mc_offset = mc.transform.matrix;
                mc_offset.tx = mc.x - mc_rect.x;
                mc_offset.ty = mc.y - mc_rect.y;
                mc_bmd = new BitmapData(mc_rect.width, mc_rect.height, true, 0);
                mc_bmd.draw(mc, mc_offset);

                return mc_bmd;
}

in order to use it, if you are on the timeline, you do:

className.createAlignedBitmap(myMovieClip, myMovieClip.getBounds(this))

Notice the use of getBounds which return the rectangle in which the movie clip is embedded. This allows the calculation of the offset matrix.

This method is quite similar to the on shown here http://www.mikechambers.com/blog/2009/06/24/using-bitmapdata-hittest-for-collision-detection/

By the ways, if this is an interesting matter for you, check my other question which I'll post in a few moments.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文