проверка java awt 2D-игры, проблема с фоновым обновлением jbutton - PullRequest
2 голосов
/ 12 февраля 2011

Я публикую простой код игры, написанный на Java.Мне потребовались мои часы сегодня, чтобы написать это, но теперь я застрял!Проблема в том, что на втором уровне этой игры (после неудачи или успеха) я не вижу красных плиток.Работает только в первый раз.

логика игры: она запускается с матрицей 3х3 и в случае успеха восстанавливает размерность этой матрицы (проверка способности памяти, запоминание координат красных плиток за 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 ]

2 голосов
/ 12 февраля 2011

В предыдущем сообщении вы сказали НЕ использовать метод update ().

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

Кроме того, никогда не используйте такую ​​тесную петлю. Это так же плохо, как использование Thread.sleep (...);

Вы, где даны предложения в вашем последнем сообщении!

1 голос
/ 15 апреля 2016

Я думаю, вы можете использовать LWJGL, библиотеку Java-игр.

https://www.lwjgl.org

1 голос
/ 12 февраля 2011

Некоторые проблемы могут быть связаны с потоком, в котором выполняется различный бит кода.При первом запуске вы работаете в потоке «Main», и чтобы быть полностью правильными, вызовы для обновления графического интерфейса AWT / Swing должны выполняться с помощью «Thread Dispatcher Thread».

Метод actionPerformedвызывается из «потока диспетчера событий», а затем во второй раз, когда вы вызываете конструктор для Memory, вы находитесь в этом потоке.

Кроме того, что вы реализовали задержку с вращениемпетля, которая не эффективна;Вы не должны откладывать «Поток диспетчера событий».

См. этот краткий обзор: http://www.javamex.com/tutorials/threads/swing_ui.shtml

...