2011-02-12 76 views
2

我發佈了一個簡單的遊戲代碼,用java編寫。今天花了我的時間來寫這個,但現在我卡住了!問題是,在這場比賽的第二級別(失敗或成功之後),我看不到紅瓦。它只有第一次運作。檢查java awt 2D遊戲,jbutton後臺更新問題

遊戲邏輯: 它啓動時使用3x3矩陣,並在成功的情況下(測試內存的能力,在1200毫秒內記憶紅色方塊的座標)反彈此矩陣的維數。所以我們首先顯示紅色瓷磚,而不是我們檢查估計。如果出現錯誤的嘗試,失敗!如果它是一個比3x3更大的矩陣,它會變小。

該代碼有點長,但只有一個類,所以它很容易執行它。如果你有時間我會很感激。

所以就這樣吧:

package skeleton; 


public class Memory extends JFrame implements ActionListener { 

private static final long serialVersionUID = 5963518754230629235L; 

private static int minDimX = 3, minDimY = 3; 
private static int maxDimX = 15, maxDimY = 15; 
private static int counter = 13; 
private static int memoriseTime = 1200; // milliseconds 
private static int memGridWidthX = 60; 
private static int memGridWidthY = 60; 

private JPanel centerPanel; 
private JButton memTile; 
private Random generator; 
private int memGridDimX, memGridDimY, coef, numberOfMemTilesToGuess; 
int[][] memTileCoordinates; 
int[] randomNums; 

Border grayBorder = LineBorder.createGrayLineBorder(); 


public Memory(int xDim, int yDim) { 

    waitALittleBit(1300); 

    memGridDimX = xDim; 
    memGridDimY = yDim; 
    coef = 3; 
    numberOfMemTilesToGuess = memGridDimX*memGridDimY/coef; 

    centerPanel = new JPanel(); 
    centerPanel.setLayout(new GridLayout(memGridDimY, memGridDimX, 0, 0)); 

    add(centerPanel, BorderLayout.CENTER); 

    System.out.println("int[" + memGridDimX + "][" + memGridDimY + "] array is created "); 

    randomNums = new int[numberOfMemTilesToGuess]; 

    for (int i = 0 ; i < numberOfMemTilesToGuess ; i ++) { 
     System.out.println("> we are in for the "+ (i+1) +". time!"); 

     int randomNum; 
     boolean randomNumberAlreadySelected = false; 

     do { 
      randomNum = calculateARandomNumber(memGridDimX * memGridDimY); 
      if (i != 0) { //for the first time, we don't need to compare any numbers 
       randomNumberAlreadySelected = isThisRandomNumberExistInAlreadyFoundRandomNumbersArray(randomNum, randomNums, i); 
       if (randomNumberAlreadySelected) 
        System.out.println("######## RECALCULATING RANDOM NUMBER !! ##########"); 
       else 
        System.out.println("They are not equal, go on!"); 
      } 
     } while (randomNumberAlreadySelected); 

     randomNums[i] = (Integer)randomNum; 
    } 

    //show the memory tiles 
    setMemTiles(randomNums, true); 

    waitALittleBit(memoriseTime); 

    //hide the memory tiles 
    setMemTiles(randomNums, false); 

} 

private int calculateARandomNumber(int limit) { 

    generator = new Random(); 

    System.out.println("* Calculating random number which is smaller than " + memGridDimX * memGridDimY); 
    int randomNum = generator.nextInt() % (memGridDimX * memGridDimY); 
    System.out.println("- Calculated random number: " + randomNum); 
    if (randomNum < 0) { 
     System.out.println(".. it is negative, so we add: " + memGridDimX * memGridDimY); 
     randomNum += memGridDimX * memGridDimY;   
    } 

    System.out.println(".. and we add 1 to have a grid array between 1 and 12"); 
    randomNum += 1; 
    System.out.println(".. and our new random number is: " + randomNum); 

    return randomNum; 
} 

private boolean isThisRandomNumberExistInAlreadyFoundRandomNumbersArray(int number, int[] numberArr, int numberArrSize) { 

    for (int j = 0 ; j < numberArrSize ; j ++) { 
     System.out.println("# Comparing random number: " + number + " and " + (j+1) + ". random number selected earlier: " + numberArr[j]); 
     if (number == numberArr[j]) 
      return true; 
    } 

    return false; 
} 

private void setMemTiles(int[] randomNums, boolean showMemTiles) { 

    centerPanel.removeAll(); 

    memTileCoordinates = new int[randomNums.length][2]; 

    for (int i = 1 ; i <= memGridDimY ; i ++) { 
     for (int j = 1 ; j <= memGridDimX ; j ++) { 

      int rnX = -1; 
      int rnY = -1; 
      boolean isMemTile = false; 
      for (int k = 0 ; k < randomNums.length ; k ++) { 
       int rn = randomNums[k]; 

       if (rn % memGridDimX == 0) { 
        rnY = rn/memGridDimX; 
        rnX = memGridDimX; 
       } else { 
        rnY = rn/memGridDimX + 1; 
        rnX = rn % memGridDimX; 
       } 
       if (i == 1 && j == 1 && !showMemTiles) { //do it once 
        System.out.println("*********  ************"); 
        System.out.println("Random label number: " + rn + " and it's position in the grid: " + rnX + "," + rnY); 

        memTileCoordinates[k][0] = rnX; 
        memTileCoordinates[k][1] = rnY; 
        System.out.println("> Memory Tiles coordinates: " + memTileCoordinates[k][0] + "," + memTileCoordinates[k][1]); 
        System.out.println("> Memory Tiles length: " + memTileCoordinates.length); 
        System.out.println("*********  ************"); 
       } 

       if (rnX == j && rnY == i) 
        isMemTile = true; 
      } 

      memTile = new JButton(); 
      if (isMemTile) { 
       update(getGraphics()); 
       if (showMemTiles) { 
        memTile.setBackground(Color.red); 
        System.out.println("%%%% PAINTING MEM TILES IN RED %%%%"); 
       } else 
        memTile.setBackground(Color.white); 
       update(getGraphics()); 
      } else 
       memTile.setBackground(Color.white); 
      if (!showMemTiles) // we listen actions after the memory tiles disappears 
       memTile.addActionListener(this); 

      centerPanel.add(memTile); 
      update(getGraphics()); 
     } 
    } 

    setJPanelSettings(); 
} 

private void setJPanelSettings() { 

    setSize(memGridDimX * memGridWidthX, memGridDimY * memGridWidthY); 
    setTitle("Memory :: " + memGridDimX + "x" + memGridDimY); 
    setResizable(false); 
    setLocationRelativeTo(null); 
    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
    setVisible(true); 
} 

private void waitALittleBit(long waitingMillisSeconds) { 
    long t0 = System.currentTimeMillis(); 
    long t1 ; 

    do { 
     t1 = System.currentTimeMillis(); 
    } while (t1 - t0 < waitingMillisSeconds); 

} 

public static void main(String[] args) { 

    new Memory(minDimX,minDimY); 

} 

@Override 
public void actionPerformed(ActionEvent e) { 

    System.out.println(">>> An action came >>>"); 

    JButton memTile = (JButton) e.getSource(); 
    Dimension size = memTile.getSize(); 

    int chosenMemTileDimX = memTile.getX(); 
    int chosenMemTileDimY = memTile.getY(); 
    int chosenMemTilePosX = chosenMemTileDimX/size.width + 1; // we add 1 becausee we present our tile numbers as 1:1, 1:2, ... (instead of 0:0,0:1, ...) 
    int chosenMemTilePosY = chosenMemTileDimY/size.height + 1; 

    System.out.println("Chosen Tile's x dimension: " + chosenMemTileDimX + " ans y dimension: " + chosenMemTileDimY); 
    System.out.println("Chosen Tile's width: " + size.width + " and height: " + size.height); 
    System.out.println("Chosen Tile's coordinates: " + chosenMemTilePosX + ", " + chosenMemTilePosY); 

    boolean tileIsMemTile = false; 

    System.out.println("Memory Tiles Coordinates: "); 
    for (int i = 0 ; i < memTileCoordinates.length ; i ++) { 

     int memTileDimX = memTileCoordinates[i][0]; 
     int memTileDimY = memTileCoordinates[i][1]; 
     System.out.println("x: " + memTileDimX + ", y: " + memTileDimY); 
     if (chosenMemTilePosX == memTileDimX && chosenMemTilePosY == memTileDimY) 
      tileIsMemTile = true; 
    } 

    if (tileIsMemTile) { 
     System.out.println("!!! Right Tile !!!"); 
     memTile.setBackground(Color.red); 
     numberOfMemTilesToGuess -= 1; 
     System.out.println("It rest " + numberOfMemTilesToGuess + " tiles to guess"); 
    } else { 
     System.out.println("!!! Wrong Tile !!!"); 
     Icon falseTileIcon; 
     try { 
      falseTileIcon = new ImageIcon(getClass().getResource("wrong.png")); 
      if (falseTileIcon.getIconHeight() > 0) 
       memTile.setIcon(falseTileIcon); 
     } catch (Exception e1) { 
      memTile.setBackground(Color.black); 
     } 
     update(getGraphics()); // good trick!! 
     waitALittleBit(1000); 

     //TODO !!! FAILED IN LEVEL MESSAGE !!! 
     dispose(); 

     if (memGridDimX == minDimX && (memGridDimY == minDimY || memGridDimY == minDimY + 1)) 
      new Memory(minDimX, minDimY); 
     else if (memGridDimX == memGridDimY) 
      new Memory(memGridDimX - 1, memGridDimY); 
     else 
      new Memory(memGridDimX, memGridDimY -1); 
    } 

    System.out.println(">>> Action processed >>>"); 

    if (numberOfMemTilesToGuess == 0) { 
     System.out.println("\n END OF THE LEVEL"); 
     System.out.println("Congratulations, you guessed all the tiles without error !! \n"); 

     dispose(); 
     //TODO !!!! SHOW INTERLEVEL INFORMATION !!!! 

     if (memGridDimX != maxDimX && memGridDimY != maxDimY) { 
      if (memGridDimX == memGridDimY) 
       new Memory(memGridDimX, memGridDimY + 1); 
      else 
       new Memory(memGridDimX + 1, memGridDimY); 
     } else 
      System.out.println("You have a really good memory my friend!"); 
    } 
}} 

我以前更新(的getGraphics());很多次,這只是一個測試... 在此先感謝。

+0

我最後的編輯後,我試圖取代 「更新(的getGraphics());」之後的「setMemTiles(randomNums,true);」方法,它的工作! – redmorning 2011-02-12 03:55:16

回答

2

你在上次發帖告訴不使用update()方法的地方。

do 
{   
    t1 = System.currentTimeMillis();  
} 
while (t1 - t0 < waitingMillisSeconds); 

另外,千萬不要使用這樣的緊密循環。它和使用Thread.sleep(...)一樣糟糕;

你在哪裏給你最後發佈的建議!

1

一些問題可能是由於運行各種代碼的線程所致。第一次通過你在「Main」線程上運行,並且完全正確的更新AWT/Swing GUI的調用應該使用「Event Dispatcher Thread」完成。

actionPerformed方法是從「Event Dispatcher Thread」中調用的,然後第二次調用Memory的構造函數時,你就在這個線程中。另外,除了事實上你已經用自旋循環實現了延遲,這是不高效的;你不應該延遲「事件調度程序線程」。

看到這個簡短的概述:http://www.javamex.com/tutorials/threads/swing_ui.shtml