2017-01-06 4 views
0

Я создаю демо-игру в Android для учебных целей. В игре, когда обнаружено столкновение между двумя объектами - я хочу показать диалог «игра над». Внутри диалогового окна есть игра снова кнопка. При нажатии ниток следует снова запускать.Как перезапустить Java-поток в Android-игре?

Я получаю следующее сообщение об ошибке java.lang.IllegalThreadStateException: Thread already started.

Вот мой код:

public class GamePanel extends SurfaceView implements Runnable { 

    private Thread thread = null; 
    private Ball ball; 
    private SurfaceHolder surfaceHolder; 
    private Paint paint; 
    private Canvas canvas; 

    volatile boolean playing = true; 

    private int hurdleCount = 3; 
    private Hurdles[] hurdles; 

    private int screenX, screenY; 
    private Rect ball_detectCollision; 

    public GamePanel(Context context, final int screenX, final int screenY) { 
     super(context); 

     ball = new Ball(context, screenX, screenY); 
     surfaceHolder = getHolder(); 

     this.screenX = screenX; 
     this.screenY = screenY; 

     paint = new Paint(); 
     canvas = new Canvas(); 

     hurdles = new Hurdles[hurdleCount]; 
     for (int i = 0; i < hurdleCount; i++) { 
      hurdles[i] = new Hurdles(context, screenX, screenY); 
     } 

     ball_detectCollision = new Rect(ball.getBall_x(), ball.getBall_y(), ball.getBitmap().getWidth(), ball.getBitmap().getHeight()); 
     surfaceHolder.addCallback(new SurfaceHolder.Callback() { 

      @Override 
      public void surfaceCreated(SurfaceHolder holder) { 

       System.out.println("Surface Created"); 
       setUpdated_x(ball.getBall_x()); 
      } 

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

       System.out.println("Surface Changed"); 
       thread = new Thread(GamePanel.this); 
       thread.start(); 
      } 

      @Override 
      public void surfaceDestroyed(SurfaceHolder holder) { 

       System.out.println("Surface Destroyed"); 
      } 
     }); 
    } 

    public int getUpdated_x() { 
     return updated_x; 
    } 

    public void setUpdated_x(int updated_x) { 
     this.updated_x = updated_x; 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 

     setUpdated_x((int) event.getX()); 

     switch (event.getAction() & MotionEvent.ACTION_MASK) { 

      case MotionEvent.ACTION_UP: 

       break; 

      case MotionEvent.ACTION_DOWN: 

       initial_X = getUpdated_x(); 
       break; 

      case MotionEvent.ACTION_MOVE: 

       if (getUpdated_x() < screenX - ball.getBitmap().getWidth() || getUpdated_x() > screenX - ball.getBitmap().getWidth()) { 
        draw(getUpdated_x()); 
       } 
       break; 
     } 
     return true; 
    } 

    private void draw(int updatedValue) { 

     canvas = surfaceHolder.lockCanvas(); 
     canvas.drawColor(Color.RED); 
     canvas.drawBitmap(ball.getBitmap(), updatedValue, ball.getBall_y(), paint); 
     ball.setBall_x(updatedValue); 

     ball_detectCollision.left = ball.getBall_x(); 
     ball_detectCollision.top = screenY - ball.getBitmap().getHeight() - 260; 
     ball_detectCollision.right = ball.getBall_x() + ball.getBitmap().getWidth(); 
     ball_detectCollision.bottom = screenY - ball.getBitmap().getHeight() - 260 + ball.getBitmap().getHeight(); 

     for (int i = 0; i < hurdleCount; i++) { 
      canvas.drawBitmap(hurdles[i].getBitmap(), hurdles[i].getX(), hurdles[i].getY(), paint); 
     } 
     surfaceHolder.unlockCanvasAndPost(canvas); 
    } 

    @Override 
    public void run() { 

     while (playing) { 
      update(); 
      draw(getUpdated_x()); 
      control(); 
     } 
    } 

    private void update() { 

     for (int i = 0; i < hurdleCount; i++) { 
      hurdles[i].update(); 

      if (Rect.intersects(getBall_detectCollision(), hurdles[i].getDetectCollision())) { 
       System.out.println("Collision Detected"); 

       playing = false; 
       Handler handler = new Handler(Looper.getMainLooper()); 
       handler.post(new Runnable() { 
        @Override 
        public void run() { 
         showGameOverMessage(); 

        } 
       }); 
      } 
     } 
    } 


    public void pause() { 

     playing = false; 
     try { 
      thread.join(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

    private void showGameOverMessage() { 

     Toast.makeText(getContext(), "Game Over", Toast.LENGTH_SHORT).show(); 
     Dialog showDialog = new Dialog(getContext()); 
     showDialog.setContentView(R.layout.dialog_game_over); 
     Button playAgainButton = (Button) showDialog.findViewById(R.id.playAgainButton); 
     playAgainButton.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       playing = true; 
       thread.start(); 
      } 
     }); 
     showDialog.show(); 

    } 
} 
+0

в 'showGameOverMessage()' вы должны создать новый поток перед вызовом 'Thread.start()', но я не могу запустить свой код, чтобы увидеть, если нужно что-то еще – nandsito

+0

я создал новый экземпляр, но ошибка остается тем же – AbhayBohra

ответ

3

Вы не можете перезапустить остановленный поток. Решение состоит в том, чтобы просто создать новый экземпляр и запустить его.

+0

Я пробовал, но его не работает – AbhayBohra

0

Когда игра закончена, просто прекратите нить и снова сыграйте кнопку, чтобы начать новую тему.

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

Редактировать

Вы остановили свой нить отлично. Вам просто нужно начать новый поток, когда вы хотите начать новую игру.

Я бы предложил сохранить функцию следующим образом и удалить implements Runnable.

private void startGame() { 
    // Start a new game 
    playing = true; 

    Thread thread = new Thread() { 
     @Override 
     public void run() { 
      try { 
       while (playing) { 
        update(); 
        draw(getUpdated_x()); 
        control(); 
       } 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    }; 

    thread.start(); 
} 
+0

Как остановить поток? Я попытался создать новый экземпляр, но он не работает – AbhayBohra

+0

См. обновленный ответ. –

+0

Нет, не работает. Проблема остается той же – AbhayBohra