在AS3中使用colormatrix着色 - 请帮忙!

时间:2011-07-06 01:45:17

标签: actionscript-3

我试图在我的太空游戏中为飞来飞去的物体着色时遇到了很大的问题。

当我射击并击中它们时 - 受影响的敌人会眨眼。图形是预渲染的(即,旋转阵列和功能,其中存储/计算对象的度数及其适当的旋转以获得更好的性能)。

所以 - 我的想法是通过附加着色功能来增强旋转功能;但有色和旋转的物体应与正常旋转的物体分开存放。为此,我创建了一个嵌套数组: 在第一行中有一个对象的360度旋转图形,在第二行中有360度旋转和着色对象的图形。

问题:着色有效,但不会旋转(始终为0度)。请帮助我 - 我几个小时都在弄清楚为什么它不起作用所以我放弃了。如果有人能找到问题会很酷!非常感谢你!

public function createRotationWithColorBlitArrayFromBD(sourceBitmapData:BitmapData, inc:int, offset:int = 0):Array
{
    trace("sourceBitmapData.width=" + sourceBitmapData.width);
    trace("sourceBitmapData.height=" + sourceBitmapData.height);
    tileList = [];
    tileListSec = [];
    levelArray = [];
    var rotation:int = offset; 

    while (rotation < (360 + offset))
    {
        var angleInRadians:Number = Math.PI * 2 * (rotation / 360);
        var rotationMatrix:Matrix = new Matrix();

        rotationMatrix.translate(-sourceBitmapData.width * .5, -sourceBitmapData.height * .5);
        rotationMatrix.rotate(angleInRadians);
        rotationMatrix.translate(sourceBitmapData.width * .5, sourceBitmapData.height * .5);

        var matrixImage:BitmapData = new BitmapData(sourceBitmapData.width, sourceBitmapData.height, true, 0x00000000);

        matrixImage.draw(sourceBitmapData, rotationMatrix);
        tileList.push(matrixImage.clone());

        var colorMatrix:ColorMatrixFilter = new ColorMatrixFilter (
                                [1, 0, 0, 0, 0,
                                 0, 0, 0, 0, 0,
                                 0, 0, 0, 0, 0,
                                 0, 0, 0, 1, 0]);

        matrixImage.applyFilter(sourceBitmapData, sourceBitmapData.rect, point0, colorMatrix);

        tileListSec.push(matrixImage.clone());

        rotation += inc;

        matrixImage.dispose();
        matrixImage = null;
        rotationMatrix = null;
    }

    levelArray = [tileList, tileListSec];
    return(levelArray);
}

1 个答案:

答案 0 :(得分:1)

当您想要将滤镜应用于源图像的旋转版本时,您似乎正在将滤镜应用于源图像。

如果仔细查看BitmapData的文档,应用过滤器函数会执行以下操作:

获取源图像和过滤器对象并生成过滤后的图像。

http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/BitmapData.html#applyFilter

您的应用过滤器调用正在写入您在draw()函数中执行的矩阵变换,其中包含源图像的新的未旋转副本。 applyFilter()就像draw一样,除了它应用过滤器而不是变换矩阵。在这种情况下,您将变换矩阵应用于matrixImage.draw()(旋转),然后使用matrixImage.applyFilter()(颜色)将数据写入。

<强>解 一个快速的解决方案是进行以下更改:

matrixImage.applyFilter(matrixImage, matrixImage.rect, point0, colorMatrix);

这有matrixImage在变成旋转的图像之后将颜色过滤器应用于自身。

BTW:在这种情况下,我认为你不需要有两个matrixImage对象的clone()。只是applyFilter()产生的最终对象应该足够了,因为它是源和过滤器都在一个。但是您可能需要将它们用于尚未发布的其他游戏逻辑。

注意: 此解决方案的唯一问题是以下性能问题:(来自admap docs for BitmapData.applyFilter())

如果BitmapData对象和指定为sourceBitmapData参数的对象是同一对象,则应用程序使用该对象的临时副本来执行过滤器。为获得最佳性能,请避免这种情况。

http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/BitmapData.html#applyFilter

实例化这些临时副本非常耗费资源,因此只需实例化一个缓冲区对象并重新使用它就会快得多。如果您发现性能问题,最好创建第三个BitmapData对象作为源和过滤器之间的缓冲区。在这种情况下,您将拥有3个bitmapData对象,而不仅仅是sourceBitmapDatamatrixImage