【问题标题】:Drawing a bitmap based on a transformed movieclip基于转换后的影片剪辑绘制位图
【发布时间】:2013-04-11 19:10:38
【问题描述】:

我正在绘制影片剪辑的位图,然后将其输入我的 hittest 函数以测试碰撞。但是,我不太确定如何添加到下面的代码中以考虑并为已缩放和/或旋转的电影剪辑绘制位图。下面的代码显然只适用于未转换的影片剪辑。我已经包含在我已经尝试过但没有成功的 cmets 代码中。

将绘制的位图添加到舞台时,无论是否转换相关的影片剪辑,绘制的位图都会被“截断”并错误地绘制 - 似乎只绘制了它的一部分。但是,这不会特别影响对未转换的动画剪辑的碰撞测试,但会对已转换的动画剪辑产生不利影响。

我想要绘制的所有动画剪辑都是通过 graphics 属性创建的。

           //for example: 
            var mymc:MovieClip = new MovieClip();
            var g:Graphics = mymc.graphics;                        
            g.moveTo(0,0);
            g.lineTo(17.5,0);
            g.lineTo(8.75,17.5);
            g.lineTo(-8.75,17.5);
            g.lineTo(0,0);

主要代码:

for each(var mc:MovieClip in impassable) {  

        //var bMatrix:Matrix = new Matrix();

        //bMatrix.scale(mc.scaleX, mc.scaleY);

        //bMatrix.rotate(mc.rotation * (Math.PI/180));

        var bData:BitmapData = new BitmapData(mc.width, mc.height, true, 0);

        //bData.draw(mc, bMatrix);

        bData.draw(mc);

        var bitmap:Bitmap = new Bitmap(bData);

        bitmap.x = mc.x;
        bitmap.y = mc.y;


        var HitTest:Number = newCollision(bitmap, centerX, centerY, 13.7);

有什么想法吗?谢谢

【问题讨论】:

  • 有没有可能有一个你不改造的父MC,然后用draw()来绘制它的内容?
  • @amy。嗯,我之前尝试过,但它似乎只是从字面上删除了子 MC。我确定这可以通过 Matrix 完成,但我不确定如何。
  • 我对@9​​87654321@ 的回答有一个代码sn-p,它创建一个转换后的DisplayObjectBitmap 克隆。听起来它可能会满足您的需求? (虽然显然你可以摆脱在舞台上定位Bitmap 的额外步骤)。
  • @DavidMear 非常感谢您提供的深入而详尽的代码。这似乎正是制作转换后的影片剪辑的精确副本并正确对齐它所需要的。但是,尽管克隆正确,但位图似乎仍然无法与我的碰撞功能一起使用。无论如何,如果我无法弄清楚,那将是一个不同的问题。如果您将此放入答案中,我将接受此作为我的答案。谢谢!
  • 太棒了!我已经发布了一个答案,但如果它仍然不起作用,如果您将碰撞功能添加到问题中,我会很感兴趣。如果您在我之前的回答中尝试使用该函数的第二个版本,它会重新缩放位图以取消舞台缩放,这可能会导致问题。

标签: actionscript-3 flash bitmapdata


【解决方案1】:

此函数将创建DisplayObjectBitmapData 克隆,同时考虑其变换矩阵,尽管它不考虑位图过滤器。 (基于this 的回答。)

function createBitmapClone(target:DisplayObject):BitmapData {
    var targetTransform:Matrix = target.transform.concatenatedMatrix;
    var targetGlobalBounds:Rectangle = target.getBounds(target.stage);
    var targetGlobalPos:Point = target.localToGlobal(new Point());

    // Calculate difference between target origin and top left.
    var targetOriginOffset:Point = new Point(targetGlobalPos.x - targetGlobalBounds.left, targetGlobalPos.y - targetGlobalBounds.top);

    // Move transform matrix so that top left of target will be at (0, 0).
    targetTransform.tx = targetOriginOffset.x;
    targetTransform.ty = targetOriginOffset.y;

    var cloneData:BitmapData = new BitmapData(targetGlobalBounds.width, targetGlobalBounds.height, true, 0x00000000);
    cloneData.draw(target, targetTransform);

    return cloneData;
}

【讨论】:

  • 根据您的评论进行了更多测试后,我认为问题可能是由于getBounds 返回的区域大于对象的实际像素大小。这在视觉上并不重要,但显然会破坏碰撞检查。我有一些部分修复,但如果我找到可靠的解决方案,我会更新我的答案。
  • 认为此编辑可能会有所帮助。我调整了targetOriginOffset 以消除getBoundsDisplayObject 的实际大小之间的差异,并将BitmapData 更改为只使用目标的大小。我曾假设这些值是相同的,但显然它们不是。
  • 谢谢,你所说的 getBounds 实际上让我意识到我的碰撞函数中的一个愚蠢错误,我使用未转换的影片剪辑的边界而不是克隆位图的边界来测试碰撞...碰巧我在您以前的答案中使用了该函数的第二个版本,但是这两个答案都可以正常工作,但此处提供的答案却没有?我想我会使用您先前答案的第一个功能。谢谢!
  • 啊,我错误地通过克隆父对象来测试这个,这会使BitmapData 太大。简直让自己迷茫!我已经回滚了编辑,但很高兴原来的答案仍然有帮助。
【解决方案2】:

当您在 Matrix 上调用连续变换时,顺序非常重要,而且确实会搞砸。

幸运的是,有一个辅助方法可以让您一次性指定平移、旋转和缩放并避免这些问题 - createBox

对于你的情况,是这样的:

var matrix:Matrix = new Matrix();
matrix.createBox(mc.scaleX, mc.scaleY, mc.rotation*Math.PI/180, 0, 0);

(两个零用于 x 和 y 平移)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-28
    • 2011-01-22
    • 2012-06-07
    • 2011-11-02
    • 1970-01-01
    相关资源
    最近更新 更多