2010-09-05 64 views
-1

請幫助下面的代碼 - 我需要一個帶有按鈕的對話框,當遊戲拼圖完成時出現。謝謝!如何在遊戲完成時用按鈕啓動對話框?

下面的代碼:

Sudoku.java

package org.example.sudoku; 

import android.app.Activity; 
import android.app.AlertDialog; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.Menu; 
import android.view.MenuInflater; 
import android.view.MenuItem; 
import android.view.View; 
import android.view.View.OnClickListener; 

public class Sudoku extends Activity implements OnClickListener { 
    private static final String TAG = "Sudoku"; 

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

     // Set up click listeners for all the buttons 
     View continueButton = findViewById(R.id.continue_button); 
     continueButton.setOnClickListener(this); 
     View newButton = findViewById(R.id.new_button); 
     newButton.setOnClickListener(this); 
     View aboutButton = findViewById(R.id.about_button); 
     aboutButton.setOnClickListener(this); 
     View exitButton = findViewById(R.id.exit_button); 
     exitButton.setOnClickListener(this); 
    } 


    @Override 
    protected void onResume() { 
     super.onResume(); 
     Music.play(this, R.raw.main); 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     Music.stop(this); 
    } 



    public void onClick(View v) { 
     switch (v.getId()) { 
     case R.id.continue_button: 
     startGame(Game.DIFFICULTY_CONTINUE); 
     break; 
     // ... 

     case R.id.about_button: 
     Intent i = new Intent(this, About.class); 
     startActivity(i); 
     break; 
     // More buttons go here (if any) ... 
     case R.id.new_button: 
     openNewGameDialog(); 
     break; 
     case R.id.exit_button: 
     finish(); 
     break; 

     } 
    } 


    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     super.onCreateOptionsMenu(menu); 
     MenuInflater inflater = getMenuInflater(); 
     inflater.inflate(R.menu.menu, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()) { 
     case R.id.settings: 
     startActivity(new Intent(this, Prefs.class)); 
     return true; 
     // More items go here (if any) ... 
     } 
     return false; 
    } 

    /** Ask the user what difficulty level they want */ 
    private void openNewGameDialog() { 
     new AlertDialog.Builder(this) 
      .setTitle(R.string.new_game_title) 
      .setItems(R.array.difficulty, 
      new DialogInterface.OnClickListener() { 
       public void onClick(DialogInterface dialoginterface, 
        int i) { 
        startGame(i); 
       } 
      }) 
      .show(); 
    } 

    /** Start a new game with the given difficulty level */ 
    private void startGame(int i) { 
     Log.d(TAG, "clicked on " + i); 
     Intent intent = new Intent(Sudoku.this, Game.class); 
     intent.putExtra(Game.KEY_DIFFICULTY, i); 
     startActivity(intent); 
    } 
} 

Game.Java

package org.example.sudoku; 

import android.app.Activity; 
import android.app.Dialog; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.Gravity; 
import android.widget.Toast; 

public class Game extends Activity { 
    private static final String TAG = "Sudoku"; 

    public static final String KEY_DIFFICULTY = 
     "org.example.sudoku.difficulty"; 

    private static final String PREF_PUZZLE = "puzzle" ; 

    public static final int DIFFICULTY_EASY = 0; 
    public static final int DIFFICULTY_MEDIUM = 1; 
    public static final int DIFFICULTY_HARD = 2; 

    protected static final int DIFFICULTY_CONTINUE = -1; 


    private int puzzle[] = new int[9 * 9]; 

    private final String easyPuzzle = 
     "360000000004230800000004200" + 
     "070460003820000014500013020" + 
     "001900000007048300000000045"; 
    private final String mediumPuzzle = 
     "650000070000506000014000005" + 
     "007009000002314700000700800" + 
     "500000630000201000030000097"; 
    private final String hardPuzzle = 
     "009000000080605020501078000" + 
     "000000700706040102004000000" + 
     "000720903090301080000000600"; 

    private PuzzleView puzzleView; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 

     super.onCreate(savedInstanceState); 
     Log.d(TAG, "onCreate"); 

     int diff = getIntent().getIntExtra(KEY_DIFFICULTY, 
      DIFFICULTY_EASY); 
     puzzle = getPuzzle(diff); 
     calculateUsedTiles(); 

     puzzleView = new PuzzleView(this); 
     setContentView(puzzleView); 
     puzzleView.requestFocus(); 


     // ... 
     // If the activity is restarted, do a continue next time 
     getIntent().putExtra(KEY_DIFFICULTY, DIFFICULTY_CONTINUE); 
    } 


    @Override 
    protected void onResume() { 
     super.onResume(); 
     Music.play(this, R.raw.game); 
    } 


    @Override 
    protected void onPause() { 
     super.onPause(); 
     Log.d(TAG, "onPause"); 
     Music.stop(this); 

     // Save the current puzzle 
     getPreferences(MODE_PRIVATE).edit().putString(PREF_PUZZLE, 
      toPuzzleString(puzzle)).commit(); 
    } 



    /** Given a difficulty level, come up with a new puzzle */ 
    private int[] getPuzzle(int diff) { 
     String puz; 
     switch (diff) { 
     case DIFFICULTY_CONTINUE: 
     puz = getPreferences(MODE_PRIVATE).getString(PREF_PUZZLE, 
       easyPuzzle); 
     break; 
     // ... 

     case DIFFICULTY_HARD: 
     puz = hardPuzzle; 
     break; 
     case DIFFICULTY_MEDIUM: 
     puz = mediumPuzzle; 
     break; 
     case DIFFICULTY_EASY: 
     default: 
     puz = easyPuzzle; 
     break; 

     } 
     return fromPuzzleString(puz); 
    } 


    /** Convert an array into a puzzle string */ 
    static private String toPuzzleString(int[] puz) { 
     StringBuilder buf = new StringBuilder(); 
     for (int element : puz) { 
     buf.append(element); 
     } 
     return buf.toString(); 
    } 

    /** Convert a puzzle string into an array */ 
    static protected int[] fromPuzzleString(String string) { 
     int[] puz = new int[string.length()]; 
     for (int i = 0; i < puz.length; i++) { 
     puz[i] = string.charAt(i) - '0'; 
     } 
     return puz; 
    } 

    /** Return the tile at the given coordinates */ 
    private int getTile(int x, int y) { 
     return puzzle[y * 9 + x]; 
    } 

    /** Change the tile at the given coordinates */ 
    private void setTile(int x, int y, int value) { 
     puzzle[y * 9 + x] = value; 
    } 

    /** Return a string for the tile at the given coordinates */ 
    protected String getTileString(int x, int y) { 
     int v = getTile(x, y); 
     if (v == 0) 
     return ""; 
     else 
     return String.valueOf(v); 
    } 

    /** Change the tile only if it's a valid move */ 
    protected boolean setTileIfValid(int x, int y, int value) { 
     int tiles[] = getUsedTiles(x, y); 
     if (value != 0) { 
     for (int tile : tiles) { 
      if (tile == value) 
       return false; 
     } 
     } 
     setTile(x, y, value); 
     calculateUsedTiles(); 
     return true; 
    } 

    /** Open the keypad if there are any valid moves */ 
    protected void showKeypadOrError(int x, int y) { 
     int tiles[] = getUsedTiles(x, y); 
     if (tiles.length == 9) { 
     Toast toast = Toast.makeText(this, 
       R.string.no_moves_label, Toast.LENGTH_SHORT); 
     toast.setGravity(Gravity.CENTER, 0, 0); 
     toast.show(); 
     } else { 
     Log.d(TAG, "showKeypad: used=" + toPuzzleString(tiles)); 
     Dialog v = new Keypad(this, tiles, puzzleView); 
     v.show(); 
     } 
    } 

    /** Cache of used tiles */ 
    private final int used[][][] = new int[9][9][]; 

    /** Return cached used tiles visible from the given coords */ 
    protected int[] getUsedTiles(int x, int y) { 
     return used[x][y]; 
    } 

    /** Compute the two dimensional array of used tiles */ 
    private void calculateUsedTiles() { 
     for (int x = 0; x < 9; x++) { 
     for (int y = 0; y < 9; y++) { 
      used[x][y] = calculateUsedTiles(x, y); 
      // Log.d(TAG, "used[" + x + "][" + y + "] = " 
      // + toPuzzleString(used[x][y])); 
     } 
     } 
    } 

    /** Compute the used tiles visible from this position */ 
    private int[] calculateUsedTiles(int x, int y) { 
     int c[] = new int[9]; 
     // horizontal 
     for (int i = 0; i < 9; i++) { 
     if (i == y) 
      continue; 
     int t = getTile(x, i); 
     if (t != 0) 
      c[t - 1] = t; 
     } 
     // vertical 
     for (int i = 0; i < 9; i++) { 
     if (i == x) 
      continue; 
     int t = getTile(i, y); 
     if (t != 0) 
      c[t - 1] = t; 
     } 
     // same cell block 
     int startx = (x/3) * 3; 
     int starty = (y/3) * 3; 
     for (int i = startx; i < startx + 3; i++) { 
     for (int j = starty; j < starty + 3; j++) { 
      if (i == x && j == y) 
       continue; 
      int t = getTile(i, j); 
      if (t != 0) 
       c[t - 1] = t; 
     } 
     } 
     // compress 
     int nused = 0; 
     for (int t : c) { 
     if (t != 0) 
      nused++; 
     } 
     int c1[] = new int[nused]; 
     nused = 0; 
     for (int t : c) { 
     if (t != 0) 
      c1[nused++] = t; 
     } 
     return c1; 
    } 

} 

PuzzleView.java

package org.example.sudoku; 

import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Paint; 
import android.graphics.Rect; 
import android.graphics.Paint.FontMetrics; 
import android.graphics.Paint.Style; 

import android.os.Bundle; 
import android.os.Parcelable; 

import android.util.Log; 
import android.view.KeyEvent; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.animation.AnimationUtils; 


public class PuzzleView extends View { 

    private static final String TAG = "Sudoku"; 


    private static final String SELX = "selX"; 
    private static final String SELY = "selY"; 
    private static final String VIEW_STATE = "viewState"; 
    private static final int ID = 42; 


    private float width; // width of one tile 
    private float height; // height of one tile 
    private int selX;  // X index of selection 
    private int selY;  // Y index of selection 
    private final Rect selRect = new Rect(); 

    private final Game game; 

    public PuzzleView(Context context) { 

     super(context); 
     this.game = (Game) context; 
     setFocusable(true); 
     setFocusableInTouchMode(true); 

     // ... 
     setId(ID); 
    } 

    @Override 
    protected Parcelable onSaveInstanceState() { 
     Parcelable p = super.onSaveInstanceState(); 
     Log.d(TAG, "onSaveInstanceState"); 
     Bundle bundle = new Bundle(); 
     bundle.putInt(SELX, selX); 
     bundle.putInt(SELY, selY); 
     bundle.putParcelable(VIEW_STATE, p); 
     return bundle; 
    } 
    @Override 
    protected void onRestoreInstanceState(Parcelable state) { 
     Log.d(TAG, "onRestoreInstanceState"); 
     Bundle bundle = (Bundle) state; 
     select(bundle.getInt(SELX), bundle.getInt(SELY)); 
     super.onRestoreInstanceState(bundle.getParcelable(VIEW_STATE)); 
     return; 
    } 


    @Override 
    protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
     width = w/9f; 
     height = h/9f; 
     getRect(selX, selY, selRect); 
     Log.d(TAG, "onSizeChanged: width " + width + ", height " 
      + height); 
     super.onSizeChanged(w, h, oldw, oldh); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     // Draw the background... 
     Paint background = new Paint(); 
     background.setColor(getResources().getColor(
      R.color.puzzle_background)); 
     canvas.drawRect(0, 0, getWidth(), getHeight(), background); 


     // Draw the board... 

     // Define colors for the grid lines 
     Paint dark = new Paint(); 
     dark.setColor(getResources().getColor(R.color.puzzle_dark)); 

     Paint hilite = new Paint(); 
     hilite.setColor(getResources().getColor(R.color.puzzle_hilite)); 

     Paint light = new Paint(); 
     light.setColor(getResources().getColor(R.color.puzzle_light)); 

     // Draw the minor grid lines 
     for (int i = 0; i < 9; i++) { 
     canvas.drawLine(0, i * height, getWidth(), i * height, 
       light); 
     canvas.drawLine(0, i * height + 1, getWidth(), i * height 
       + 1, hilite); 
     canvas.drawLine(i * width, 0, i * width, getHeight(), 
       light); 
     canvas.drawLine(i * width + 1, 0, i * width + 1, 
       getHeight(), hilite); 
     } 

     // Draw the major grid lines 
     for (int i = 0; i < 9; i++) { 
     if (i % 3 != 0) 
      continue; 
     canvas.drawLine(0, i * height, getWidth(), i * height, 
       dark); 
     canvas.drawLine(0, i * height + 1, getWidth(), i * height 
       + 1, hilite); 
     canvas.drawLine(i * width, 0, i * width, getHeight(), dark); 
     canvas.drawLine(i * width + 1, 0, i * width + 1, 
       getHeight(), hilite); 
     } 

     // Draw the numbers... 
     // Define color and style for numbers 
     Paint foreground = new Paint(Paint.ANTI_ALIAS_FLAG); 
     foreground.setColor(getResources().getColor(
      R.color.puzzle_foreground)); 
     foreground.setStyle(Style.FILL); 
     foreground.setTextSize(height * 0.75f); 
     foreground.setTextScaleX(width/height); 
     foreground.setTextAlign(Paint.Align.CENTER); 

     // Draw the number in the center of the tile 
     FontMetrics fm = foreground.getFontMetrics(); 
     // Centering in X: use alignment (and X at midpoint) 
     float x = width/2; 
     // Centering in Y: measure ascent/descent first 
     float y = height/2 - (fm.ascent + fm.descent)/2; 
     for (int i = 0; i < 9; i++) { 
     for (int j = 0; j < 9; j++) { 
      canvas.drawText(this.game.getTileString(i, j), i 
        * width + x, j * height + y, foreground); 
     } 
     } 


     if (Prefs.getHints(getContext())) { 
     // Draw the hints... 

     // Pick a hint color based on #moves left 
     Paint hint = new Paint(); 
     int c[] = { getResources().getColor(R.color.puzzle_hint_0), 
       getResources().getColor(R.color.puzzle_hint_1), 
       getResources().getColor(R.color.puzzle_hint_2), }; 
     Rect r = new Rect(); 
     for (int i = 0; i < 9; i++) { 
      for (int j = 0; j < 9; j++) { 
       int movesleft = 9 - game.getUsedTiles(i, j).length; 
       if (movesleft < c.length) { 
        getRect(i, j, r); 
        hint.setColor(c[movesleft]); 
        canvas.drawRect(r, hint); 
       } 
      } 
     } 

     } 


     // Draw the selection... 
     Log.d(TAG, "selRect=" + selRect); 
     Paint selected = new Paint(); 
     selected.setColor(getResources().getColor(
      R.color.puzzle_selected)); 
     canvas.drawRect(selRect, selected); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     if (event.getAction() != MotionEvent.ACTION_DOWN) 
     return super.onTouchEvent(event); 

     select((int) (event.getX()/width), 
      (int) (event.getY()/height)); 
     game.showKeypadOrError(selX, selY); 
     Log.d(TAG, "onTouchEvent: x " + selX + ", y " + selY); 
     return true; 
    } 

    @Override 
    public boolean onKeyDown(int keyCode, KeyEvent event) { 
     Log.d(TAG, "onKeyDown: keycode=" + keyCode + ", event=" 
      + event); 
     switch (keyCode) { 
     case KeyEvent.KEYCODE_DPAD_UP: 
     select(selX, selY - 1); 
     break; 
     case KeyEvent.KEYCODE_DPAD_DOWN: 
     select(selX, selY + 1); 
     break; 
     case KeyEvent.KEYCODE_DPAD_LEFT: 
     select(selX - 1, selY); 
     break; 
     case KeyEvent.KEYCODE_DPAD_RIGHT: 
     select(selX + 1, selY); 
     break; 
     case KeyEvent.KEYCODE_0: 
     case KeyEvent.KEYCODE_SPACE: setSelectedTile(0); break; 
     case KeyEvent.KEYCODE_1:  setSelectedTile(1); break; 
     case KeyEvent.KEYCODE_2:  setSelectedTile(2); break; 
     case KeyEvent.KEYCODE_3:  setSelectedTile(3); break; 
     case KeyEvent.KEYCODE_4:  setSelectedTile(4); break; 
     case KeyEvent.KEYCODE_5:  setSelectedTile(5); break; 
     case KeyEvent.KEYCODE_6:  setSelectedTile(6); break; 
     case KeyEvent.KEYCODE_7:  setSelectedTile(7); break; 
     case KeyEvent.KEYCODE_8:  setSelectedTile(8); break; 
     case KeyEvent.KEYCODE_9:  setSelectedTile(9); break; 
     case KeyEvent.KEYCODE_ENTER: 
     case KeyEvent.KEYCODE_DPAD_CENTER: 
     game.showKeypadOrError(selX, selY); 
     break; 
     default: 
     return super.onKeyDown(keyCode, event); 
     } 
     return true; 
    } 

    public void setSelectedTile(int tile) { 
     if (game.setTileIfValid(selX, selY, tile)) { 
     invalidate();// may change hints 
     } else { 
     // Number is not valid for this tile 
     Log.d(TAG, "setSelectedTile: invalid: " + tile); 
     startAnimation(AnimationUtils.loadAnimation(game, 
       R.anim.shake)); 
     } 
    } 

    private void select(int x, int y) { 
     invalidate(selRect); 
     selX = Math.min(Math.max(x, 0), 8); 
     selY = Math.min(Math.max(y, 0), 8); 
     getRect(selX, selY, selRect); 
     invalidate(selRect); 
    } 

    private void getRect(int x, int y, Rect rect) { 
     rect.set((int) (x * width), (int) (y * height), (int) (x 
      * width + width), (int) (y * height + height)); 
    } 

    // ... 
} 

回答

相關問題