3

我使用一个非常大的 BitmapData 作为我的平台游戏的路径图,但是我只使用 4 个特定值的像素,而不是 4294967295。

将此位图数据转换为布尔值的 2 个 2D 向量会节省一些内存吗?如果确实如此,那么性能如何,执行以下操作会更快还是更慢:

MapGetPixel(x:int, y:int):int
{
    return MapBoolFirst[x][y] + MapBoolSecond[x][y]*2;
}

而不是位图数据类getPixel32(x:int, y:int):uint

简而言之,我正在寻找一种减小尺寸和/或优化我的 4 色位图数据的方法。

编辑: 使用我的布尔方法显然消耗的内存是位图数据的 2 倍。我想布尔值在内存中占用的内存不止一位,否则就太容易了。所以我正在考虑对 int 进行移位,因此有一个 int 存储几个像素的值,但我不确定这个......</p>

编辑 2: 使用 int bitshifts 我可以将 16 个像素的数据管理到一个 int 中,这个技巧应该可以节省一些内存,即使它可能会影响性能。

4

3 回答 3

1

一个简单的改进是使用 aByteArray而不是BitmapData。这意味着每个“像素”只占用 1 个字节而不是 4 个。这仍然有点浪费,因为每个像素只需要 2 位而不是 8 位,但它比使用 BitmapData 少得多。如果您需要为每个像素存储超过 4 个值,它还为您提供了一些“增长空间”,而无需在以后进行任何重大更改。

ByteArray.readByte()/ByteArray.writeByte()适用于整数,因此使用起来非常方便。当然,调用 writeByte() 时只写入整数的低 8 位。

您设置ByteArray.position为您希望下一次读取或写入开始的点(基于 0 的索引)。

总结一下:将 ByteArray 视为一个一维整数数组,其值为 0-255。

于 2013-11-14T10:54:22.930 回答
1

位移位将是处理它的最优化内存的方式。性能方面,这应该不是太大的问题,除非您需要在每一帧中轮询很多问题。AS 的问题是布尔值是 4 位 :(

正如我所看到的,您可以在不同的情况下处理它:

1) 为命中检测创建一个较低分辨率的纹理,通常可以将其缩小 4 倍 (256x256 --> 64x64)

2)使用某种技术将该数据保存到某种存储中(布尔是最简单的,但如果它太大,那么你需要为它找到另一个解决方案)

3) 做整数解(我以前没有使用过位移,所以我认为这将是一个有趣的挑战,这就是结果)

而且该解决方案比用于布尔的解决方案小得多,也更难理解:/

public class Foobar extends MovieClip {
    const MAX_X:int = 32;
    const MAX_Y:int = 16;

    var _itemPixels:Vector.<int> = new Vector.<int>(Math.ceil(MAX_X * MAX_Y / 32));

    public function Foobar() {
        var pre:Number = System.totalMemory;
        init();
        trace("size=" + _itemPixels.length);
        for (var i = 0; i < MAX_Y; ++i) {
            for (var j = 0; j < MAX_X; ++j) {
                trace("item=" + (i*MAX_X+j) + "=" +  isWalkablePixel(j, i));
            }
        }
        trace("memory preInit=" + pre);
        trace("memory postInit=" + System.totalMemory);
    }

    public function init() {
        var MAX_SIZE:int = MAX_X * MAX_Y;
        var id:int = 0;
        var val:int = 0;
        var b:Number = 0;
        for(var y=0; y < MAX_Y; ++y) {
            for (var x = 0; x < MAX_X; ++x) {
                b = Math.round(Math.random()); //lookup the pixel from some kind of texture or however you expose the items
                if (b == 1) {
                    id = Math.floor((y * MAX_X + x) / 32);
                    val = _itemPixels[id];
                    var it:uint = (y * MAX_X + x) % 32;
                    b = b << it;
                    val |=  b;
                    _itemPixels[id] = val;
                }
            }
        }
    }

    public function isWalkablePixel(x, y):Boolean {
        var val:int = _itemPixels[Math.floor((y * MAX_X + x) / 32)];
        var it:uint = 1 << (y * MAX_X + x) % 32;
        return (val & it) != 0;
    }
}
于 2013-11-14T03:39:36.980 回答
0

Here are the results, I was using an imported 8 bit colored .png by the way, not sure if it changes anything when he gets converted into a BitmapData.

Memory usage :

  • BitmapData : 100%
  • Double Boolean vectors : 200%
  • Int Bitshifting : 12%

So int bitshifting win hands down, it works pretty much the same way as hexadecimal color components, however in that case I store 16 components (pixel values in 2 bits) not the 4 ARGB:

var pixels:int = -1;// in binary full of 1
for (var i:int = 0; i < 16; i++)
    trace("pixel " + (i + 1) +" value : " + (pixels >> i * 2 & 3));

outputs as expected : "pixel i value : 3"

于 2013-11-14T14:57:06.257 回答