【问题标题】:Starting new activity triggered by boolean in GameThread (android)在 GameThread (android) 中启动由布尔值触发的新活动
【发布时间】:2012-11-22 09:50:14
【问题描述】:

我正在制作一个“保卫城堡”风格的安卓应用程序。游戏已完成,但我只需要帮助关闭我的表面视图并在玩家输掉游戏时开始新的活动。

输掉比赛的条件只是我的 GameThread 类中的一个布尔变量。该变量称为“丢失”,默认设置为 false。当城堡的生命值低于 1 时,lost 设置为 true 并播放音效。

理想情况下,我想在 lost=true 时停止当前循环的声音效果并打开一个新活动(已经制作并正在工作)。

主要活动如下:

import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;

public class MainActivity extends Activity {

    Button btn_startGame;
    Activity activity;

    GameView mGameView;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
                WindowManager.LayoutParams.FLAG_FULLSCREEN);

        activity = this;

        setContentView(R.layout.main);

        btn_startGame = (Button) findViewById(R.id.btnStartGame);
        btn_startGame.setOnClickListener(new OnClickListener() {

            //@Override
            public void onClick(View v) {
                mGameView = new GameView(activity);
                setContentView(mGameView);
                mGameView.mThread.doStart();
            }
        });
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        try {
            mGameView.mThread.onTouch(event);
        } catch(Exception e) {}

        return true;
    }

    @Override 
    public void onConfigurationChanged(Configuration newConfig) { 
      // ignore orientation/keyboard change 
      super.onConfigurationChanged(newConfig); 
    } 
}

surfaceview 是在这个名为 GameView 的类中创建的:

import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceHolder.Callback;

public class GameView extends SurfaceView implements Callback {

    Context mContext;
    GameThread mThread;

    public GameView(Context context) {
        super(context);
        this.mContext = context;

        getHolder().addCallback(this);

        mThread = new GameThread(getHolder(), mContext, new Handler() {
            @Override
            public void handleMessage(Message m) {
                // Use for pushing back messages.
            }
        });

        setFocusable(true);
    }

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

        Log.d(this.getClass().toString(), "in SurfaceChanged()");
    }

    //@Override
    public void surfaceCreated(SurfaceHolder holder) {
        Log.d(this.getClass().toString(), "in SurfaceCreated()");
        mThread.running = true;
        mThread.start();
    }

    //@Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        Log.d(this.getClass().toString(), "in SurfaceDestroyed()");

        boolean retry = true;
        mThread.running = false;
        while (retry) {
            try {
                mThread.join();
                retry = false;
            } catch (InterruptedException e) {
            }
            GameThread.music.stop();
            GameThread.groan1.stop();
            GameThread.groan2.stop();
            GameThread.walk.stop();

            GameThread.music.release();
            GameThread.groan1.release();
            GameThread.groan2.release();
            GameThread.walk.release();
            GameThread.shoot.release();
        }
    }

}

GameThread 类包含所有绘图、逻辑和所有运行方法(如下)。

@Override
    public void run() {
         // check if condition here 
         if(lost){
            mContext.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                //start Activity here

                  Intent intent = new Intent(mContext, LoseActivity.class);
                  mContext.startActivity(intent);
             }
             }); 
            }
           else{
        if (running == true) {
            while (running) {
                Canvas c = null;
                try {
                    c = mHolder.lockCanvas();
                    if (width == 0) {
                        width = c.getWidth();
                        height = c.getHeight();

                        player.x = 50;
                        player.y = 45;
                    }

                    synchronized (mHolder) {
                        long now = System.currentTimeMillis();

                        update();
                        draw(c);
                        ifps++;

                        if (now > (mLastTime + 1000)) {
                            mLastTime = now;
                            fps = ifps;
                            ifps = 0;
                        }
                    }
                } finally {
                    if (c != null) {
                        mHolder.unlockCanvasAndPost(c);
                    }
                }
            }
        }
       }

我要启动的活动称为 LoseActivity.class。提前感谢您的任何帮助。如果有人需要任何进一步的代码/解释,我将非常乐意发布。

【问题讨论】:

    标签: android android-activity surfaceview


    【解决方案1】:

    使用runOnUiThread从线程启动Activity:

    将您的主要活动更改为:

    public class MainActivity extends Activity {
    
        Button btn_startGame;
        Activity activity;
    
        GameView mGameView;
    
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            requestWindowFeature(Window.FEATURE_NO_TITLE);
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
                    WindowManager.LayoutParams.FLAG_FULLSCREEN);
    
            activity = this;
    
            setContentView(R.layout.main);
    
            btn_startGame = (Button) findViewById(R.id.btnStartGame);
            btn_startGame.setOnClickListener(new OnClickListener() {
    
                //@Override
                public void onClick(View v) {
                    mGameView = new GameView(activity,MainActivity.this);
                    setContentView(mGameView);
                    mGameView.mThread.doStart();
                }
            });
        }
      ///your code.....
    

    将您的 GameView 类更改为:

    public class GameView extends SurfaceView implements Callback {
    
        Context mContext;
        Activity contextx;
        GameThread mThread;
    
        public GameView(Context context,Activity contextx) {
            super(context);
            this.mContext = context;
            this.contextx=contextx;
    
            getHolder().addCallback(this);
    
            mThread = new GameThread(getHolder(), mContext, new Handler() {
                @Override
                public void handleMessage(Message m) {
                    // Use for pushing back messages.
                }
            });
    
            setFocusable(true);
        }
      //your code here..........
    
    @Override
        public void run() {
             // check if condition here 
             if(lost){
                contextx.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    //start Activity here
    
                      Intent intent = new Intent(contextx, LoseActivity.class);
                      contextx.startActivity(intent);
                 }
                 }); 
                }
               else{
      //your code here.........
    

    【讨论】:

    • 当我将您的代码粘贴到我的 GameView 构造函数中时,我收到一条错误消息,提示“未为类型上下文定义方法 runOnUiThread(new Runnable(){})”。这是什么意思,我该如何解决?另外,假设这是可行的,我是否只需在意图上方放置一个 if 语句来检查是否 lost=true?
    • 不要将我的代码放在 GameView 构造函数中。只需将它复制过去,您想在 Thread 的 run 方法中开始 Thread 中的活动,并将您的 if 条件放在 runOnUiThread 的 run 方法中。我认为这会起作用 f9
    • 好的,所以我把它放在 GameThread 的 run 方法中,它说 runOnUiThread 对于类型 Context 是未定义的。我做错了什么?
    • @L337Man : 你能用你尝试过的最新代码编辑你的帖子吗,包括我的代码,并在 MainActivity 类中使​​用activty=MainActivity.this
    • 很抱歉给您带来了困惑。我在上面编辑了我的代码。我将您的代码放在 GameThread 类中的 run() 方法中。
    猜你喜欢
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 2011-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    相关资源
    最近更新 更多