有没有人有一个很好的解决方案,在AS3中创建一个基于BitmapData的滚动条,可以在向左和向右滚动时包裹图像(并且还支持任意速度,而不是每个循环一个像素)?我正在尝试编写一个快速轻量级的滚动条,它只能使用BitmapData.copyPixels()和BitmapData.scroll()。
到目前为止,我想出了这段代码:
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.KeyboardEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.ui.Keyboard;
[SWF(width="800", height="480", frameRate="60", backgroundColor="#000000")]
public class Main extends Sprite
{
private var _source:BitmapData;
private var _sourceWidth:int;
private var _buffer:BitmapData;
private var _canvas:BitmapData;
private var _rect:Rectangle = new Rectangle();
private var _point:Point = new Point();
private var _xOffset:int = 0;
public function Main()
{
_source = new Picture();
_sourceWidth = _source.width;
_rect.width = _source.width;
_rect.height = _source.height;
_canvas = new BitmapData(_source.width, _source.height, false, 0x000000);
_canvas.copyPixels(_source, _rect, _point);
_buffer = _canvas.clone();
var b:Bitmap = new Bitmap(_canvas);
b.x = stage.stageWidth / 2 - _canvas.width / 2;
b.y = 10;
addChild(b);
stage.addEventListener(KeyboardEvent.KEY_DOWN, function(e:KeyboardEvent):void
{
if (e.keyCode == Keyboard.RIGHT) scroll(10);
else if (e.keyCode == Keyboard.LEFT) scroll(-10);
});
}
private function scroll(speed:int):void
{
/* Update offset. */
_xOffset -= speed;
/* Reset rect & point. */
_rect.width = _sourceWidth;
_rect.x = 0;
_point.x = 0;
/* Reached the end of the source image width. Copy full source onto buffer. */
if (_xOffset == (speed > -1 ? -(_sourceWidth + speed) : _sourceWidth - speed))
{
_xOffset = -speed;
_buffer.copyPixels(_source, _rect, _point);
}
/* Scroll the buffer by <speed> pixels. */
_buffer.scroll(-speed, 0);
/* Draw the scroll buffer onto the canvas. */
_canvas.copyPixels(_buffer, _rect, _point);
/* Update rect and point for copying scroll-in part. */
_rect.width = Math.abs(_xOffset);
/* Scrolls to left. */
if (speed > -1)
{
_rect.x = 0;
_point.x = _sourceWidth + _xOffset;
}
/* Scrolls to right. */
else
{
_rect.x = _sourceWidth - _xOffset;
_point.x = 0;
}
trace("rect.x: " + _rect.x + " point.x: " + _point.x);
/* Copy the scrolling-in part from source to the canvas. */
_canvas.copyPixels(_source, _rect, _point);
}
}
}
您可以使用光标键向左/向右滚动。仅当图像环绕一次时,滚动才能正常工作。如果决定在它们之间的某个地方向相反方向滚动,则会弄乱坐标以从滚动缓冲区复制该区域。基本上这个块需要工作:
/* Update rect and point for copying scroll-in part. */
_rect.width = Math.abs(_xOffset);
/* Scrolls to left. */
if (speed > -1)
{
_rect.x = 0;
_point.x = _sourceWidth + _xOffset;
}
/* Scrolls to right. */
else
{
_rect.x = _sourceWidth - _xOffset;
_point.x = 0;
}
... rect.x和point.x需要在这里根据滚动方向进行不同的设置,但我不知道如何在没有完全过度复杂的整个循环的情况下。任何有关更好实施的提示或想法都将受到欢迎!
答案 0 :(得分:0)
这个问题刚才被问过,但由于它仍未得到答复,我将加上我的两分钱。
我只需要为我正在进行的项目解决这个问题并提出以下解决方案。一般的想法是将位图绘制到显示对象的图形中,并使用矩阵变换来控制位图数据上视口的x和y坐标。
public class Example extends Sprite
{
private var vx:Number;
private var vy:Number;
private var coords:Point;
private var shape:Shape;
private var bitmap:Bitmap;
private var bmd:BitmapData;
public function Example()
{
vx = 1.5;
vy = -3.0;
coords = new Point();
shape = new Shape();
bitmap = new Image(); // image, in my case is an embedded image
bmd = bitmap.bitmapData;
addChild(shape);
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(event:Event):void
{
coords.x += vx;
coords.y += vy;
// this is important!
// without it, bitmap size constraints are reached and scrolling stops
coords.x %= bitmap.width;
coords.y %= bitmap.height;
shape.graphics.clear();
shape.graphics.beginBitmapFill(bmd, new Matrix(1, 0, 0, 1, coords.x, coords.y), true, true);
shape.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
shape.graphics.endFill();
}
}
现在你可以更新x&amp;用于滚动位图的Point对象的y值。您可以轻松地将速度,加速度和摩擦力添加到等式中,以使滚动更加动态。