setContentView () внутри потока - PullRequest
0 голосов
/ 26 июля 2011

Я делаю простую игру для Android, написанную на Java.

У меня есть активность ...

public class GameName extends Activity{
...
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
}

Внутри «основного» макета у меня есть кнопка, которая вызывает метод «startTheGame»:

public void startTheGame(View v) {
theGame = new Panel(this);
    setContentView(theGame);
}

Вот код панели (упрощенно)

class Panel extends SurfaceView implements SurfaceHolder.Callback {
  public GameThread _thread;
    public Panel(Context context) {
      super(context);
      getHolder().addCallback(this);
      setFocusable(true);
    } 
  ...
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        _thread = new GameThread(getHolder(), this);
        _thread.setRunning(true);
        _thread.start();
    }
 ...
 }

Итак, как вы можете видеть, у меня запущен класс "GameThread" ... здесь он ниже:

class GameThread extends Thread {
    private SurfaceHolder _surfaceHolder;
    private Panel _panel;
    private boolean _run = false;

    public GameThread(SurfaceHolder surfaceHolder, Panel panel) {
        _surfaceHolder = surfaceHolder;
        _panel = panel;
    }

    public void setRunning(boolean run) {
        _run = run;
    }
            @Override
    public void run() {
        Canvas c;
        while (_run) {
            c = null;

            try {
                    ...

                    if (health <= 0) {
                        _run = false;

                        //change views?
                        setContentView(R.layout.over);

                    }

                    c = _surfaceHolder.lockCanvas(null);
                    synchronized (_surfaceHolder) {
                        _panel.onDraw(c);                       
                    }

                    ...

                } finally {
                    // do this in a finally so that if an exception is
                    // thrown
                    // during the above, we don't leave the Surface in an
                    // inconsistent state
                    if (c != null) {
                        _surfaceHolder.unlockCanvasAndPost(c);
                    }
                    try {
                        Thread.sleep(60);
                    } catch (Exception e) {
                    }
                }


            }

        }

Надеюсь, вы видите, что если состояние

Он просто останавливает обновление экрана (рисование), но я никогда не вижу новую панель.

Я пробовал:

GameName cs = ((GameName)getApplicationContext())
cs.setContentView(R.layout.over);

Но я получаю ClassCastException ...

Пожалуйста, помогите!

Ответы [ 2 ]

0 голосов
/ 26 июля 2011

Вы не можете привести свой ApplicationContext к своему основному Activity (GameName), потому что это не тот же объект. Определенным образом getApplicationContext() соответствует не первому запущенному Activity, а самому приложению.

Для меня вы должны попытаться выполнять различные действия вместо того, чтобы пытаться изменить макет и поведение одного Activity. Это было бы проще для вас, и это позволило бы избежать проблем, с которыми вы сталкиваетесь. На самом деле, каждый setContentView(), который я вижу в коде, должен соответствовать переключателю.

Таким образом, вы получите что-то вроде:

  • WelcomeActivity (возможно GameName здесь): выберите параметры игры и запустите
  • PlayingActivity: сама игра. Вот где собственно геймплей.
  • GameOverActivity: отображает счет или все, что вы хотели бы показать после окончания игры

Это не зная, в какую игру вы играете, но этот скелет должен хорошо работать с аркадами / экшенами, ролевыми играми / приключениями или даже лабиринтами / богами-играми.

0 голосов
/ 26 июля 2011

Я бы рекомендовал изучить использование Обработчиков . Он позволяет вам безопасно общаться с потоком пользовательского интерфейса, не беспокоясь о том, в каком потоке вы сейчас находитесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...