4

onDraw メソッドの ImageView で描画を行っていました。ただし、onDraw の外側でキャンバスを描画し、onDraw でキャンバスを更新するだけの方がよいことを学びました。

これが明らかに間違っていることはわかっていますが(機能していないため)、私がやろうとしていることをどのように達成できますか:

@Override 
public void onDraw(Canvas c) {
  c = this.newCanvas;
  super.onDraw(c);
}
4

2 に答える 2

1
    public class GameLoopThread extends Thread {
private GameView view;
private boolean running = false;

public GameLoopThread(GameView view) {
      this.view = view;
}

public void setRunning(boolean run) {
      running = run;
}

@Override
public void run() {

      while (running) {
             Canvas c = null;

             try {
                    c = view.getHolder().lockCanvas();
                    synchronized (view.getHolder()) {
                        if (c != null) {
                            view.onDraw(c);
                        }

                    }
             } finally {
                    if (c != null) {
                           view.getHolder().unlockCanvasAndPost(c);
                    }
             }

             try {

                           sleep(10);
             } catch (Exception e) {}
      }
}
}

そのスレッドを作成し、アクティビティでこのようなことを行います

    @Override
public void onCreate(Bundle savedInstanceState) {
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
    WindowManager.LayoutParams.FLAG_FULLSCREEN);
    super.onCreate(savedInstanceState);
    setContentView(new GameView(GameActivity.this));
}

次に、GameViewClassで次のようなことを行います

   public class GameView extends SurfaceView {

   private SurfaceHolder holder;
   private GameLoopThread gameLoopThread;


   public GameView(Context context) {
         super(context);
         gameLoopThread = new GameLoopThread(this);
         holder = getHolder();
         holder.addCallback(new SurfaceHolder.Callback() {

                @Override
                public void surfaceDestroyed(SurfaceHolder holder) {
                       boolean retry = true;
                       gameLoopThread.setRunning(false);
                       while (retry) {
                              try {
                                    gameLoopThread.join();
                                    retry = false;
                              } catch (InterruptedException e) {
                              }
                       }
                }

                @Override
                public void surfaceCreated(SurfaceHolder holder) {
                       gameLoopThread.setRunning(true);
                       gameLoopThread.start();
                }

                @Override
                public void surfaceChanged(SurfaceHolder holder, int format,
                              int width, int height) {
                }
         });

   }

   @Override
   protected void onDraw(Canvas canvas) {
         //Do Drawing
   }
}

ここで重要なのは、スレッドが手動でonDraw()メソッドを繰り返し自動呼び出ししていることと、キャンバスをロックして描画し、投稿していることです。超高速のリフレッシュレートが必要ない場合は、次のようなことを行う方がよい場合があります。

    @Override 
    public void onDraw(Canvas c) {
        c = this.getHolder().lockCanvas();
        if (c != null) {
           //draw on canvas
        }
        if (c != null) {
            this.getHolder().unlockCanvasAndPost(c);
        }
    }

その最後のビットが機能するかどうかはわかりませんが、テストしたことはありません。また、on drawメソッドの外部で描画を行う場合は、スレッドで更新(キャンバス上での描画)を実行できます。onDrawメソッドが呼び出されるたびに、Canvasでの準備ができているかどうかを確認してください。役職。たとえば、スレッドにブール値があり、キャンバスがプルされるとfalseに設定されるため、スレッドは新しいスレッドを描画しますが、描画が完了するとブール値をtrueに設定します。ondrawメソッドで、ブール値がtrueであるかどうか、およびそれがキャンバスをプルしているかどうかを確認します。

于 2012-08-12T08:03:22.183 に答える