0

ゲームエンジンのすべてのコンポーネントをAsyncTaskで初期化したいと思います。誰かがこれがどのように行われるかを私に教えてもらえますか?

次のようなものが欲しいです:1。コードを実行する前に、スプラッシュ画面(.xml)を設定します2.初期化コードを実行します3.すべて完了したら、ゲームのロード画面を実行します

これが私の現在のコードです:

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

        // Display splash screen
        if(this.splashScreen != null) {
            // .xml
            setContentView(this.splashScreen);
        }

        // Do all the initialization

        // Acquire a wakeLock to prevent the phone from sleeping
        PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
        wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "GLGame");

        // Setup all the Game Engine components 
        gameEngineLog = new WSLog("WSGameEngine");
        gameEngineLog.setLogType(this.gameEngineLogType);
        gameLog = new WSLog(this.gameLogTAG);
        gameLog.setLogType(this.gameLogType);
        io = new FileIO(this, getAssets());
        audio = new Audio(this);
        wsScreen = new WSScreen(this, this.screenResizeType, this.customTopYGap, this.customLeftXGap, this.gameScreenWidth, this.gameScreenHeight);
        graphics = new Graphics(this, wsScreen.getGameScreen(), wsScreen.getGameScreenextended());
        renderView = new RenderView(this, wsScreen.getGameScreen(), wsScreen.getGameScreenextended(), FPS, maxFrameskippes);
        input = new Input(this, renderView, logGameEngineInputLog);
        networkSocket = new NetworkSocket(this);

        this.gameEngineLog.d(classTAG, "Completed initialization");
        setContentView(renderView);

        // Check that the developer has initialized the assets
        if(this.assets == null) {
            this.gameEngineLog.w(classTAG, "The assets for the game haven't been defined!");
        }

        this.getNetworkSocket().useAnalytics(this.analyticsAppAPIKey);
        this.getNetworkSocket().useServerCommunication(this.serverCommunicationAppID, this.serverCommunicationClientKey);
        this.getNetworkSocket().useFacebookCommunicaiton(this.facebookCommunicationAppID);

        // Check if server communication should be initialized
        if(this.networkSocket.getUseOfServerCommunication() == true) {
            this.networkSocket.getServerCommunication().initialize(this, this.networkSocket.getServerCommunicationAppID(), this.networkSocket.getServerCommunicationClientKey()); 
        }

        // Check if facebook communication should be initialized
        if(this.networkSocket.getUseFacebookCommunication() == true) {
            this.networkSocket.getFacebookCommunication().initialize(this.networkSocket.getFacebookCommunicationAppID(), true);
        }

        // Start the Load screen
        // Once all of this code has been executed, the class that extends this class calls "setScreen(new LoadScreen(this));" to set the LoadScreen, which
        // loads all the assets of the game

    }
4

2 に答える 2

0

asynctaskのドキュメントによると、クラスは、アプリケーションのロードロジックを実装するために使用できる4つのメソッドを公開しています。

onPreExecute()は、タスクが実行された直後にUIスレッドで呼び出されます。この手順は通常、ユーザーインターフェイスに進行状況バーを表示するなどしてタスクを設定するために使用されます。

doInBackground(Params ...)、onPreExecute()の実行が終了した直後にバックグラウンドスレッドで呼び出されます。このステップは、時間がかかる可能性のあるバックグラウンド計算を実行するために使用されます。

onProgressUpdate(Progress ...)、publishProgress(Progress ...)の呼び出し後にUIスレッドで呼び出されます。このメソッドは、バックグラウンド計算の実行中に、ユーザーインターフェイスであらゆる形式の進行状況を表示するために使用されます。

onPostExecute(Result)、バックグラウンド計算が終了した後にUIスレッドで呼び出されます。バックグラウンド計算の結果は、パラメーターとしてこのステップに渡されます。

ドキュメントに従って、メインアクティビティで非同期タスクを開始できます。onPreExecuteメソッドでは、スプラッシュ画面を表示できます。

doInBackGroundメソッドに、すべての読み込みを行うコードを挿入します。読み込み状態に関する情報をユーザーに提供する場合は、このメソッドpublishProgress内で使用して、1つ以上の進行状況を公開できます。これらの値は、UIスレッドのonProgressUpdate(Progress ...)ステップで公開されます。

最後に、onPostExecuteメソッドで、スプラッシュスクリーンを削除して、ゲームのロード画面を実行できます。

この例も見てください。

さよなら

于 2012-06-21T12:28:58.997 に答える
0

長い間答えてください、我慢してください。

あなたが望むものを手に入れるためにあなたはいくつかのことをしなければならないでしょう。

setContentViewを複数回呼び出すのではなく、最初にアクティビティを分離します。

次に、「ゲーム設定」であるドメインオブジェクトを設定して、それをロードし、すべてのフィールドを初期化します。

また、設定をロードするための構成オブジェクトもあります。

以下の例では、すべてのフィールドをロードしていませんが、要点を理解していただければ幸いです。

最終的な結果は次のようになります。

最初のアクティビティ:

package com.blundell.tut.ui;

import com.blundell.tut.R;
import com.blundell.tut.domain.Config;
import com.blundell.tut.task.LoadingTask;
import com.blundell.tut.task.LoadingTask.LoadingTaskFinishedListener;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.ProgressBar;

public class SplashActivity extends Activity implements LoadingTaskFinishedListener {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Show the splash screen
        setContentView(R.layout.activity_splash);
        // Find the progress bar
        ProgressBar progressBar = (ProgressBar) findViewById(R.id.activity_splash_progress_bar);
        // Start your loading
        new LoadingTask(progressBar, this, getAssets(), new Config()).execute("www.google.co.uk"); // Pass in whatever you need a url is just an example we don't use it in this tutorial
    }

    // This is the callback for when your async task has finished
    @Override
    public void onTaskFinished(GameDomain result) {
            // The result object is your loaded files!
        completeSplash();
    }

    private void completeSplash(){
        startApp();
        finish(); // Don't forget to finish this Splash Activity so the user can't return to it!
    }

    private void startApp() {
        Intent intent = new Intent(SplashActivity.this, MainActivity.class);
        startActivity(intent);
    }
}

次に、ロードを実行するASyncTask:

package com.blundell.tut.task;

import com.blundell.tut.domain.Config;
import com.blundell.tut.domain.GameDomain;

import android.content.res.AssetManager;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ProgressBar;

public class LoadingTask extends AsyncTask<String, Integer, GameDomain> {

    public interface LoadingTaskFinishedListener {
        void onTaskFinished(GameDomain domain); // If you want to pass something back to the listener add a param to this method
    }

    private static final int NUM_OF_TASKS = 2;

    // This is the progress bar you want to update while the task is in progress
    private final ProgressBar progressBar;
    // This is the listener that will be told when this task is finished
    private final LoadingTaskFinishedListener finishedListener;

    private final AssetManager assets;

    private final Config config;

    /**
     * A Loading task that will load some resources that are necessary for the app to start
     * @param progressBar - the progress bar you want to update while the task is in progress
     * @param finishedListener - the listener that will be told when this task is finished
     */
    public LoadingTask(ProgressBar progressBar, LoadingTaskFinishedListener finishedListener, AssetManager assets, Config config) {
        this.progressBar = progressBar;
        this.finishedListener = finishedListener;
        this.assets = assets;
        this.config = config;
    }

    @Override
    protected GameDomain doInBackground(String... params) {
        GameDomain gameDomain = new GameDomain();
        Log.i("Tutorial", "Starting task with url: "+params[0]);
        if(resourcesDontAlreadyExist()){
            downloadResources(gameDomain);
        }

        return gameDomain;
    }

    private boolean resourcesDontAlreadyExist() {
        // Here you would query your app's internal state to see if this download had been performed before
        // Perhaps once checked save this in a shared preference for speed of access next time
        return true; // returning true so we show the splash every time
    }


    private void downloadResources(GameDomain gameDomain) {
        // We are just imitating some process thats takes a bit of time (loading of resources / downloading)
            int count = NUM_OF_TASKS;

            // Do some long loading things

            // Setup all the Game Engine components
           gameDomain.setGameEngineLog("WSGameEngine", config.LOG_TYPE);

           updateProgress(count--);

           gameDomain.setAssets(assets);

           updateProgress(count--);
    }

    public void updateProgress(int count) {
        // Update the progress bar after every step
        int progress = (int) ((NUM_OF_TASKS / (float) count) * 100);
        publishProgress(progress);
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        progressBar.setProgress(values[0]); // This is ran on the UI thread so it is ok to update our progress bar ( a UI view ) here
    }

    @Override
    protected void onPostExecute(GameDomain result) {
        super.onPostExecute(result);
        finishedListener.onTaskFinished(result); // Tell whoever was listening we have finished
    }
}

次に、インスタンス化するオブジェクト:

public class GameDomain {

    private WSLog gameEngineLog;
    private FileIO io;

    public void setGameEngineLog(String name, String logType){
         gameEngineLog = new WSLog(name);
         gameEngineLog.setLogType(logType);
    }

    public void setAssets(AssetManager assets) {
         io = new FileIO(assets);
    }

}

また、構成:

package com.blundell.tut.domain;

public class Config {
    public String LOG_TYPE = "logType";
}

最後に、WakeLockはonCreateの各アクティビティで「取得」され、「onPause」で解放されます。

于 2012-06-21T12:32:31.960 に答える