2017-01-06 8 views
0

학습 목적으로 안드로이드에 데모 게임을 만들고 있습니다. 게임에서 두 객체간에 충돌이 감지되면 "게임 오버"대화 상자를 표시하려고합니다. 대화 상자 안에 이 다시 재생 버튼이 있습니다. 이 버튼을 누르면 스레드가 다시 시작됩니다.Android 게임에서 Java Thread를 다시 시작하는 방법은 무엇입니까?

다음 오류가 발생합니다. 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

()'는') ('thread.start를 호출하기 전에 새 스레드를 생성해야합니다,하지만 난 그게 뭔가 다른 – nandsito

+0

을 필요로하는 경우 나는 새 인스턴스하지만 오류를 만들어 볼 수 코드를 실행할 수 없습니다 동일하게 유지됩니다 – AbhayBohra

답변

3

당신은 중지 된 스레드를 다시 시작할 수 없습니다 :

여기 내 코드입니다. 해결책은 단순히 새로운 인스턴스를 생성하고 시작하는 것입니다.

+0

시도했지만 그 작동하지 않습니다 – AbhayBohra

0

게임이 끝나면 방금 게임을 중지하고 다시 재생 버튼을 눌러 새 게임을 시작해야합니다.

이전 스레드의 인스턴스를 저장해야하는 경우 외부 변수에 저장하십시오. 이 경우 어쨌든 많은 옵션이 있습니다.

편집 당신은 완벽하게 스레드를 중단했다. 새 게임을 시작하려면 새 스레드를 시작해야합니다.

나는 이와 같은 기능을 유지하고 implements Runnable을 제거 할 것을 제안합니다. showGameOverMessage`에서

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