2012-01-08 108 views
2

使用下面的代碼滾動 我有一個Surfaceview線程和正在生成(更改),第一行(行),每幀,然後複製一個位置(行)在常規的SurfaceView位圖上做滾動效果,然後我繼續繪製其他的東西。那麼這就是我真正想要的,但是即使我爲屏幕外位圖創建單獨的畫布,我也無法使其工作。它只是不滾動。如何滾動屏幕內存位圖

我換句話說,我有一個內存位圖,與Surfaceview畫布相同,我需要每幀滾動(移位)一行,然後用新的隨機紋理替換頂部行,然後在常規Surfaceview上繪製它帆布。

這是我認爲會工作;

我surfaceChanged,我指定位圖,畫布和啓動線程:

@Override 
    public void surfaceCreated(SurfaceHolder holder) { 
    intSurfaceWidth = mSurfaceView.getWidth(); 
    intSurfaceHeight = mSurfaceView.getHeight(); 

    memBitmap = Bitmap.createBitmap(intSurfaceWidth, intSurfaceHeight, 
      Bitmap.Config.ARGB_8888); 
    memCanvas = new Canvas(memCanvas); 

    myThread = new MyThread(holder, this); 
    myThread.setRunning(true); 
    blnPause = false; 
    myThread.start(); 
} 

我的線索,只顯示必要的中間傳動部分:

@Override 
public void run() { 
    while (running) {  
    c = null; 
try { 
    // Lock canvas for drawing 
    c = myHolder.lockCanvas(null);     

    synchronized (mSurfaceHolder) { 
     // Scroll down off screen canvas and hopefully underlying bitmap bitmap 
     Rect src = new Rect(0, 0, intSurfaceWidth, intSurfaceHeight - 1); 
     Rect dst = new Rect(0, 1, intSurfaceWidth, intSurfaceHeight); 
     memCanvas.drawBitmap(memBitmap, src, dst, null); 

     // Note scrolling up like this works fine 
     // Rect src = new Rect(0, 1, intSurfaceWidth, intSurfaceHeight + 1); 
     // Rect dst = new Rect(0, 0, intSurfaceWidth, intSurfaceHeight); 
     // memCanvas.drawBitmap(memBitmap, src, dst, null); 

     // Create random one line(row) texture bitmap 
     textureBitmap = Bitmap.createBitmap(imgTexture, 0, rnd.nextInt(intTextureImageHeight), intSurfaceWidth, 1); 

     // Now add this texture bitmap to top of screen canvas and hopefully underlying bitmap 
     memCanvas.drawBitmap(textureBitmap, 
       intSurfaceWidth, 0, null); 

     // Draw above updated off screen bitmap to regular canvas, at least I thought it would update (save changes) shifting down and add the texture line to off screen bitmap the off screen canvas was pointing to. 
     c.drawBitmap(memBitmap, 0, 0, null); 

     // Other drawing to canvas comes here 


    } finally { 
     // do this in a finally so that if an exception is thrown 
     // during the above, we don't leave the Surface in an 
     // inconsistent state 
     if (c != null) { 
      myHolder.unlockCanvasAndPost(c); 
     } 
    } 
}  
} 

對於我的比賽隧道運行,https://market.android.com/details?id=com.zubima.TunnelRun,現在我有一個工作的解決方案,我有一個位圖陣列,表面高度的大小,我用我的隨機紋理填充,然後在每個幀的循環中下移。我每秒獲得50幀,但我認爲我可以通過滾動位圖來做得更好。

+0

完成題外話,但在市場上的應用程序描述是全文,沒有段落,沒有什麼......你應該構造它!首先想到的是:tldr – WarrenFaith 2012-01-08 15:08:44

+0

好的建議,補充段落謝謝,但不知道你的意思是「全文......沒有」。這是一個純文本字段,我不能將圖像添加到此。 – DKDiveDude 2012-01-08 16:05:36

+0

是的,但是你的文本格式非常難看。我不想在說明中提供完整的「如何使用/播放」指南。想想它更像是一個廣告文字。總結列表中的一些很酷的功能,讓讀者對你的遊戲感興趣。 – WarrenFaith 2012-01-08 17:46:35

回答

0

有畫布內的drawBitmap功能具有以下特徵:

public void drawBitmap (Bitmap bitmap, Rect src, RectF dst, Paint paint); 

你可以讓你的DST畫布的大小,和你的src可以設置爲新

Rect(0,offset,width,height+offset) 

然後,您可以每幀增加偏移量,並在視圖中獲得平滑滾動位圖。

+0

感謝您的建議。我已經試過了,看到我的代碼更改如上所述,因爲它不適合這裏,但本質上它滾動位圖的方式錯誤,並將偏移量反轉爲-1不會使其向下滾動 – DKDiveDude 2012-01-08 15:00:50

+0

在您的示例中,我認爲你是來源和目的地可能會倒退。源是您正在查看的位圖的區域,目標是顯示器上的區域。 另外,你的代碼是向下滾動的? – nmjohn 2012-01-08 15:35:46

+0

好吧我理解我的增加的評論可能看起來令人困惑,所以讓我修改原始代碼並擺脫添加 – DKDiveDude 2012-01-08 16:09:38

1

您正在嘗試在自己的頂部繪製位圖,這是從未在Android AFAIK上工作過的。我的第一場比賽是一個叫做Mole Miner的側滾輪,我陷入了這個確切的問題。

問題很簡單:drawBitmap()本質上是一種特殊類型的memcpy(),其中字節始終爲轉發。這很好,最好使用L1緩存等,但如果源和目標區域(a)重疊,並且(b)源地址爲dest地址,那麼顯然會出現問題。

(的memcpy(),順便說一下,檢查是否有這種可能性,如果需要向後做副本的真正實現。Canvas.drawBitmap()並沒有這樣做。)

我用鼴鼠礦工的解決方法將有兩個離屏位圖,並在替代幀之間切換它們。但那是在2009年,現在我可能根本不會使用滾動。

+0

是的,它認爲這是一個錯誤/糟糕的實現。我會嘗試兩個離屏位圖,並在今天晚些時候在它們之間切換,如果它有效,我相信您的答案,謝謝! – DKDiveDude 2012-01-16 15:39:49

+0

如果您只是向一個方向滾動(向下),則可以更改此設置,以便將位圖顛倒繪製並滾動*向上*。如果dest <源,則不會出現問題。 – 2012-01-16 16:04:03

+0

也許我無法正確可視化這一點,但這似乎並不奏效。隨着時間的推移,我遊戲中的隧道寬度逐漸縮小。想象一下,在一個屏幕上,隧道從最大寬度到最小寬度到倒V,向下滾動將完美地生成這個動畫。在一個屏幕隧道上再次鏡像位圖會從最大寬度到最小寬度,它看起來像V的右側,其中新的位圖材料(行)將在底部ond中刷新,然後向上滾動,該動畫似乎是完全關閉。如果我錯了,請糾正我,謝謝! – DKDiveDude 2012-01-16 18:24:04