检查java awt 2D游戏,jbutton后台更新问题

时间:2011-02-12 03:47:52

标签: java 2d awt jbutton

我发布了一个用java编写的简单游戏代码。今天花了我几个小时写这个,但现在我被卡住了!问题是,在这个游戏的第二级(失败或成功后)我看不到红色的瓷砖。它只是第一次工作。

游戏逻辑: 它以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!");
    }
}}

我多次使用 update(getGraphics()); ,它仅用于测试...... 提前谢谢。

3 个答案:

答案 0 :(得分:2)

你在上次发帖中告诉你不要使用update()方法。

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

此外,永远不要使用这样的紧密循环。它与使用Thread.sleep(...);

一样糟糕

您在上次发布时给出了建议!

答案 1 :(得分:1)

某些问题可能是由运行各种代码的线程引起的。第一次通过你在“主”线程上运行,并且要完全正确调用更新AWT / Swing GUI应该使用“事件调度程序线程”完成。

从“事件调度程序线程”调用actionPerformed方法,然后第二次调用Memory的构造函数时,您就在此线程中。

另外,除了使用自旋循环实现延迟的事实,这是无效的;你不应该推迟“事件调度程序线程”。

请参阅此简短概述:http://www.javamex.com/tutorials/threads/swing_ui.shtml

答案 2 :(得分:1)

我认为你可以使用LWJGL,这是一个java游戏库。

https://www.lwjgl.org