新ブログ「ごんフラブログG2」

WordPressで始めてみました

[海外]バンドルされた複数のゲーム・PCアプリが購入できるサイト
humblebundle.com


ごんたろうのぼやきトップ

2018年10月07日

SurfaceViewが上手く動かなかったのでサンプルを作ってみた【Androidプログラミング】

以前購入したAndroidプログラミングの本を参考に
SurfaceViewをいじってみたんだけど、Android4.xでは
動いたけど、5〜6辺りで全くうんともすんとも言わなかったので
色々調べてみたんだけど、なかなかうまく動くモノが無かった。
四苦八苦しながらやっと、サンプルにできるくらいは
出来たので記録。
(一部のAndroid6.0エミュレータではスワイプしたら落ちたけど
原因不明。試しに他の6.0で試してみたら落ちなかったので
Android6.0で落ちると言うことではなさそう。)

SurfaceViewとThread(ここではDrawThread)を
分けているサンプルなどもあるけど
分けて記述することも可能かと思いますが、
ここではSurfaceViewのファイルと一つにまとめて記述しています。

(AndroidStudio 3.1.4で作成)
必要javaファイルは2つ
*MainActivity.java
*SurfaceViewSample.java


■[MainActivity.java](任意の名称に変更して下さい)
(import部分は省略しています)


public class MainActivity extends AppCompatActivity implements SurfaceViewSample.Callback {

//クラス名を変更する場合はこちらも変更して下さい
private SurfaceViewSample surfaceViewSample;

private void onCreateProcess() {
   //クラス名を変更する場合はこちらも変更して下さい
surfaceViewSample= new SurfaceViewSample(getApplicationContext());
surfaceViewSample.setCallback(this);
setContentView(surfaceViewSample);
}

private void onResumeProcess() {
surfaceViewSample.startDrawThread();
}

private void onPauseProcess() {
surfaceViewSample.stopDrawThread();

}


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
onCreateProcess();
}

@Override
protected void onResume() {
super.onResume();
onResumeProcess();
}


@Override
protected void onPause() {
super.onPause();
onPauseProcess();
}



//Callback
public void onGameOver() {
//CallBack
//ゲームオーバーなど表示
//
}


}



※コールバックのonGameOver関数はSurfaceViewでゲームオーバーなどの
処理で使用できるように作っているだけで、サンプルでは使用していません。

【setContentView(surfaceViewSample)】の部分を
setContentView(new SurfaceViewSample(getApplicationContext()));
書き方も出来ますが、
Activity側で処理を止めるために(onPauseで止めています)
直接記述はしていません。
また、getApplicationContext()を引数で渡していますが、
thisなどのサンプルも見かけます。
どちらでもいいですが、一応渡すのはContextなので、
getApplicationContextの方がよろすぃみたいな説明を
されている方もいらっしゃいました。


■[SurfaceViewSample.java](任意の名称に変更して下さい)
※gameOver()関数は未使用ですが、ゲームオーバー等の処理で
MainActivityへのコールバックを作成しています。


import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Handler;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class SurfaceViewSample extends SurfaceView implements SurfaceHolder.Callback {

private static final int FPS = 60;

DrawThread drawThread;

public interface Callback {
public void onGameOver();
}
private Callback callback;
public void setCallback(Callback callback) {
this.callback = callback;
}

private final Handler handler;

public SurfaceViewSample(Context context) {
super(context);
handler = new Handler();
getHolder().addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
startDrawThread();
}

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

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
stopDrawThread();
}

public void processGameAll(Canvas canvas){
int disp_w=canvas.getWidth();
int disp_h=canvas.getHeight();

canvas.drawColor(0xffcccccc);//背景色


}


private class DrawThread extends Thread{
boolean isFinished;

@Override
public void run() {
//SurfaceHolder holder = getHolder();//途中でやり方を変更したためコメントアウトw
while (!isFinished) {
Canvas canvas;
//canvas = holder.lockCanvas();//上記コメントアウトの名残w
canvas = getHolder().lockCanvas();
if (canvas == null) {
stopDrawThread();
}else{
processGameAll(canvas);//メイン描画処理
//holder.unlockCanvasAndPost(canvas);//同じく上記コメントアウトの名残
//getHolder().unlockCanvasAndPost(canvas);
}
}
}
}



public void startDrawThread() {
stopDrawThread();
drawThread = new DrawThread();
drawThread.start();
}

public boolean stopDrawThread() {
if (drawThread == null) {
return false;
}
drawThread.isFinished = true;
drawThread = null;
return true;
}

  //ここからMainActivityの関数(UI)へコールバック
private void gameOver() {
handler.post(new Runnable() {
@Override
public void run() {
callback.onGameOver();
}
});
}



posted by ごんたろう(Gontaro-Soft) at 19:26 | Comment(0) | Androidアプリ開発/Android Studio
この記事へのコメント
コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
ブログランキング・にほんブログ村へ
にほんブログ村

インターネット・コンピュータランキング