今まで描画に関してはViewを利用していましたが、今回はSurfaceViewを利用してみたいと思います。
SurfaceViewに関しては「ゲーム向き」と言われますが、Viewに比べて描画の動作を軽量化できる。と言った点でゲーム向きのようですが、描画自体は若干粗くなるようです。
surfaceを利用する場合はいくつかの関数で構成されていますが、ある程度のテンプレートを示させていただきます。
public class MainView extends SurfaceView implements SurfaceHolder.Callback, Runnable{ private SurfaceHolder holder; private Thread thread; public MainView(Context context){ super(context); holder = null; thread = null; getHolder().addCallback(this); } public void surfaceCreated(SurfaceHolder holder){ this.holder = holder; thread = new Thread(this); } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height){ if(thread != null ){ thread.start(); } } public void surfaceDestroyed(SurfaceHolder holder){ thread = null; } public void run(){ Canvas canvas = holder.lockCanvas(); //canvas.draw(***); holder.unlockCanvasAndPost(canvas); } }
上記が基本の形です。
Threadを作成してその中で描画を行う形式です。繰り返し利用をしない場合はthreadを作成しなくても問題ありません。
ここでThreadを一フレームと考えて、フレーム毎の動作が作成できます。
動作の処理によっては遅くなったり、早く見えたりしてしまいます。さまざまな機種で同様の動作を行えるようにする為に、下記の形で「時間」を用いる事をおすすめします。
private long myTime = 0;
を作成。
mTime = System.currentTimeMillis();
surfaceChangedで実行をします。※これを設定しないと最初の一回の値が変になるので注意です。
int Interval = (System.currentTimeMillis()-myTime); myTime = System.currentTimeMillis();
をThread内で設定をする事で、前回のthread実行からどれくらい時間がかかったかが分かります。
このIntervalを利用して、
1秒間に50だけ動かしたい対象があった場合に50/1000*Intervalとする事で時間に対応した位置にオブジェクトの配置をする事ができ処理が重くなった場合にも、さほど気にする事なく動作(移動がフレーム落ち感はあっても目的地までは通常の時間でたどり着きます。)を行えます
また、SurfaceViewで物体を動かす際には多くの場合に
canvas.drawColor(Color.WHITE);
などで、毎回前回の描写をリセットしてから、描写する事が多いです。
また、この部分にalphaをつけると残像を残した状態で作成ができます。
以上です。