2013-02-23 84 views
1

有沒有人有一個很好的解決方案,在AS3中創建一個基於BitmapData的滾動條,可以在向左和向右滾動的同時環繞圖像(並且還支持任意速度,而不是每個循環一個像素)?我試圖編寫一個快速輕量級的滾動條,它只能使用BitmapData.copyPixels()和BitmapData.scroll()。AS3 Wrapped-around BitmapData Scrolling?

到目前爲止,我想出了這個代碼:

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

@Amy Blankenship這是一個類似的問題,但在那裏發佈的解決方案不考慮任意方向的滾動。代碼只能滾動到左​​側,但不能到右側。 – BadmintonCat 2013-02-24 05:27:52

+1

哇!這是什麼樣的評論!如果我的問題讓你惱火,就忽略它,你似乎也不知道答案! – BadmintonCat 2013-02-24 18:42:22

+0

我的不好。我認爲這個問題的答案已經與[博客文章](http://flexdiary.blogspot.com/2012/06/endless-scrolling-bathroom.html)聯繫在一起,我在其中提供了一張關於如何思考這個問題。查看博客文章,看看它是否有幫助。編輯:其實博客文章被鏈接到評論中,但如果你沒有擴展它們,你可能會錯過它。 – 2013-02-24 23:32:32

回答

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(); 
    } 
} 

你可以更新Point對象的x & y值周圍的位圖滾動。您可以輕鬆地將速度,加速度和摩擦添加到方程中,使滾動更加動態。