java实现俄罗斯方块小游戏

以下是一个简单的俄罗斯方块游戏Java代码示例(使用Swing库):

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

public class Tetris extends JPanel {
    private final static int ROWS = 20;
    private final static int COLUMNS = 10;
    private final static int SQUARE_WIDTH = 20;
    private final static int SQUARE_HEIGHT = 20;
    private final static int BOARD_WIDTH = COLUMNS * SQUARE_WIDTH;
    private final static int BOARD_HEIGHT = ROWS * SQUARE_HEIGHT;

    private Timer timer;
    private boolean isFallingFinished = false;
    private boolean isStarted = false;
    private boolean isPaused = false;
    private int numLinesRemoved = 0;
    private int curX = 0;
    private int curY = 0;
    private JLabel statusbar;
    private Shape curPiece;
    private Square[][] board;

    public Tetris(Frame parent) {
        initUI(parent);
    }

    private void initUI(Frame parent) {
        setFocusable(true);
        statusbar = new JLabel(" 0");
        add(statusbar, BorderLayout.SOUTH);
        curPiece = new Shape();
        board = new Square[COLUMNS][ROWS];
        clearBoard();
        addKeyListener(new TAdapter());
        timer = new Timer(400, new GameCycle());
        timer.start();
    }

    private void clearBoard() {
        for (int i = 0; i < COLUMNS; i++) {
            for (int j = 0; j < ROWS; j++) {
                board[i][j] = Square.NoShape;
            }
        }
    }

    private void shapeDropped() {
        for (int i = 0; i < 4; i++) {
            int x = curX + curPiece.getX(i);
            int y = curY - curPiece.getY(i);
            board[x][y] = curPiece.getShape();
        }
        removeFullLines();
        if (!isFallingFinished) {
            newPiece();
        }
    }

    private void newPiece() {
        curPiece.setRandomShape();
        curX = COLUMNS / 2 + 1;
        curY = ROWS - 1 + curPiece.minY();
        if (!tryMove(curPiece, curX, curY)) {
            curPiece.setShape(Square.NoShape);
            timer.stop();
            isStarted = false;
            statusbar.setText("Game over");
        }
    }

    private boolean tryMove(Shape newPiece, int newX, int newY) {
        for (int i = 0; i < 4; i++) {
            int x = newX + newPiece.getX(i);
            int y = newY - newPiece.getY(i);
            if (x < 0 || x >= COLUMNS || y < 0 || y >= ROWS) {
                return false;
            }
            if (board[x][y] != Square.NoShape) {
                return false;
            }
        }
        curPiece = newPiece;
        curX = newX;
        curY = newY;
        repaint();
        return true;
    }

    private void removeFullLines() {
        int numFullLines = 0;
        for (int i = ROWS - 1; i >= 0; i--) {
            boolean lineIsFull = true;
            for (int j = 0; j < COLUMNS; j++) {
                if (board[j][i] == Square.NoShape) {
                    lineIsFull = false;
                    break;
                }
            }
            if (lineIsFull) {
                numFullLines++;
                for (int k = i; k < ROWS - 1; k++) {
                    for (int j = 0; j < COLUMNS; j++) {
                        board[j][k] = board[j][k + 1];
                    }
                }
                for (int j = 0; j < COLUMNS; j++) {
                    board[j][ROWS - 1] = Square.NoShape;
                }
            }
        }
        if (numFullLines > 0) {
            numLinesRemoved += numFullLines;
            statusbar.setText(String.valueOf(numLinesRemoved));
            isFallingFinished = true;
            curPiece.setShape(Square.NoShape);
        }
    }

    private void doDrawing(Graphics g) {
        Dimension size = getSize();
        int boardTop = (int) size.getHeight() - BOARD_HEIGHT;
        for (int i = 0; i < COLUMNS; i++) {
            for (int j = 0; j < ROWS; j++) {
                Square shape = board[i][ROWS - j - 1];
                if (shape != Square.NoShape) {
                    drawSquare(g, i * SQUARE_WIDTH,
                            boardTop + j * SQUARE_HEIGHT, shape);
                }
            }
        }
        if (curPiece.getShape() != Square.NoShape) {
            for (int i = 0; i < 4; i++) {
                int x = curX + curPiece.getX(i);
                int y = curY - curPiece.getY(i);
                drawSquare(g, x * SQUARE_WIDTH,
                        boardTop + (ROWS - y - 1) * SQUARE_HEIGHT,
                        curPiece.getShape());
            }
        }
    }

    private void drawSquare(Graphics g, int x, int y, Square shape) {
        Color colors[] = {
            new Color(0, 0, 0), new Color(204, 102, 102),
            new Color(102, 204, 102), new Color(102, 102, 204),
            new Color(204, 204, 102), new Color(204, 102, 204),
            new Color(102, 204, 204), new Color(218, 170, 0)
        };
        Color color = colors[shape.ordinal()];
        g.setColor(color);
        g.fillRect(x + 1, y + 1, SQUARE_WIDTH - 2,
                SQUARE_HEIGHT - 2);
        g.setColor(color.brighter());
        g.drawLine(x, y + SQUARE_HEIGHT - 1, x, y);
        g.drawLine(x, y, x + SQUARE_WIDTH - 1, y);
        g.setColor(color.darker());
        g.drawLine(x + 1, y + SQUARE_HEIGHT - 1,
                x + SQUARE_WIDTH - 1, y + SQUARE_HEIGHT - 1);
        g.drawLine(x + SQUARE_WIDTH - 1,
                y + SQUARE_HEIGHT - 1,
                x + SQUARE_WIDTH - 1, y + 1);
    }

    private class TAdapter extends KeyAdapter {
        @Override
        public void keyPressed(KeyEvent e) {
            if (!isStarted || curPiece.getShape() == Square.NoShape) {
                return;
            }
            int keycode = e.getKeyCode();
            if (keycode == 'p' || keycode == 'P') {
                pause();
            }
            if (isPaused) {
                return;
            }
            switch (keycode) {
                case KeyEvent.VK_LEFT:
                    tryMove(curPiece, curX - 1, curY);
                    break;
                case KeyEvent.VK_RIGHT:
                    tryMove(curPiece, curX + 1, curY);
                    break;
                case KeyEvent.VK_DOWN:
                    tryMove(curPiece.rotateRight(), curX, curY);
                    break;
                case KeyEvent.VK_UP:
                    tryMove(curPiece.rotateLeft(), curX, curY);
                    break;
                case KeyEvent.VK_SPACE:
                    dropDown();
                    break;
                case 'd':
                    oneLineDown();
                    break;
            }
        }
    }

    private void pause() {
        isPaused = !isPaused;
        if (isPaused) {
            statusbar.setText("paused");
            timer.stop();
        } else {
            statusbar.setText(String.valueOf(numLinesRemoved));
            timer.start();
        }
        repaint();
    }

    private void dropDown() {
        int newY = curY;
        while (newY > 0) {
            if (!tryMove(curPiece, curX, newY - 1)) {
                break;
            }
            newY--;
        }
        shapeDropped();
    }

    private void oneLineDown() {
        if (!tryMove(curPiece, curX, curY - 1)) {
            shapeDropped();
        }
    }

    private class GameCycle implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            doGameCycle();
        }
    }

    private void doGameCycle() {
        update();
        repaint();
    }

    private void update() {
        if (isPaused) {
            return;
        }
        if (isFallingFinished) {
            isFallingFinished = false;
            newPiece();
        } else {
            oneLineDown();
        }
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("Tetris");
        frame.setSize(BOARD_WIDTH, BOARD_HEIGHT);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        Tetris game = new Tetris(frame);
        frame.add(game);
        frame.setVisible(true);
    }
}

enum Square {
    NoShape, ZShape, SShape, LineShape,
    TShape, SquareShape, LShape, MirroredLShape
}

class Shape {
    private Square pieceShape;
    private int coords[][];
    private int[][][] coordsTable;

    public Shape() {
        coords = new int[4][2];
        setShape(Square.NoShape);
    }

    protected void setShape(Square shape) {
        coordsTable = new int[][][]{
            {{0, 0}, {0, 0}, {0, 0}, {0, 0}},
            {{0, -1}, {0, 0}, {-1, 0}, {-1, 1}},
            {{0, -1}, {0, 0}, {1, 0}, {1, 1}},
            {{0, -1}, {0, 0}, {0, 1}, {0, 2}},
            {{-1, 0}, {0, 0}, {1, 0}, {0, 1}},
            {{0, 0}, {1, 0}, {0, 1}, {1, 1}},
            {{-1, -1}, {0, -1}, {0, 0}, {0, 1}},
            {{1, -1}, {0, -1}, {0, 0}, {0, 1}}
        };
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 2; ++j) {
                coords[i][j] = coordsTable[shape.ordinal()][i][j];
            }
        }
        pieceShape = shape;
    }

    private void setX(int index, int x) {
        coords[index][0] = x;
    }

    private void setY(int index, int y) {
        coords[index][1] = y;
    }

    public int getX(int index) {
        return coords[index][0];
    }

    public int getY(int index) {
        return coords[index][1];
    }

    public Square getShape() {
        return pieceShape;
    }

    public void setRandomShape() {
        int x = (int) (Math.random() * 7 + 1);
        Square[] values = Square.values();
        setShape(values[x]);
    }

    public int minY() {
        int m = coords[0][1];
        for (int i = 0; i < 4; i++) {
            m = Math.min(m, coords[i][1]);
        }
        return m;
    }

    public Shape rotateLeft() {
        if (pieceShape == Square.SquareShape) {
            return this;
        }
        Shape result = new Shape();
        result.pieceShape = pieceShape;
        for (int i = 0; i < 4; i++) {
            result.setX(i, getY(i));
            result.setY(i, -getX(i));
        }
        return result;
    }

    public Shape rotateRight() {
        if (pieceShape == Square.SquareShape) {
            return this;
        }
        Shape result = new Shape();
        result.pieceShape = pieceShape;
        for (int i = 0; i < 4; i++) {
            result.setX(i, -getY(i));
            result.setY(i, getX(i));
        }
        return result;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

个人练习生xx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值