如何显示一个位图,它只是AS3中BitmapData的一部分?

时间:2011-05-14 10:33:28

标签: flash actionscript-3 bitmap scroll bitmapdata

我正在为我正在制作的游戏编写一个屏幕滚动条。有一个BitmapData对象,它保存背景图形,但我不想一次在屏幕上显示/渲染它。

例如,我想只显示500x500的数据部分,但整个BitmapData是1000x1000。我想使用 scroll()方法来滚动数据但我的问题是我不能限制在Bitmap上绘制多少BitmapData。我尝试将BitmapData的高度/宽度属性设置为500x500(并绘制所有1000x1000),但是绘制的超出我定义的边界的任何数据都不是真正绘制的。

我考虑的另一个选项是存储一个不同的BitmapData对象,它保存整个数据,然后使用 copyPixels()从它到Bitmap本身使用的那个,虽然我不能用< em> scroll()并且必须使用不同的方法来实现滚动。

提前感谢谁回答。

3 个答案:

答案 0 :(得分:4)

执行此操作的最佳方法是使用CopyPixels()进行blit。基本上你会将一个Bitmap对象添加到舞台大小正确以反映你想要显示的区域,然后你将使用CopyPixels只带来你想要在任何给定时间显示的内容。

var largeBitmap:Bitmap = yourLargeBitmap;
var displayBitmap:Bitmap = new Bitmap(new BitmapData(500, 500));
addEventListener(Event.ENTER_FRAME, loop);

function loop(e:Event):void {
displayBitmap.bitmapData.copyPixels(largeBitmap, new Rectangle(X, Y, 500, 500), new Point());
}

填充X和Y,你就被设定了!

编辑:是的,这需要双倍的内存,因为你在任何给定的时间基本上都在内存中保存了两个位图数据对象 - 但老实说这将是一个小问题。特别是如果您的位图太小,内存占用可以忽略不计。然而,有什么好处的是你正在回避任何类型的对象操作或显示列表争夺 - 这就是主要性能优势的来源。老实说,你做的任何事情都可以正常工作 - 但如果你是部署到移动设备,或最终制作更大的背景,或者其他任何东西,你会看到通过掩蔽或缩放或任何其他技巧的性能增加。据我所知,这通常被认为是最佳实践。 的 /修改

请注意,许多游戏框架(例如Flixel)都内置了blitting引擎。如果你使用blit所有内容而不是使用显示列表,你会获得更好的性能。

答案 1 :(得分:1)

我愿意:

//the rectangle you would like to draw
var rectangle:Rectangle = new Rectangle(100,100,400,500);

var shape:Shape = new Shape();
var matrix:Matrix = new Matrix(1,0,0,1,-rectangle.x, -rectangle.y);
shape.graphics.beginBitmapFill(bitmapData, matrix);
shape.graphics.drawRect(0, 0, rectangle.width, rectangle.height);
shape.graphics.endFill();

然后,您可以通过更改矩形的位置或直接更改矩阵来滚动。

<强>更新 在检查了Myk的答案之后,我惊讶地发现(经过相当快速和宽松的测试)beginBitmapFill实际上比copyPixels更快。我会留下我的测试代码,所以如果你有兴趣可以去看看它:

copyPixels(我得到15-20 fps):

var bmp:BitmapData=new BitmapData(1000, 1000, true, 0);
bmp.perlinNoise(100, 100, 3, 1, true, true);

var arr:Array=new Array();
for (var i:uint = 0; i < 50; i++) {
    var clip:Bitmap = new Bitmap(new BitmapData(500, 500));
    addChild(clip);
    clip.alpha = .05;
    arr.push(clip);
}
var t1:uint = getTimer();
stage.addEventListener("enterFrame", function() {
    trace(getTimer() - t1);
    t1 = getTimer();
    for each(var clip:* in arr) {
        var x:uint=Math.random()*100;
        var y:uint=Math.random()*100;

        clip.bitmapData.copyPixels(bmp,new Rectangle(x,y,500,500), new Point);
    }
});

beginBitmapFill(我得到55-60 fps):

var bmp:BitmapData=new BitmapData(1000, 1000, true, 0);
bmp.perlinNoise(100, 100, 3, 1, true, true);

var arr:Array=new Array();
for (var i:uint = 0; i < 50; i++) {
    var clip:Shape = new Shape();
    addChild(clip);
    clip.alpha = .05;
    arr.push(clip);
}
var t1:uint = getTimer();
stage.addEventListener("enterFrame", function() {
    trace(getTimer() - t1);
    t1 = getTimer();
    for each(var clip:* in arr) {
        var x:uint=Math.random()*100;
        var y:uint=Math.random()*100;

        clip.graphics.clear();
        clip.graphics.beginBitmapFill(bmp,new Matrix(1,0,0,1,-x,-y),false,false);
        clip.graphics.drawRect(0,0,500,500);
        clip.graphics.endFill();
    }
});

答案 2 :(得分:0)

创建形状,将500x500填充的矩形绘制到其中并将其指定给位图的蒙版属性 - 位图将被剪裁为此大小。