Java制作俄罗斯方块

Java俄罗斯方块小游戏

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class TetrisGame extends JFrame implements ActionListener, KeyListener {

    private final int BOARD_WIDTH = 10;
    private final int BOARD_HEIGHT = 20;
    private final int CELL_SIZE = 30;

    private Timer timer;
    private Board board;
    private Shape currentShape;

    public TetrisGame() {
        initUI();
    }

    private void initUI() {
        board = new Board();
        add(board);

        timer = new Timer(500, this);
        timer.start();

        setTitle("俄罗斯方块游戏");
        setSize(BOARD_WIDTH * CELL_SIZE, BOARD_HEIGHT * CELL_SIZE);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        addKeyListener(this);
        setFocusable(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            TetrisGame tetrisGame = new TetrisGame();
            tetrisGame.setVisible(true);
        });
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        // 定时器触发,尝试向下移动当前方块
        if (board.canMoveDown(currentShape)) {
            currentShape.moveDown();
        } else {
            // 如果无法继续下移,将当前方块加入游戏板并生成新的方块
            board.addShape(currentShape);
            currentShape = new Shape();
            if (!board.canMoveDown(currentShape)) {
                // 如果新生成的方块无法下移,游戏结束
                timer.stop();
                JOptionPane.showMessageDialog(this, "游戏结束!");
                System.exit(0);
            }
        }
        repaint();
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyPressed(KeyEvent e) {
        // 根据按键事件执行相应操作
        if (e.getKeyCode() == KeyEvent.VK_LEFT && board.canMoveLeft(currentShape)) {
            // 左移
            currentShape.moveLeft();
        } else if (e.getKeyCode() == KeyEvent.VK_RIGHT && board.canMoveRight(currentShape)) {
            // 右移
            currentShape.moveRight();
        } else if (e.getKeyCode() == KeyEvent.VK_DOWN && board.canMoveDown(currentShape)) {
            // 下移
            currentShape.moveDown();
        } else if (e.getKeyCode() == KeyEvent.VK_SPACE && board.canRotate(currentShape)) {
            // 旋转
            currentShape.rotate();
        }
        repaint();
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }

    // 游戏板
    class Board extends JPanel {

        private boolean[][] filledCells;

        public Board() {
            filledCells = new boolean[BOARD_HEIGHT][BOARD_WIDTH];
            currentShape = new Shape();
        }

        // 判断是否可以左移
        public boolean canMoveLeft(Shape shape) {
            for (Cell cell : shape.getCells()) {
                if (cell.getX() <= 0 || filledCells[cell.getY()][cell.getX() - 1]) {
                    return false;
                }
            }
            return true;
        }

        // 判断是否可以右移
        public boolean canMoveRight(Shape shape) {
            for (Cell cell : shape.getCells()) {
                if (cell.getX() >= BOARD_WIDTH - 1 || filledCells[cell.getY()][cell.getX() + 1]) {
                    return false;
                }
            }
            return true;
        }

        // 判断是否可以下移
        public boolean canMoveDown(Shape shape) {
            for (Cell cell : shape.getCells()) {
                if (cell.getY() >= BOARD_HEIGHT - 1 || filledCells[cell.getY() + 1][cell.getX()]) {
                    return false;
                }
            }
            return true;
        }

        // 判断是否可以旋转
        public boolean canRotate(Shape shape) {
            Shape rotatedShape = shape.getRotatedShape();
            for (Cell cell : rotatedShape.getCells()) {
                if (cell.getX() < 0 || cell.getX() >= BOARD_WIDTH || cell.getY() >= BOARD_HEIGHT || filledCells[cell.getY()][cell.getX()]) {
                    return false;
                }
            }
            return true;
        }

        // 将方块加入已填充单元格
        public void addShape(Shape shape) {
            for (Cell cell : shape.getCells()) {
                filledCells[cell.getY()][cell.getX()] = true;
            }
            clearLines();
        }

        // 消除满行
        private void clearLines() {
            for (int i = BOARD_HEIGHT - 1; i >= 0; i--) {
                boolean isFullLine = true;
                for (int j = 0; j < BOARD_WIDTH; j++) {
                    if (!filledCells[i][j]) {
                        isFullLine = false;
                        break;
                    }
                }
                if (isFullLine) {
                    moveLinesDown(i);
                }
            }
        }

        // 将上方所有行向下移动
        private void moveLinesDown(int row) {
            for (int i = row; i > 0; i--) {
                for (int j = 0; j < BOARD_WIDTH; j++) {
                    filledCells[i][j] = filledCells[i - 1][j];
                }
            }
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            drawBoard(g);
            drawShape(g, currentShape);
        }

        // 绘制游戏板
        private void drawBoard(Graphics g) {
            for (int i = 0; i < BOARD_HEIGHT; i++) {
                for (int j = 0; j < BOARD_WIDTH; j++) {
                    if (filledCells[i][j]) {
                        g.setColor(Color.BLUE);
                        g.fillRect(j * CELL_SIZE, i * CELL_SIZE, CELL_SIZE, CELL_SIZE);
                        g.setColor(Color.BLACK);
                        g.drawRect(j * CELL_SIZE, i * CELL_SIZE, CELL_SIZE, CELL_SIZE);
                    }
                }
            }
        }

        // 绘制方块
        private void drawShape(Graphics g, Shape shape) {
            for (Cell cell : shape.getCells()) {
                g.setColor(Color.RED);
                g.fillRect(cell.getX() * CELL_SIZE, cell.getY() * CELL_SIZE, CELL_SIZE, CELL_SIZE);
                g.setColor(Color.BLACK);
                g.drawRect(cell.getX() * CELL_SIZE, cell.getY() * CELL_SIZE, CELL_SIZE, CELL_SIZE);
            }
        }
    }

    // 单元格
    class Cell {
        private int x;
        private int y;

        public Cell(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public int getX() {
            return x;
        }

        public int getY() {
            return y;
        }
    }

    // 方块
    class Shape {
        private List<Cell> cells;

        public Shape() {
            cells = new ArrayList<>();
            // 初始化形状
            Random random = new Random();
            int shapeType = random.nextInt(7); // 0 到 6
            switch (shapeType) {
                case 0: // I
                    cells.add(new Cell(3, 0));
                    cells.add(new Cell(3, 1));
                    cells.add(new Cell(3, 2));
                    cells.add(new Cell(3, 3));
                    break;
                case 1: // J
                    cells.add(new Cell(4, 0));
                    cells.add(new Cell(4, 1));
                    cells.add(new Cell(4, 2));
                    cells.add(new Cell(3, 2));
                    break;
                case 2: // L
                    cells.add(new Cell(3, 0));
                    cells.add(new Cell(3, 1));
                    cells.add(new Cell(3, 2));
                    cells.add(new Cell(4, 2));
                    break;
                case 3: // O
                    cells.add(new Cell(4, 0));
                    cells.add(new Cell(4, 1));
                    cells.add(new Cell(3, 0));
                    cells.add(new Cell(3, 1));
                    break;
                case 4: // S
                    cells.add(new Cell(4, 1));
                    cells.add(new Cell(3, 1));
                    cells.add(new Cell(3, 0));
                    cells.add(new Cell(2, 0));
                    break;
                case 5: // T
                    cells.add(new Cell(3, 0));
                    cells.add(new Cell(3, 1));
                    cells.add(new Cell(3, 2));
                    cells.add(new Cell(4, 1));
                    break;
                case 6: // Z
                    cells.add(new Cell(2, 1));
                    cells.add(new Cell(3, 1));
                    cells.add(new Cell(3, 0));
                    cells.add(new Cell(4, 0));
                    break;
            }
        }

        public List<Cell> getCells() {
            return cells;
        }

        // 左移
        public void moveLeft() {
            for (Cell cell : cells) {
                cell.x--;
            }
        }

        // 右移
        public void moveRight() {
            for (Cell cell : cells) {
                cell.x++;
            }
        }

        // 下移
        public void moveDown() {
            for (Cell cell : cells) {
                cell.y++;
            }
        }

        // 旋转
        public void rotate() {
            int centerX = cells.get(1).getX();
            int centerY = cells.get(1).getY();

            for (Cell cell : cells) {
                int x = cell.getX() - centerX;
                int y = cell.getY() - centerY;

                cell.x = centerX - y;
                cell.y = centerY + x;
            }
        }

        // 获取旋转后的形状
        public Shape getRotatedShape() {
            Shape rotatedShape = new Shape();
            rotatedShape.cells.clear();
            rotatedShape.cells.addAll(this.cells);
            rotatedShape.rotate();
            return rotatedShape;
        }
    }
}
相关推荐
P.H. Infinity17 分钟前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq
生命几十年3万天21 分钟前
java的threadlocal为何内存泄漏
java
caridle33 分钟前
教程:使用 InterBase Express 访问数据库(五):TIBTransaction
java·数据库·express
萧鼎36 分钟前
Python并发编程库:Asyncio的异步编程实战
开发语言·数据库·python·异步
学地理的小胖砸37 分钟前
【一些关于Python的信息和帮助】
开发语言·python
疯一样的码农37 分钟前
Python 继承、多态、封装、抽象
开发语言·python
^velpro^38 分钟前
数据库连接池的创建
java·开发语言·数据库
苹果醋342 分钟前
Java8->Java19的初步探索
java·运维·spring boot·mysql·nginx
秋の花1 小时前
【JAVA基础】Java集合基础
java·开发语言·windows
小松学前端1 小时前
第六章 7.0 LinkList
java·开发语言·网络