LunarLander と同様のフレームワークで、SurfaceView を使用してビットマップを描画する Android ゲーム エンジンを開発しています。私のメイン ゲーム エンジン アクティビティは、以下に示すように、SurfaceView 拡張クラスを表示するようにレイアウトを設定します。
super.onCreate(savedInstanceState);
setContentView(R.layout.ss_layout);
SSSurfaceView ssSurfaceView = (SSSurfaceView)findViewById(R.id.surface_view);
SSSurfaceView.SSViewThread renderThread =
(SSSurfaceView.SSViewThread) ssSurfaceView.getThread();
findViewById メソッドは、SurfaceView 拡張クラスのインスタンスを正常に返し、クラス コンストラクターであるこのメソッドで作成されたクラス内で定義したスレッドを実行できます。
public SSSurfaceView(Context context, AttributeSet attributes)
{
super(context, attributes);
SurfaceHolder holder = getHolder();
holder.addCallback(this);
thread = new SSViewThread(holder, context);
}
コンストラクターは、関連付けられた SurfaceHolder への参照を取得する必要があり、それをスレッド コンストラクターに渡します。holder.lockCanvas(null) が null を返すスレッド実行メソッド内で問題が発生し始めました。これはサーフェスが作成されていないことを意味する可能性があることをどこかで読んだので、surfaceCreated コールバックで true に設定したブール値を使用して if ステートメントを追加しました。
public void run()
{
Canvas canvas = null;
try
{
canvas = holder.lockCanvas(null);
//I added the condition below
if(surfaceCreated)
{
drawAll(canvas);
}
}
catch(Exception e)
{
Log.wtf("SurfaceView", "exception");
}
finally
{
if(canvas != null)
{
holder.unlockCanvasAndPost(canvas);
}
}
}
そして、ここにコールバックがあります:
public void surfaceCreated(SurfaceHolder holder)
{
surfaceCreated = true;
}
結局のところ、surfaceCreated が呼び出されることはありません。drawAll メソッドが繰り返されないため、私のアプリケーションは灰色の画面を表示し、他には何もしません。起動する layout.xml ファイルは次のとおりです。
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<com.bostonwalker.sseng.SSSurfaceView
android:id="@+id/surface_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
編集:これは私のコード全体ではありません。例を関連するセクションに限定しようとしました。スレッドはメイン ループで呼び出されますが、時間が経ってもコールバックは起動しません。
編集: UI スレッドで繰り返されるループは次のとおりです。
while(!halt)
{
//EDIT: Changed from .run() to .start()
renderThread.start();
gameThread.start();
//Wait for both threads to proceed before continuing
try
{
renderThread.join();
gameThread.join();
}
catch (InterruptedException e)
{
//Do nothing
}
Thread.currentThread();
try
{
Thread.sleep(2);
}
catch (Exception e)
{
//Do nothing
}
}