程序在俄罗斯方块克隆中绘制相同的块

时间:2017-07-13 19:16:41

标签: java swing awt tetris

我写了一个小俄罗斯方块克隆。块是随机的,但是在6或7个块之后程序开始反复绘制相同的块,即使将随机块传递给paintBlock()方法。

绘制俄罗斯方块板的类:

       import blocks.AbstractBlock;
    import blocks.BlockController;
    import scores.ScoreController;

    import javax.swing.*;
    import java.awt.*;


    public class GameBoard extends JPanel {
        public static final Integer boardWidth = 10;
        public static final Integer boardHeight = 20;
        public static final Integer cellWidth = 25;
        public static final Integer cellHeight = 25;
        private Cell[][] board = new Cell[boardWidth][boardHeight];
        private Integer iterations;
        private Boolean shutdown;
        private AbstractBlock currentBlock;
        private Long timestamp;

        private Thread movement = new Thread(() -> {
            while (!shutdown) {
                    if((System.currentTimeMillis() - timestamp) > ScoreController.getDelay()) {
                        repaint();
                        moveDown();
                        timestamp = System.currentTimeMillis();
                    }
            }
        });

        public void init() {
            for (int i = 0; i < boardWidth; i++) {
                for (int j = 0; j < boardHeight; j++) {
                    board[i][j] = new Cell(i, j);
                }
            }
            BlockController.init();
            ScoreController.init();
            currentBlock = BlockController.getRandomBlock();
            iterations = 0;
            timestamp = System.currentTimeMillis();
            shutdown = false;
            movement.start();
        }

        public synchronized void moveDown() {
            Point position = BlockController.getBlockPosition();
            if (!findCollisions(position.x, position.y + 1)) {
                BlockController.setBlockPosition(new Cell(position.x, position.y + 1));
                iterations += 1;
                this.repaint();
            } else {
                if (iterations > 0) {
                    secureBlock();
                    clearRows();
                    currentBlock = BlockController.getRandomBlock();
                    iterations = 0;
                } else {
                    shutdown();
                }
            }
        }

        private Boolean findCollisions(Integer x, Integer y) {
            for (Cell cell : currentBlock.getShapes()[BlockController.getRotationScale()]) {
                if (cell.y + y >= boardHeight || cell.x + x >= boardWidth || cell.x + x < 0 ||
                        !(board[cell.x + x][cell.y + y].getColor() == cell.getDefaultColor())) {
                    return true;
                }
            }
            return false;
        }

        public void moveHorizontal(Integer dx) {
            Point position = BlockController.getBlockPosition();
            if (!findCollisions(position.x + dx, position.y)) {
                BlockController.setBlockPosition(new Cell(position.x + dx, position.y));
            }
            repaint();
        }

        private void secureBlock() {
            Cell position = BlockController.getBlockPosition();
            for (Cell cell : currentBlock.getShapes()[BlockController.getRotationScale()]) {
                board[position.x + cell.x][position.y + cell.y].setColor(currentBlock.getColor());
            }
            repaint();
        }

        private void clearRows() {
            Integer rowsCleared = 0;
            Boolean gap;
            for (int j = boardHeight - 1; j >= 0; j--) {
                gap = false;
                for (int i = 0; i < boardWidth; i++) {
                    if (board[i][j].getColor() == board[i][j].getDefaultColor()) {
                        gap = true;
                        break;
                    }
                }
                if (!gap) {
                    deleteRow(j);
                    j = boardHeight - 1;
                    repaint();
                    rowsCleared++;
                }
            }
            if (rowsCleared != 0) {
                ScoreController.rowsCleared(rowsCleared);
            }
        }

        private void deleteRow(Integer y) {
            for (int j = y; j > 0; j--) {
                for (int i = 0; i < boardWidth; i++) {
                    board[i][j].setColor(board[i][j - 1].getColor());
                }
            }
        }

        public void shutdown() {
            shutdown = true;
        }

        public void rotate() {
            BlockController.rotate();
            repaint();
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            paintGameBoard(g);
            paintBlock(g);
        }

        private void paintGameBoard(Graphics g) {
            for (int i = 0; i < boardWidth; i++) {
                for (Cell cell : board[i]) {
                    g.setColor(cell.getColor());
                    g.drawRect(cell.x * cellWidth, cell.y * cellHeight, cellWidth, cellHeight);
                    g.fillRect(cell.x * cellWidth, cell.y * cellHeight, cellWidth, cellHeight);
                }
            }
            g.setColor(Color.WHITE);
            g.drawString("Score: " + ScoreController.getScore(), 10, 20);
            g.drawString("Level: " + ScoreController.getLevel(), 10, 40);
            g.drawString("Rows Cleared: " + ScoreController.getRows(), 10, 60);
        }

        private void paintBlock(Graphics g) {
            Cell position = BlockController.getBlockPosition();
            if (currentBlock != null) {
                for (Cell cell : currentBlock.getShapes()[BlockController.getRotationScale()]) {
                    g.setColor(currentBlock.getColor());
                    g.drawRect((position.x + cell.x) * cellWidth, (position.y + cell.y) * cellHeight, cellWidth, cellHeight);
                    g.fillRect((position.x + cell.x) * cellWidth, (position.y + cell.y) * cellHeight, cellWidth, cellHeight);
                }
            }
        }
    }

我找不到这个问题的解决方案,所以欢迎任何建议。提前谢谢。

Edit1:BlockController类 - 用于返回随机块和其他一些东西。

    import board.Cell;
    import com.google.common.collect.Iterables;

    import java.util.*;
    import java.util.List;

    public class BlockController {

        private static List<String> blockNames = Arrays.asList("I", "J", "L", "O", "S", "T", "Z");
        private static Integer rotationScale;
        private static Cell blockPosition;
        private static final List<Integer> rotations = Arrays.asList(0, 1, 2, 3);
        private static Iterator<Integer> rotationCycle = Iterables.cycle(rotations).iterator();

        private BlockController(){}

        private static AbstractBlock getBlock(String name) {
            switch(name) {
                case "I" : return I_block.getInstance();
                case "J" : return J_block.getInstance();
                case "L" : return L_block.getInstance();
                case "O" : return O_block.getInstance();
                case "S" : return S_block.getInstance();
                case "T" : return T_block.getInstance();
                case "Z" : return Z_block.getInstance();
                default : return null;
            }
        }

        public static void init() {
            setBlockPosition(new Cell(3,0));
            setRotationScale(0);
        }

        public static Cell getBlockPosition() {
            return blockPosition;
        }

        public static void setBlockPosition(Cell blockPosition) {
            BlockController.blockPosition = blockPosition;
        }

        public static Integer getRotationScale() {
            return rotationScale;
        }

        private static void setRotationScale(Integer rotationScale) {
            BlockController.rotationScale = rotationScale;
        }

        public static AbstractBlock getRandomBlock() {
            setBlockPosition(new Cell(3, 0));
            setRotationScale(0);
            rotationCycle = Iterables.cycle(rotations).iterator();
            Collections.shuffle(blockNames);
            return getBlock(blockNames.get(0));
        }

        public static void rotate() {
            setRotationScale(rotationCycle.next());
        }
    }

1 个答案:

答案 0 :(得分:0)

这是由于我以某种方式得到我的积木的方式。块的简单映射而不是一堆单例帮助我解决了这个问题。 感谢davidxxx提供了这方面的建议。