2012-06-08 61 views
9

我想用3個類畫一個球到我的屏幕。我已經讀了一些關於這個,我發現了一個代碼片段,使用3個類在一個頁面上,Playing with graphics in AndroidAndroid使用SurfaceView和線程繪製

我改變了代碼,以便我有一個球是移動和移動方向時,像牆圖片在(這是使用鏈接中的代碼)

moving ball screenshot

現在我喜歡的類分爲3次不同的頁面不使一切都那麼擁擠,一切都設立了同樣的方式。

這裏是我的3個班級。

  1. BallActivity.java
  2. Ball.java
  3. BallThread.java

package com.brick.breaker; 
import android.app.Activity; 
import android.os.Bundle; 
import android.view.Window; 
import android.view.WindowManager; 


public class BallActivity extends Activity { 

private Ball ball; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 

    super.onCreate(savedInstanceState); 

    requestWindowFeature(Window.FEATURE_NO_TITLE); 
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN); 

    ball = new Ball(this); 
    setContentView(ball); 
} 

@Override 
protected void onPause() { 

    super.onPause(); 

    setContentView(null); 
    ball = null; 

    finish(); 
} 

} 

package com.brick.breaker; 

import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 

public class Ball extends SurfaceView implements SurfaceHolder.Callback { 

private BallThread ballThread = null; 

private Bitmap bitmap; 

private float x, y; 
private float vx, vy; 

public Ball(Context context) { 
    super(context); 

    bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ball); 

    x = 50.0f; 
    y = 50.0f; 

    vx = 10.0f; 
    vy = 10.0f; 

    getHolder().addCallback(this); 
    ballThread = new BallThread(getHolder(), this); 
} 

protected void onDraw(Canvas canvas) { 

    update(canvas); 

    canvas.drawBitmap(bitmap, x, y, null); 
} 

public void update(Canvas canvas) { 

    checkCollisions(canvas); 

    x += vx; 
    y += vy; 
} 

public void checkCollisions(Canvas canvas) { 

    if(x - vx < 0) { 

     vx = Math.abs(vx); 

    } else if(x + vx > canvas.getWidth() - getBitmapWidth()) { 

     vx = -Math.abs(vx); 
    } 

    if(y - vy < 0) { 

     vy = Math.abs(vy); 

    } else if(y + vy > canvas.getHeight() - getBitmapHeight()) { 

     vy = -Math.abs(vy); 
    } 
} 

public int getBitmapWidth() { 

    if(bitmap != null) { 

     return bitmap.getWidth(); 

    } else { 

     return 0; 
    } 
} 

public int getBitmapHeight() { 

    if(bitmap != null) { 

     return bitmap.getHeight(); 

    } else { 

     return 0; 
    } 
} 

public void surfaceChanged(SurfaceHolder holder, int format, int width, 
     int height) { 

} 

public void surfaceCreated(SurfaceHolder holder) { 

    ballThread.setRunnable(true); 
    ballThread.start(); 

} 

public void surfaceDestroyed(SurfaceHolder holder) { 

    boolean retry = true; 
    ballThread.setRunnable(false); 

    while(retry) { 

     try { 

      ballThread.join(); 
      retry = false; 

     } catch(InterruptedException ie) { 

      //Try again and again and again 
     } 

     break; 
    } 

    ballThread = null; 

} 

} 

package com.brick.breaker; 

import android.graphics.Canvas; 
import android.view.SurfaceHolder; 

public class BallThread extends Thread { 

private SurfaceHolder sh; 
private Ball ball; 

private Canvas canvas; 

private boolean run = false; 

public BallThread(SurfaceHolder _holder,Ball _ball) { 

    sh = _holder; 
    ball = _ball; 
} 

public void setRunnable(boolean _run) { 

    run = _run; 
} 

public void run() { 

    while(run) { 

     canvas = null; 

     try { 

      canvas = sh.lockCanvas(null); 

      synchronized(sh) { 

       ball.onDraw(canvas); 
      } 

     } finally { 

      if(canvas != null) { 

       sh.unlockCanvasAndPost(canvas); 
      } 

     } 

    } 
} 

public Canvas getCanvas() { 

    if(canvas != null) { 

     return canvas; 

    } else { 

     return null; 
    } 
} 
} 

這裏是一個圖象,顯示這些類的結果。

enter image description here

我試圖算出這個,但因爲我非常新的Android開發我以爲我可以尋求幫助。

是否有人知道是什麼導致球被畫出來? 代碼與鏈接中的代碼非常相似,我試圖嘗試找到一個解決方案,但沒有運氣。

回答

14

好吧,就像你在圖片上看到的那樣,你只能畫出球。相反,您需要在每次繪製球之前重新繪製黑色背景(或任何您希望的內容)。

或者,您可以僅在前一個位置繪製黑色區域,但以後使用更多對象時可能會遇到問題。

here's a nice sample,類似於你做了什麼

+0

YEPP是固定我的問題克隆此項目的源代碼,對的onDraw方法我增加了線條的畫布。 drawColor(Color.BLACK);在我畫球之前,屏幕上會充滿黑色,消除不需要的綠球擊球。 Thx alot =) –

+0

順便說一句,爲了更平滑和更快的動畫,我會推薦使用opengl。畫布僅用於簡單的東西,尤其是現在大多數設備仍然沒有GPU幫助圖形的東西,因爲大多數仍然是「舊」Android版本(薑餅)。 –

+0

優秀的建議=)我會搞砸上面的代碼,然後創建一個新的項目,並執行相同的邏輯,但使用openGL。 Thx for the tip :) –

1

一個快速的樣子,我不得不說你只是在同一個表面上繪圖,永遠不會要求你的surfaceview重繪自己。在finally語句塊的末尾,在IF語句中使用:postInvalidate();這應該會導致表面視圖自己重繪。

1

把這個

public void onDraw(Canvas canvas){ 
    canvas.drawColor(Color.BLACK); 

..... 

} 
-1

[編輯]答案是錯的,但評論是有幫助的,所以我會離開這個答案了:

不是你問的問題,但是你的代碼存在問題。在Android中,只允許在UI線程中寫入屏幕。這是運行所有Activity回調等的線程。通過從BallThread寫入屏幕,您將在程序中冒許多奇怪的故障。

+2

'SurfaceView'可以從另一個線程更新 - http://developer.android.com/reference/android/view/SurfaceView.html –

+0

謝謝。學到了新東西。 –