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文档,该类公开了四种可用于实现应用程序加载逻辑的方法:

onPreExecute(),在任务执行后立即在 UI 线程上调用。此步骤通常用于设置任务,例如通过在用户界面中显示进度条。

doInBackground(Params...),在 onPreExecute() 完成执行后立即在后台线程上调用。此步骤用于执行可能需要很长时间的后台计算。

onProgressUpdate(Progress...),在调用 publishProgress(Progress...) 后在 UI 线程上调用。此方法用于在后台计算仍在执行时在用户界面中显示任何形式的进度。

onPostExecute(Result),在后台计算完成后在 UI 线程上调用。后台计算的结果作为参数传递给该步骤。

按照文档,您可以在主 Activity 中启动异步任务。在 onPreExecute 方法中,您可以显示启动画面。

在 doInBackGround 方法中插入执行所有加载内容的代码。如果您想向用户提供有关加载状态的一些信息,您可以在此方法中使用 publishProgress 来发布一个或多个进度单位。这些值在 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 回答