发布一个Java写的俄罗斯方块源码 算法简单(300行) 注释详细

 转自:http://topic.csdn.net/u/20100612/03/A8D7B257-4385-4BB8-82FF-4A51AC3BD810.html

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.*;
import javax.swing.Timer;

public class Tetris extends JFrame {
    public Tetris() {
        Tetrisblok a = new Tetrisblok();
        addKeyListener(a);
        add(a);
    }

    public static void main(String[] args) {
        Tetris frame = new Tetris();
        JMenuBar menu = new JMenuBar();
        frame.setJMenuBar(menu);
        JMenu game = new JMenu("游戏");
        JMenuItem newgame = game.add("新游戏");
        JMenuItem pause = game.add("暂停");
        JMenuItem goon = game.add("继续");
        JMenuItem exit = game.add("退出");
        JMenu help = new JMenu("帮助");
        JMenuItem about = help.add("关于");
        menu.add(game);
        menu.add(help);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(220, 275);
        frame.setTitle("Tetris内测版");
        // frame.setUndecorated(true);
        frame.setVisible(true);
        frame.setResizable(false);

    }
}

// 创建一个俄罗斯方块类
class Tetrisblok extends JPanel implements KeyListener {

    // blockType 代表方块类型
    // turnState代表方块状态
    private int blockType;
    private int score = 0;

    private int turnState;

    private int x;

    private int y;

    private int i = 0;

    int j = 0;
    int flag = 0;
    // 定义已经放下的方块x=0-11,y=0-21;
    int[][] map = new int[13][23];

    // 方块的形状 第一组代表方块类型有S、Z、L、J、I、O、T 7种 第二组 代表旋转几次 第三四组为 方块矩阵
    private final int shapes[][][] = new int[][][] {
    // i
            { { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
                    { 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 },
                    { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
                    { 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 } },
            // s
            { { 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                    { 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
                    { 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                    { 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 } },
            // z
            { { 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                    { 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
                    { 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                    { 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 } },
            // j
            { { 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0 },
                    { 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                    { 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
                    { 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
            // o
            { { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                    { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                    { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                    { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
            // l
            { { 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0 },
                    { 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                    { 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
                    { 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
            // t
            { { 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                    { 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
                    { 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                    { 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 } } };

    // 生成新方块的方法
    public void newblock() {
        blockType = (int) (Math.random() * 1000) % 7;
        turnState = (int) (Math.random() * 1000) % 4;
        x = 4;
        y = 0;
        if (gameover(x, y) == 1) {

            newmap();
            drawwall();
            score = 0;
            JOptionPane.showMessageDialog(null, "GAME OVER");
        }
    }

    // 画围墙
    public void drawwall() {
        for (i = 0; i < 12; i++) {
            map[i][21] = 2;
        }
        for (j = 0; j < 22; j++) {
            map[11][j] = 2;
            map[0][j] = 2;
        }
    }

    // 初始化地图
    public void newmap() {
        for (i = 0; i < 12; i++) {
            for (j = 0; j < 22; j++) {
                map[i][j] = 0;
            }
        }
    }

    // 初始化构造方法
    Tetrisblok() {
        newblock();
        newmap();
        drawwall();
        Timer timer = new Timer(1000, new TimerListener());
        timer.start();
    }

    // 旋转的方法
    public void turn() {
        int tempturnState = turnState;
        turnState = (turnState + 1) % 4;
        if (blow(x, y, blockType, turnState) == 1) {
        }
        if (blow(x, y, blockType, turnState) == 0) {
            turnState = tempturnState;
        }
        repaint();
    }

    // 左移的方法
    public void left() {
        if (blow(x - 1, y, blockType, turnState) == 1) {
            x = x - 1;
        }
        ;
        repaint();
    }

    // 右移的方法
    public void right() {
        if (blow(x + 1, y, blockType, turnState) == 1) {
            x = x + 1;
        }
        ;
        repaint();
    }

    // 下落的方法
    public void down() {
        if (blow(x, y + 1, blockType, turnState) == 1) {
            y = y + 1;
            delline();
        }
        ;
        if (blow(x, y + 1, blockType, turnState) == 0) {
            add(x, y, blockType, turnState);
            newblock();
            delline();
        }
        ;
        repaint();
    }

    // 是否合法的方法
    public int blow(int x, int y, int blockType, int turnState) {
        for (int a = 0; a < 4; a++) {
            for (int b = 0; b < 4; b++) {
                if (((shapes[blockType][turnState][a * 4 + b] == 1) && (map[x
                        + b + 1][y + a] == 1))
                        || ((shapes[blockType][turnState][a * 4 + b] == 1) && (map[x
                                + b + 1][y + a] == 2))) {

                    return 0;
                }
            }
        }
        return 1;
    }

    // 消行的方法
    public void delline() {
        int c = 0;
        for (int b = 0; b < 22; b++) {
            for (int a = 0; a < 12; a++) {
                if (map[a][b] == 1) {

                    c = c + 1;
                    if (c == 10) {
                        score += 10;
                        for (int d = b; d > 0; d--) {
                            for (int e = 0; e < 11; e++) {
                                map[e][d] = map[e][d - 1];

                            }
                        }
                    }
                }
            }
            c = 0;
        }
    }

    // 判断你挂的方法
    public int gameover(int x, int y) {
        if (blow(x, y, blockType, turnState) == 0) {
            return 1;
        }
        return 0;
    }

    // 把当前添加map
    public void add(int x, int y, int blockType, int turnState) {
        int j = 0;
        for (int a = 0; a < 4; a++) {
            for (int b = 0; b < 4; b++) {
                if (map[x + b + 1][y + a] == 0) {
                    map[x + b + 1][y + a] = shapes[blockType][turnState][j];
                }
                ;
                j++;
            }
        }
    }

    // 画方块的的方法
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        // 画当前方块
        for (j = 0; j < 16; j++) {
            if (shapes[blockType][turnState][j] == 1) {
                g.fillRect((j % 4 + x + 1) * 10, (j / 4 + y) * 10, 10, 10);
            }
        }
        // 画已经固定的方块
        for (j = 0; j < 22; j++) {
            for (i = 0; i < 12; i++) {
                if (map[i][j] == 1) {
                    g.fillRect(i * 10, j * 10, 10, 10);

                }
                if (map[i][j] == 2) {
                    g.drawRect(i * 10, j * 10, 10, 10);

                }
            }
        }
        g.drawString("score=" + score, 125, 10);
        g.drawString("抵制不良游戏,", 125, 50);
        g.drawString("拒绝盗版游戏。", 125, 70);
        g.drawString("注意自我保护,", 125, 90);
        g.drawString("谨防受骗上当。", 125, 110);
        g.drawString("适度游戏益脑,", 125, 130);
        g.drawString("沉迷游戏伤身。", 125, 150);
        g.drawString("合理安排时间,", 125, 170);
        g.drawString("享受健康生活。", 125, 190);
    }

    // 键盘监听
    public void keyPressed(KeyEvent e) {
        switch (e.getKeyCode()) {
        case KeyEvent.VK_DOWN:
            down();
            break;
        case KeyEvent.VK_UP:
            turn();
            break;
        case KeyEvent.VK_RIGHT:
            right();
            break;
        case KeyEvent.VK_LEFT:
            left();
            break;
        }

    }

    // 无用
    public void keyReleased(KeyEvent e) {
    }

    // 无用
    public void keyTyped(KeyEvent e) {
    }

    // 定时器监听
    class TimerListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {

            repaint();
            if (blow(x, y + 1, blockType, turnState) == 1) {
                y = y + 1;
                delline();
            }
            ;
            if (blow(x, y + 1, blockType, turnState) == 0) {

                if (flag == 1) {
                    add(x, y, blockType, turnState);
                    delline();
                    newblock();
                    flag = 0;
                }
                flag = 1;
            }
            ;
        }
    }
}


 

好的,以下是简易完整版Java俄罗斯方块源码注释: ```java import java.awt.Color; import java.awt.Graphics; import java.awt.Point; import java.util.ArrayList; import java.util.Collections; import java.util.Random; import javax.swing.JFrame; import javax.swing.JPanel; // 方块类 class Block { // 方块的形状 private ArrayList<Point> shape; // 方块的颜色 private Color color; // 方块的位置 private int x, y; // 构造函数,随机生成方块的形状和颜色 public Block() { Random rand = new Random(); // 随机生成方块的形状 shape = new ArrayList<Point>(); int type = rand.nextInt(7); switch (type) { case 0: // I型 shape.add(new Point(0, 0)); shape.add(new Point(1, 0)); shape.add(new Point(2, 0)); shape.add(new Point(3, 0)); color = Color.CYAN; break; case 1: // J型 shape.add(new Point(0, 0)); shape.add(new Point(0, 1)); shape.add(new Point(1, 1)); shape.add(new Point(2, 1)); color = Color.BLUE; break; case 2: // L型 shape.add(new Point(2, 0)); shape.add(new Point(0, 1)); shape.add(new Point(1, 1)); shape.add(new Point(2, 1)); color = Color.ORANGE; break; case 3: // O型 shape.add(new Point(0, 0)); shape.add(new Point(1, 0)); shape.add(new Point(0, 1)); shape.add(new Point(1, 1)); color = Color.YELLOW; break; case 4: // S型 shape.add(new Point(1, 0)); shape.add(new Point(2, 0)); shape.add(new Point(0, 1)); shape.add(new Point(1, 1)); color = Color.GREEN; break; case 5: // T型 shape.add(new Point(1, 0)); shape.add(new Point(0, 1)); shape.add(new Point(1, 1)); shape.add(new Point(2, 1)); color = Color.MAGENTA; break; case 6: // Z型 shape.add(new Point(0, 0)); shape.add(new Point(1, 0)); shape.add(new Point(1, 1)); shape.add(new Point(2, 1)); color = Color.RED; break; } // 随机生成方块的位置 x = rand.nextInt(10); y = -2; } // 获取方块的形状 public ArrayList<Point> getShape() { return shape; } // 获取方块的颜色 public Color getColor() { return color; } // 获取方块的位置 public int getX() { return x; } public int getY() { return y; } // 移动方块 public void move(int dx, int dy) { x += dx; y += dy; } // 旋转方块 public void rotate() { for (Point p : shape) { int x = p.x; int y = p.y; p.x = y; p.y = -x; } } } // 俄罗斯方块游戏类 public class Tetris extends JPanel implements Runnable { // 方块的大小 private static final int BLOCK_SIZE = 30; // 游戏区域的宽度和高度 private static final int BOARD_WIDTH = 10; private static final int BOARD_HEIGHT = 20; // 游戏区域的左上角坐标 private static final int BOARD_X = 150; private static final int BOARD_Y = 50; // 游戏的状态 private boolean isRunning = true; private boolean isPaused = false; private boolean isGameOver = false; // 当前的方块和下一个方块 private Block currentBlock, nextBlock; // 游戏区域的方块矩阵 private Color[][] board = new Color[BOARD_WIDTH][BOARD_HEIGHT]; // 随机数生成器 private Random rand = new Random(); // 构造函数 public Tetris() { // 初始化游戏区域的方块矩阵 for (int i = 0; i < BOARD_WIDTH; i++) { for (int j = 0; j < BOARD_HEIGHT; j++) { board[i][j] = Color.WHITE; } } // 预先生成下一个方块 nextBlock = new Block(); } // 绘制游戏区域 private void drawBoard(Graphics g) { // 绘制游戏区域的边框 g.setColor(Color.GRAY); g.drawRect(BOARD_X - 1, BOARD_Y - 1, BLOCK_SIZE * BOARD_WIDTH + 2, BLOCK_SIZE * BOARD_HEIGHT + 2); // 绘制游戏区域的方块 for (int i = 0; i < BOARD_WIDTH; i++) { for (int j = 0; j < BOARD_HEIGHT; j++) { Color c = board[i][j]; if (c != Color.WHITE) { g.setColor(c); g.fillRect(BOARD_X + i * BLOCK_SIZE, BOARD_Y + j * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE); g.setColor(Color.BLACK); g.drawRect(BOARD_X + i * BLOCK_SIZE, BOARD_Y + j * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE); } } } } // 绘制当前方块和下一个方块 private void drawBlock(Graphics g) { // 绘制当前方块 ArrayList<Point> shape = currentBlock.getShape(); Color c = currentBlock.getColor(); for (Point p : shape) { int x = currentBlock.getX() + p.x; int y = currentBlock.getY() + p.y; g.setColor(c); g.fillRect(BOARD_X + x * BLOCK_SIZE, BOARD_Y + y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE); g.setColor(Color.BLACK); g.drawRect(BOARD_X + x * BLOCK_SIZE, BOARD_Y + y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE); } // 绘制下一个方块 shape = nextBlock.getShape(); c = nextBlock.getColor(); for (Point p : shape) { int x = BOARD_WIDTH + 2 + p.x; int y = 2 + p.y; g.setColor(c); g.fillRect(BOARD_X + x * BLOCK_SIZE, BOARD_Y + y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE); g.setColor(Color.BLACK); g.drawRect(BOARD_X + x * BLOCK_SIZE, BOARD_Y + y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE); } } // 是否可以移动方块 private boolean canMove(Block block, int dx, int dy) { ArrayList<Point> shape = block.getShape(); for (Point p : shape) { int x = block.getX() + p.x + dx; int y = block.getY() + p.y + dy; if (x < 0 || x >= BOARD_WIDTH || y < 0 || y >= BOARD_HEIGHT || board[x][y] != Color.WHITE) { return false; } } return true; } // 将方块放到游戏区域 private void placeBlock() { ArrayList<Point> shape = currentBlock.getShape(); Color c = currentBlock.getColor(); for (Point p : shape) { int x = currentBlock.getX() + p.x; int y = currentBlock.getY() + p.y; board[x][y] = c; } } // 消除可以消除的 private void eliminateLines() { for (int j = BOARD_HEIGHT - 1; j >= 0; j--) { boolean isFull = true; for (int i = 0; i < BOARD_WIDTH; i++) { if (board[i][j] == Color.WHITE) { isFull = false; break; } } if (isFull) { // 将上面的所有向下移动一 for (int k = j; k > 0; k--) { for (int i = 0; i < BOARD_WIDTH; i++) { board[i][k] = board[i][k - 1]; } } // 最上面一变成空白 for (int i = 0; i < BOARD_WIDTH; i++) { board[i][0] = Color.WHITE; } // 分数加一 score++; // 继续判断当前是否可以消除 j++; } } } // 游戏结束 private void gameOver() { isGameOver = true; repaint(); } // 游戏主循环 public void run() { // 不断地移动方块下落,直到游戏结束 while (isRunning) { if (!isPaused) { // 检查是否可以移动当前方块 if (canMove(currentBlock, 0, 1)) { currentBlock.move(0, 1); } else { // 将当前方块放到游戏区域 placeBlock(); // 消除可以消除的 eliminateLines(); // 检查游戏是否结束 if (currentBlock.getY() < 0) { gameOver(); break; } // 生成下一个方块,并将其设置为当前方块 currentBlock = nextBlock; nextBlock = new Block(); } repaint(); } try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } } // 绘制游戏界面 public void paint(Graphics g) { super.paint(g); // 绘制游戏区域 drawBoard(g); // 绘制当前方块和下一个方块 if (!isGameOver) { drawBlock(g); } else { // 游戏结束时显示 Game Over g.setColor(Color.RED); g.drawString("Game Over", BOARD_X + BLOCK_SIZE * BOARD_WIDTH / 2 - 30, BOARD_Y + BLOCK_SIZE * BOARD_HEIGHT / 2); } // 绘制分数 g.setColor(Color.BLACK); g.drawString("Score: " + score, BOARD_X + BLOCK_SIZE * BOARD_WIDTH + 20, BOARD_Y + BLOCK_SIZE * 4); } // 暂停游戏 public void pause() { isPaused = true; } // 恢复游戏 public void resume() { isPaused = false; } // 开始游戏 public void start() { // 生成第一个方块 currentBlock = new Block(); // 启动游戏主循环线程 Thread t = new Thread(this); t.start(); } // 分数 private int score = 0; // 主函数 public static void main(String[] args) { JFrame frame = new JFrame("俄罗斯方块"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(500, 600); frame.setLocationRelativeTo(null); Tetris tetris = new Tetris(); frame.add(tetris); frame.addKeyListener(new TetrisKeyListener(tetris)); frame.setVisible(true); tetris.start(); } } // 键盘监听器 class TetrisKeyListener implements java.awt.event.KeyListener { private Tetris tetris; public TetrisKeyListener(Tetris tetris) { this.tetris = tetris; } public void keyPressed(java.awt.event.KeyEvent e) { switch (e.getKeyCode()) { case java.awt.event.KeyEvent.VK_LEFT: if (tetris.canMove(tetris.currentBlock, -1, 0)) { tetris.currentBlock.move(-1, 0); } break; case java.awt.event.KeyEvent.VK_RIGHT: if (tetris.canMove(tetris.currentBlock, 1, 0)) { tetris.currentBlock.move(1, 0); } break; case java.awt.event.KeyEvent.VK_DOWN: if (tetris.canMove(tetris.currentBlock, 0, 1)) { tetris.currentBlock.move(0, 1); } break; case java.awt.event.KeyEvent.VK_UP: Block temp = new Block(); temp.getShape().addAll(tetris.currentBlock.getShape()); temp.rotate(); if (tetris.canMove(temp, 0, 0)) { tetris.currentBlock.rotate(); } break; case java.awt.event.KeyEvent.VK_SPACE: tetris.pause(); String[] options = {"Resume", "Restart", "Quit"}; int choice = javax.swing.JOptionPane.showOptionDialog(tetris, "Game Paused", "Pause", javax.swing.JOptionPane.DEFAULT_OPTION, javax.swing.JOptionPane.PLAIN_MESSAGE, null, options, options[0]); switch (choice) { case 0: tetris.resume(); break; case 1: tetris.restart(); break; case 2: System.exit(0); break; } break; } tetris.repaint(); } public void keyReleased(java.awt.event.KeyEvent e) { } public void keyTyped(java.awt.event.KeyEvent e) { } } ``` 以上是简易完整版Java俄罗斯方块源码注释,希望对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值