给个俄罗斯方块代码详解

做不出来,帮个忙!谢谢各位了,新手上路,不会做,结课实训,太难实现了

https://blog.csdn.net/Zp_insist/article/details/124740009

参考gpt:
下面是一个简单的俄罗斯方块游戏的 Java 实现示例,附带了一些基本的注释以解释代码的功能和工作原理:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Tetris extends JPanel {

    private final int BOARD_WIDTH = 10;
    private final int BOARD_HEIGHT = 22;
    private final int BLOCK_SIZE = 30;

    private List<Point> occupiedBlocks;
    private Point currentBlock;
    private int currentBlockType;
    private int rotation;

    private Timer timer;
    private boolean isGameOver;

    private int[][][] tetrominoes = {
        // 俄罗斯方块的所有形状,3D 数组,分别表示不同方向的形状
        // 第一维表示方块的类型(共7种),第二维和第三维表示方块的形状
        // 0 表示空白,1 表示方块
        {
            {0, 0, 0, 0},
            {1, 1, 1, 1},
            {0, 0, 0, 0},
            {0, 0, 0, 0}
        },
        // 其他方块形状...
    };

    private Color[] blockColors = {
        // 不同方块类型对应的颜色
        Color.BLACK,
        Color.CYAN,
        Color.BLUE,
        Color.ORANGE,
        Color.YELLOW,
        Color.GREEN,
        Color.MAGENTA,
        Color.RED
    };

    public Tetris() {
        initGame();
        setFocusable(true);
        addKeyListener(new TetrisKeyListener());
    }

    private void initGame() {
        occupiedBlocks = new ArrayList<>();
        currentBlock = new Point(0, 0);
        currentBlockType = new Random().nextInt(7) + 1;
        rotation = 0;
        timer = new Timer(1000, new TimerActionListener());
        isGameOver = false;
        timer.start();
    }

    private void updateGame() {
        if (isCollision(currentBlock.x, currentBlock.y + 1, rotation)) {
            // 方块到达底部或碰撞到其他方块
            addOccupiedBlocks();
            checkLines();
            currentBlock = new Point(0, 0);
            currentBlockType = new Random().nextInt(7) + 1;
            rotation = 0;
            if (isCollision(currentBlock.x, currentBlock.y, rotation)) {
                // 新生成的方块也无法放置,游戏结束
                isGameOver = true;
                timer.stop();
            }
        } else {
            // 方块下落一格
            currentBlock.y++;
        }

        repaint();
    }

    private boolean isCollision(int x, int y, int rotation) {
        // 检查当前方块是否与已占用的方块或边界碰撞
        int[][] currentTetromino = tetrominoes[currentBlockType][rotation];
        for (int row = 0; row < currentTetromino.length; row++) {
            for (int col = 0; col < currentTetromino[row].length; col++) {
                if (currentTetromino[row][col] == 1) {
                    int blockX = x + col;
                    int blockY = y + row;
                    if (blockY >= BOARD_HEIGHT || blockX < 0 || blockX >= BOARD_WIDTH
                            || isBlockOccupied(blockX, blockY)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    private boolean isBlockOccupied(int x, int y) {
        // 检查指定位置的方块是否已占用
        return occupiedBlocks.stream().anyMatch(p -> p.x == x && p.y == y);
    }

    private void addOccupiedBlocks() {
        // 将当前方块的位置添加到已占用方块列表中
        int[][] currentTetromino = tetrominoes[currentBlockType][rotation];
        for (int row = 0; row < currentTetromino.length; row++) {
            for (int col = 0; col < currentTetromino[row].length; col++) {
                if (currentTetromino[row][col] == 1) {
                    int blockX = currentBlock.x + col;
                    int blockY = currentBlock.y + row;
                    occupiedBlocks.add(new Point(blockX, blockY));
                }
            }
        }
    }

    private void checkLines() {
        // 检查是否有可以消除的行,若有则删除行并更新已占用方块列表
        for (int row = BOARD_HEIGHT - 1; row >= 0; row--) {
            boolean isLineFilled = true;
            for (int col = 0; col < BOARD_WIDTH; col++) {
                if (!isBlockOccupied(col, row)) {
                    isLineFilled = false;
                    break;
                }
            }
            if (isLineFilled) {
                deleteLine(row);
                row++; // 下一行需要重新检查
            }
        }
    }

    private void deleteLine(int row) {
        // 删除指定行并更新已占用方块列表
        occupiedBlocks.removeIf(p -> p.y == row);
        for (Point p : occupiedBlocks) {
            if (p.y < row) {
                p.y++; // 所有行下移一格
            }
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        drawBoard(g);
        drawOccupiedBlocks(g);
        drawCurrentBlock(g);
        if (isGameOver) {
            drawGameOver(g);
        }
    }

    private void drawBoard(Graphics g) {
        // 绘制游戏区域的边界
        g.setColor(Color.BLACK);
        g.drawRect(0, 0, BOARD_WIDTH * BLOCK_SIZE, BOARD_HEIGHT * BLOCK_SIZE);
    }

    private void drawOccupiedBlocks(Graphics g) {
        // 绘制已占用的方块
        for (Point p : occupiedBlocks) {
            drawBlock(g, p.x, p.y, getBlockColor(p));
        }
    }

    private void drawCurrentBlock(Graphics g) {
        // 绘制当前方块
        int[][] currentTetromino = tetrominoes[currentBlockType][rotation];
        for (int row = 0; row < currentTetromino.length; row++) {
            for (int col = 0; col < currentTetromino[row].length; col++) {
                if (currentTetromino[row][col] == 1) {
                    int blockX = currentBlock.x + col;
                    int blockY = currentBlock.y + row;
                    drawBlock(g, blockX, blockY, blockColors[currentBlockType]);
                }
            }
        }
    }

    private void drawBlock(Graphics g, int x, int y, Color color) {
        // 绘制一个方块
        g.setColor(color);
        g.fillRect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
        g.setColor(Color.BLACK);
        g.drawRect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
    }

    private Color getBlockColor(Point p) {
        // 获取指定位置方块的颜色
        for (int i = 1; i < tetrominoes.length; i++) {
            int[][] currentTetromino = tetrominoes[i][rotation];
            for (int row = 0; row < currentTetromino.length; row++) {
                for (int col = 0; col < currentTetromino[row].length; col++) {
                    if (currentTetromino[row][col] == 1 && p.x == currentBlock.x + col
                            && p.y == currentBlock.y + row) {
                        return blockColors[i];
                    }
                }
            }
        }
        return null;
    }

    private void drawGameOver(Graphics g) {
        // 绘制游戏结束的提示信息
        g.setColor(Color.RED);
        g.drawString("Game Over", BLOCK_SIZE, BLOCK_SIZE);
    }

    private class TimerActionListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            updateGame();
        }
    }

    private class TetrisKeyListener implements KeyListener {

        @Override
        public void keyPressed(KeyEvent e) {
            if (!isGameOver) {
                if (e.getKeyCode() == KeyEvent.VK_LEFT) {
                    // 左移
                    if (!isCollision(currentBlock.x - 1, currentBlock.y, rotation)) {
                        currentBlock.x--;
                    }
                } else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
                    // 右移
                    if (!isCollision(currentBlock.x + 1, currentBlock.y, rotation)) {
                        currentBlock.x++;
                    }
                } else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
                    // 加速下落
                    if (!isCollision(currentBlock.x, currentBlock.y + 1, rotation)) {
                        currentBlock.y++;
                    }
                } else if (e.getKeyCode() == KeyEvent.VK_UP) {
                    // 旋转
                    int newRotation = (rotation + 1) % 4;
                    if (!isCollision(currentBlock.x, currentBlock.y, newRotation)) {
                        rotation = newRotation;
                    }
                }
            }

            repaint();
        }

        @Override
        public void keyTyped(KeyEvent e) {}

        @Override
        public void keyReleased(KeyEvent e) {}
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("Tetris");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(320, 480);
        frame.add(new Tetris());
        frame.setVisible(true);
    }
}

这个示例代码实现了一个简单的俄罗斯方块游戏。它使用 Java 的 Swing 库进行图形界面的绘制和交互。游戏区域由一个矩形网格表示,方块通过不断下落来填充网格,并在填满一行时消除。你可以根据需要对代码进行修改和扩展,以实现更多功能。