2017-12-24 26 views
0

게임이 끝나면 게임이 끝났으며 어떤 점수를 받았는지 경고 대화 상자를 열어야합니다. 이 작업은 한 번 이상 수행되며 앱이 다운 될 때까지 대화 상자를 열어 둡니다. 나는 왜이 일을하는지 알 수 없다. logcat은 오류를보고하지 않습니다. try {}로 대화 상자를 여는 코드를 넣으려고 시도했지만 때로는 일관되게 작동하지 않았습니다. 당신은 문제를 일으키는 원인이 무엇인지 생각하고 있습니까?alertdialog가 두 번 이상 열려고 시도합니다.

다음은 관련 코드입니다.

class SnakeView extends SurfaceView implements Runnable { 

public SnakeView(Context context, Point size){ 
    super(context); 
    handler = new Handler(context.getMainLooper()); 

    mContext = context; 

    mScreenWidth = size.x; 
    mScreenHeight = size.y; 

    mBlockSize = mScreenWidth/NUM_BLOCKS_WIDE; 
    mNumBlocksHigh = ((mScreenHeight))/mBlockSize; 

    loadSound(); 

    mHolder = getHolder(); 
    mPaint = new Paint(); 

    mSnakeXs = new int[200]; 
    mSnakeYs = new int[200]; 

    startGame(); 
} 
public void updateGame(){ 
    if (mSnakeXs[0]== mMouseXs && mSnakeYs[0] == mMouseYs){ 
     eatMouse(); 
    } 

    moveSnake(); 
    if (detectDeath()){ 
     mSoundPool.play(mDead_sound, 1, 1, 0, 0, 1); 

     final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(mContext); 
     alertDialogBuilder 
       .setTitle("Game Over!") 
       .setMessage("Your score: " + mScore + "!") 
       .setCancelable(false) 
       .setPositiveButton("New", new DialogInterface.OnClickListener() { 
        @Override 
        public void onClick(DialogInterface dialog, int which) { 
         Intent intent = new Intent(mContext, SnakeActivity.class); 
         mContext.startActivity(intent); 
        } 
       }) 
       .setNegativeButton("Exit", new DialogInterface.OnClickListener() { 
        @Override 
        public void onClick(DialogInterface dialog, int which) { 
         Intent intent = new Intent(mContext, Start.class); 
         mContext.startActivity(intent); 
        } 
       }); 
     runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 

       alertDialogBuilder.show(); 
      } 
     }); 


    } 


} 
private void runOnUiThread(Runnable r){ 
    handler.post(r); 
} 

    } 
+1

하는 것 같다 . – ADM

+0

여러 번 호출되는 경우'if (detectDeath() &&! playerDead)'를 사용하고 대화 상자를 표시하기 전에'playerDead = true'를 설정할 수 있습니다. –

+0

대화 상자가 표시되는지 여부를 확인하기 위해 부울을 포함 할 수 있습니다. –

답변

0

대화 상자를 추적하기 위해 변수 dead을 소개합니다. 이것은 프로그램이 프로그램을 중단시킬 수있는 OOM 예외를 유발할 수있는 새로운 대화 상자를 만드는 전체 과정을 거치지 못하도록 방지하기위한 것입니다.

class SnakeView extends SurfaceView implements Runnable { 
    boolean dead = false; 
    public SnakeView(Context context, Point size){ 
     super(context); 
     handler = new Handler(context.getMainLooper()); 

     mContext = context; 

     mScreenWidth = size.x; 
     mScreenHeight = size.y; 

     mBlockSize = mScreenWidth/NUM_BLOCKS_WIDE; 
     mNumBlocksHigh = ((mScreenHeight))/mBlockSize; 

     loadSound(); 

     mHolder = getHolder(); 
     mPaint = new Paint(); 

     mSnakeXs = new int[200]; 
     mSnakeYs = new int[200]; 

     startGame(); 
    } 
    public void updateGame(){ 
     if (mSnakeXs[0]== mMouseXs && mSnakeYs[0] == mMouseYs){ 
      eatMouse(); 
     } 

     moveSnake(); 
     if (detectDeath()&& !dead){ 
      mSoundPool.play(mDead_sound, 1, 1, 0, 0, 1); 

      final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(mContext); 
      alertDialogBuilder 
        .setTitle("Game Over!") 
        .setMessage("Your score: " + mScore + "!") 
        .setCancelable(false) 
        .setPositiveButton("New", new DialogInterface.OnClickListener() { 
         @Override 
         public void onClick(DialogInterface dialog, int which) { 
          Intent intent = new Intent(mContext, SnakeActivity.class); 
          mContext.startActivity(intent); 
         } 
        }) 
        .setNegativeButton("Exit", new DialogInterface.OnClickListener() { 
         @Override 
         public void onClick(DialogInterface dialog, int which) { 
          Intent intent = new Intent(mContext, Start.class); 
          mContext.startActivity(intent); 
         } 
        }); 
      runOnUiThread(new Runnable() { 
       @Override 
       public void run() { 
    dead = true; 
        alertDialogBuilder.show(); 
       } 
      }); 


     } 


    } 
    private void runOnUiThread(Runnable r){ 
     handler.post(r); 
    } 

     } 
+0

정말 고마워요 !! – Tor99er

0

음, 내가 context.getMainLooper()가 모든 것을 루핑 또는 실행 가능한 로직은 단지 자체에 다시 반복되어 있는지 모르겠지만, 당신이 당신의 클래스 hasDialogBeenShown에서 부울을 선언 할 수는 허위로 설정 이 같은

public void run(){ 
    if(!hasDialogBeenShown){ 
     alertDialogBuilder.show(); 
     hasDialogBeenShown=true; 
    } 
} 

뭔가 문제를 "해결"해야하지만, 왜 alertDialogBuilder.show은() 한 실행 가능한에있을 않습니다 SnakeView, 다음 실행이에() 코드를 설정? 왜 오너 쓰레드를 사용해야합니까?

+0

다른 방법으로도 대화 상자가 표시되지 않았습니다. 이것이 제가 발견 한 유일한 방법이었습니다. 잘 거의 일했다 :). – Tor99er

0

이 삭제 :

runOnUiThread(new Runnable() { 
@Override 
    public void run() { 
     alertDialogBuilder.show(); 
    } 
}); 

이 넣어 : 코드와는 한 번만 호출해야합니다 .Debug 당신이`updateGame()`방식을 여러 번 호출하는 것처럼

final AlertDialog dialog2 = alertDialogBuilder.create(); 
dialog2.show(); 
+0

당신은 또 다른 부울을 필요로하지 않아야합니다. detectDeath()는 true 또는 false를 반환 할 것이므로 dead –