【问题标题】:AS3 transparent png collision detection against a sprite针对精灵的 AS3 透明 png 碰撞检测
【发布时间】:2014-04-16 12:31:34
【问题描述】:

我在这里,因为我目前正在为我的 AS3 应用程序进行碰撞检测。 我正在加载一个位图,它代表一个房间 - 它有边界(墙壁),其余部分是透明的(地板)。然后我创建一个内部有一个圆圈的精灵。

我希望我的精灵在这些边界内移动并停在墙上,我能够实现其背后的逻辑,我要求的是一种检测与墙壁碰撞的方法,我的整个房间都是一个位图,所以我猜我会检查与这个位图的碰撞,但不幸的是它也计算了透明部分。

我已经对此进行了谷歌研究,但我只发现非常复杂的系统无论如何都无法工作。我这样做是出于学习目的,所以我想知道如何自己实现它。

因此,我想问是否有人可以向我提供一段代码,只检查位图的非透明部分是否存在冲突? (或者我应该将此 png 作为矢量加载?怎么做?)。

我也在旋转我的“圈子”,所以我想这也应该考虑在内。我假设我应该对位图进行位图检查,而不是对位图进行精灵检查?

我根本没有冲突的工作代码,所以我不会提供任何代码。

我是否应该提供更多信息,请告诉我。

提前致谢!

@编辑

这是我的功能代码,它属于房间类。

public function detectCollisionWith(obj:Sprite):Boolean
    {
        var _bitmapData:BitmapData = new BitmapData(obj.width, obj.height, true, 0);
        _bitmapData.draw(obj);
        var _bitmap:Bitmap = new Bitmap(_bitmapData);
        if (_bitmapData.hitTest(new Point(_bitmap.x, _bitmap.y), 255, this.bitmap, new Point(this.x, this.y), 255))
            return true;
        return false;
    }

【问题讨论】:

    标签: actionscript-3 flash bitmap collision-detection


    【解决方案1】:

    当它们都是位图时,您可以使用BitmapData hitTest() 轻松检查这一点。

    AdobebitmapData hitTest()

    在一个位图图像和一个位图图像之间执行像素级命中检测 点、矩形或其他位图图像。命中定义为 一个点或矩形在一个不透明像素上的重叠,或两个 重叠的不透明像素。没有拉伸、旋转或其他 命中测试时考虑任一对象的变换 执行。


    现在举例说明如何实现它。如果你把你的精灵变成位图:

    var spriteBmd:BitmapData = new BitmapData( mySprite.width, mySprite.height, true, 0 );
    spriteBmd.draw( mySprite ); //get the sprite asset
    var spriteBitmap:Bitmap = new Bitmap( spriteBmd ); //create the bitmap to use
    

    然后您可以对两个位图运行hitTest(),而不考虑透明部分:

    if ( spriteBitmap.bitmapData.hitTest( new Point( mySprite.x, mySprite.y ), 
         255, levelBitmap, new Point( levelBitmap.x, levelBitmap.y ), 255 ) ) {
        trace("Collision detected");
    }
    

    这仅检查位图的不透明部分是否存在冲突。如果您想增加允许检测的透明度,可以调整 if 语句中的值255

    【讨论】:

    • 好吧,这看起来很简单,但有一件事确实让我感到困惑,为什么我需要传递这些位图的 x 和 y?这是否意味着它只测试 1 个点(像素),我需要遍历两个位图的所有点?
    • 不,您不需要发送所有点,只需发送位图的 x 和 y。这些点只是告诉它从哪里开始和在哪里结束,如果你传入显示对象,算法将筛选它们各自的边界。或者,您可以将它们的左上角点传递到右下角边界。
    • 好的,我会试一试,然后带着一些结果返回这里(希望是积极的)。性能呢?对于那么大的位图(我将有大约 5000 x 5000“房间”png),它不会显着影响它吗?
    • 就性能而言,任何碰撞测试都非常昂贵。特别是使用位图的这个是最昂贵的,因为它考虑了透明度。所以大小肯定会起作用,但由于您只是检查 2 个位图,它可能并不可怕。但是请注意,bitmapdata 有一个最大尺寸,“...... BitmapData 对象的最大尺寸是宽度或高度 8,191 像素,并且像素总数不能超过 16,777,215 像素。(因此,如果 BitmapData 对象是 8,191 像素宽,它只能是 2,048 像素高。)”在 FP9 和更早的版本中更低。
    • 好吧,所以我想我必须将我的图像分割到某些房间,甚至更好。然后我可以用 hitTestObject 检查我的精灵是否在房间的边界内,然后执行位图测试。就 fps 不会明显下降而言,我很高兴。
    【解决方案2】:

    简单的房间?是简单的矩形吗?因此,我建议通过检查预定义矩形中的点来计算碰撞。创建矩形,在圆的半径上插入它的大小,并检查圆心是否在矩形内

    //Some room
    var roomBounds:Rectangle = new Rectangle(0, 0, 700, 500);
    const circleRadius:int = 10;
    var collisionBounds: Rectangle = new Rectangle(circleRadius, circleRadius, roomBounds.width - 2*circleRadius, roomBounds.height - 2*circleRadius);
    
    //Check if center of circle inside of collisionBounds
    //For example you have point with name circlePosition
    //collisionBounds.containsPoint(circlePosition)
    if(!collisionBounds.contains(circleX, circleY)){
        trace("Houston! We have collision here!");
    }
    

    【讨论】:

    • 很遗憾不是,这是更复杂的房间,嗯,它不止一个房间可以提供完整的信息,但我现在尝试在我的第一个房间工作,所以我可以在墙上停下来。
    【解决方案3】:

    多年前就这样做了...但是如果我没记错的话,您可以解决创建具有墙壁矢量形状的 MC 的问题(将其放置在墙壁下方)并检查与它的碰撞而不是与位图。

    【讨论】:

    • 好极了,也许可以,但是如何将图像的矢量放置在 mc 上?
    • 不是真的,绘制它太复杂了,需要很长时间,还有墙壁我还有其他对象用于最终产品,它们都必须从 png 映射。我已经设法让它与AirBag lib 一起工作,但我不得不放弃它,因为它在无法捕捉的碰撞中很脆弱 - 没有明显的原因我有时会穿过墙壁或降落在上面(然后有一个有趣的当我试图摆脱它时的事情)。所以它可以满足我的需要(读取具有透明度的 png),但有时不会让我弹跳或停止。
    • 过长就算过form illustrator,把位图转成曲线,去掉透明部分再flash导入?
    • 哦,我想以编程方式绘制它!因为我使用 corel 制作了它,所以我将它作为矢量,但我不知道我应该使用什么文件类型? .svg?可以加载到flash吗?
    • 您可以导入多种格式的矢量: .ai .swf .dxf .fxg 如果 corel 无法导出这些格式,您肯定会找到一些转换器
    猜你喜欢
    • 2013-05-04
    • 1970-01-01
    • 2019-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    相关资源
    最近更新 更多