文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java实现俄罗斯方块小游戏。(附完整源代码)

2023-09-02 08:23

关注

大家好,我是百思不得小赵。

创作时间:2022 年 5 月 12 日
博客主页: 🔍点此进入博客主页
—— 新时代的农民工 🙊
—— 换一种思维逻辑去看待这个世界 👀
今天是加入CSDN的第1167天。觉得有帮助麻烦👏点赞、🍀评论、❤️收藏


目录

一、游戏背景

二、功能实现

三、效果展示


俄罗斯方块是俄罗斯人发明的。这人叫阿列克谢·帕基特诺夫(Алексей Пажитнов 英文:Alexey Pazhitnov)。俄罗斯方块原名是俄语Тетрис(英语是Tetris),这个名字来源于希腊语tetra,意思是“四”,而游戏的作者最喜欢网球(tennis)。于是,他把两个词tetra和tennis合而为一,命名为Tetris,这也就是俄罗斯方块名字的由来。

规则说明:

由小方块组成的不同形状的板块陆续从屏幕上方落下来,玩家通过调整板块的位置和方向,使它们在屏幕底部拼出完整的一条或几条。这些完整的横条会随即消失,给新落下来的板块腾出空间,与此同时,玩家得到分数奖励。没有被消除掉的方块不断堆积起来,一旦堆到屏幕顶端,玩家便告输,游戏结束。

开发工具:idea、jdk8

技术汇总:Java基础知识、数组、面向对象、多线程、IO流、Swing。

整体代码分为三个模块:方格模块,七种图形模块,俄罗斯方块主模块。

小方块类:Cell

public class Cell {    // 行    private int row;    // 列    private int col;    private BufferedImage image;    public Cell() {    }    public Cell(int row, int col, BufferedImage image) {        this.row = row;        this.col = col;        this.image = image;    }    public int getRow() {        return row;    }    public void setRow(int row) {        this.row = row;    }    public int getCol() {        return col;    }    public void setCol(int col) {        this.col = col;    }    public BufferedImage getImage() {        return image;    }    public void setImage(BufferedImage image) {        this.image = image;    }    @Override    public String toString() {        return "Cell{" +                "row=" + row +                ", col=" + col +                ", image=" + image +                '}';    }    @Override    public boolean equals(Object o) {        if (this == o) {            return true;        }        if (!(o instanceof Cell)) {            return false;        }        Cell cell = (Cell) o;        return getRow() == cell.getRow() &&                getCol() == cell.getCol() &&                Objects.equals(getImage(), cell.getImage());    }    @Override    public int hashCode() {        return Objects.hash(getRow(), getCol(), getImage());    }    //左移动一格    public void left(){        col--;    }    //右移动一格    public void right(){        col++;    }    //下移动一格    public void down(){        row++;    }}

 四方格图形的父类:Tetromino

public class Tetromino {    public Cell[] cells = new Cell[4];    //旋转的状态    protected State[] states;    //声明旋转次数    protected int count = 10000;    //左移方法    public void moveLeft() {        for (Cell cell : cells) {            cell.left();        }    }    //右移方法    public void moveRight() {        for (Cell cell : cells) {            cell.right();        }    }    //单元格下落    public void moveDrop() {        for (Cell cell : cells) {            cell.down();        }    }    //编写随机生成四方格    public static Tetromino randomOne() {        int num = (int) (Math.random() * 7);        Tetromino tetromino = null;        switch (num) {            case 0:                tetromino = new I();                break;            case 1:                tetromino = new J();                break;            case 2:                tetromino = new L();                break;            case 3:                tetromino = new O();                break;            case 4:                tetromino = new S();                break;            case 5:                tetromino = new T();                break;            case 6:                tetromino = new Z();                break;        }        return tetromino;    }    //顺时针旋转的方法    public void rotateRight() {        if (states.length == 0) {            return;        }        //旋转次数+1        count++;        State s = states[count % states.length];        Cell cell = cells[0];        int row = cell.getRow();        int col = cell.getCol();        cells[1].setRow(row + s.row1);        cells[1].setCol(col + s.col1);        cells[2].setRow(row + s.row2);        cells[2].setCol(col + s.col2);        cells[3].setRow(row + s.row3);        cells[3].setCol(col + s.col3);    }    //逆时针旋转的方法    public void rotateLeft() {        if (states.length == 0) {            return;        }        //旋转次数+1        count--;        State s = states[count % states.length];        Cell cell = cells[0];        int row = cell.getRow();        int col = cell.getCol();        cells[1].setRow(row + s.row1);        cells[1].setCol(col + s.col1);        cells[2].setRow(row + s.row2);        cells[2].setCol(col + s.col2);        cells[3].setRow(row + s.row3);        cells[3].setCol(col + s.col3);    }    //四方格旋转状态的内部类    protected class State {        //存储四方格各元素的位置        int row0, col0, row1, col1, row2, col2, row3, col3;        public State() {        }        public State(int row0, int col0, int row1, int col1, int row2, int col2, int row3, int col3) {            this.row0 = row0;            this.col0 = col0;            this.row1 = row1;            this.col1 = col1;            this.row2 = row2;            this.col2 = col2;            this.row3 = row3;            this.col3 = col3;        }        public int getRow0() {            return row0;        }        public void setRow0(int row0) {            this.row0 = row0;        }        public int getCol0() {            return col0;        }        public void setCol0(int col0) {            this.col0 = col0;        }        public int getRow1() {            return row1;        }        public void setRow1(int row1) {            this.row1 = row1;        }        public int getCol1() {            return col1;        }        public void setCol1(int col1) {            this.col1 = col1;        }        public int getRow2() {            return row2;        }        public void setRow2(int row2) {            this.row2 = row2;        }        public int getCol2() {            return col2;        }        public void setCol2(int col2) {            this.col2 = col2;        }        public int getRow3() {            return row3;        }        public void setRow3(int row3) {            this.row3 = row3;        }        public int getCol3() {            return col3;        }        public void setCol3(int col3) {            this.col3 = col3;        }        @Override        public String toString() {            return "State{" +                    "row0=" + row0 +                    ", col0=" + col0 +                    ", row1=" + row1 +                    ", col1=" + col1 +                    ", row2=" + row2 +                    ", col2=" + col2 +                    ", row3=" + row3 +                    ", col3=" + col3 +                    '}';        }    }}

七种图形类:I、J、L、O、S、T、Z

public class I extends Tetromino {    public I() {        cells[0] = new Cell(0,4, Tetris.I);        cells[1] = new Cell(0,3, Tetris.I);        cells[2] = new Cell(0,5, Tetris.I);        cells[3] = new Cell(0,6, Tetris.I);        //共有两种旋转状态        states =new State[2];        //初始化两种状态的相对坐标        states[0]=new State(0,0,0,-1,0,1,0,2);        states[1]=new State(0,0,-1,0,1,0,2,0);    }}
public class J extends Tetromino {    public J() {        cells[0] = new Cell(0,4, Tetris.J);        cells[1] = new Cell(0,3, Tetris.J);        cells[2] = new Cell(0,5, Tetris.J);        cells[3] = new Cell(1,5, Tetris.J);        states=new State[4];        states[0]=new State(0,0,0,-1,0,1,1,1);        states[1]=new State(0,0,-1,0,1,0,1,-1);        states[2]=new State(0,0,0,1,0,-1,-1,-1);        states[3]=new State(0,0,1,0,-1,0,-1,1);    }}
public class L extends Tetromino {    public L() {        cells[0] = new Cell(0,4, Tetris.L);        cells[1] = new Cell(0,3, Tetris.L);        cells[2] = new Cell(0,5, Tetris.L);        cells[3] = new Cell(1,3, Tetris.L);        states=new State[4];        states[0]=new State(0,0,0,-1,0,1,1,-1);        states[1]=new State(0,0,-1,0,1,0,-1,-1);        states[2]=new State(0,0,0,1,0,-1,-1,1);        states[3]=new State(0,0,1,0,-1,0,1,1);    }}
public class O extends Tetromino {    public O() {        cells[0] = new Cell(0, 4, Tetris.O);        cells[1] = new Cell(0, 5, Tetris.O);        cells[2] = new Cell(1, 4, Tetris.O);        cells[3] = new Cell(1, 5, Tetris.O);        //无旋转状态        states = new State[0];    }}
public class S extends Tetromino {    public S() {        cells[0] = new Cell(0,4, Tetris.S);        cells[1] = new Cell(0,5, Tetris.S);        cells[2] = new Cell(1,3, Tetris.S);        cells[3] = new Cell(1,4, Tetris.S);        //共有两种旋转状态        states =new State[2];        //初始化两种状态的相对坐标        states[0]=new State(0,0,0,1,1,-1,1,0);        states[1]=new State(0,0,1,0,-1,-1,0,-1);    }}
public class T extends Tetromino {    public T() {        cells[0] = new Cell(0,4, Tetris.T);        cells[1] = new Cell(0,3, Tetris.T);        cells[2] = new Cell(0,5, Tetris.T);        cells[3] = new Cell(1,4, Tetris.T);        states=new State[4];        states[0]=new State(0,0,0,-1,0,1,1,0);        states[1]=new State(0,0,-1,0,1,0,0,-1);        states[2]=new State(0,0,0,1,0,-1,-1,0);        states[3]=new State(0,0,1,0,-1,0,0,1);    }}
public class Z extends Tetromino {    public Z() {        cells[0] = new Cell(1,4, Tetris.Z);        cells[1] = new Cell(0,3, Tetris.Z);        cells[2] = new Cell(0,4, Tetris.Z);        cells[3] = new Cell(1,5, Tetris.Z);        //共有两种旋转状态        states =new State[2];        //初始化两种状态的相对坐标        states[0]=new State(0,0,-1,-1,-1,0,0,1);        states[1]=new State(0,0,-1,1,0,1,1,0);    }}

俄罗斯方块游戏主类:Tetris

public class Tetris extends JPanel {    //正在下落的方块    private Tetromino currentOne = Tetromino.randomOne();    //将要下落的方块    private Tetromino nextOne = Tetromino.randomOne();    //游戏主区域    private Cell[][] wall = new Cell[18][9];    //声明单元格的值    private static final int CELL_SIZE = 48;    //游戏分数池    int[] scores_pool = {0, 1, 2, 5, 10};    //当前游戏的分数    private int totalScore = 0;    //当前消除的行数    private int totalLine = 0;    //游戏三种状态 游戏中、暂停、结束    public static final int PLING = 0;    public static final int STOP = 1;    public static final int OVER = 2;    //当前游戏状态值    private int game_state;    //显示游戏状态    String[] show_state = {"P[pause]", "C[continue]", "S[replay]"};    //载入方块图片    public static BufferedImage I;    public static BufferedImage J;    public static BufferedImage L;    public static BufferedImage O;    public static BufferedImage S;    public static BufferedImage T;    public static BufferedImage Z;    public static BufferedImage background;    static {        try {            I = ImageIO.read(new File("images/I.png"));            J = ImageIO.read(new File("images/J.png"));            L = ImageIO.read(new File("images/L.png"));            O = ImageIO.read(new File("images/O.png"));            S = ImageIO.read(new File("images/S.png"));            T = ImageIO.read(new File("images/T.png"));            Z = ImageIO.read(new File("images/Z.png"));            background = ImageIO.read(new File("images/background.png"));        } catch (IOException e) {            e.printStackTrace();        }    }    @Override    public void paint(Graphics g) {        g.drawImage(background, 0, 0, null);        //平移坐标轴        g.translate(22, 15);        //绘制游戏主区域        paintWall(g);        //绘制正在下落的四方格        paintCurrentOne(g);        //绘制下一个将要下落的四方格        paintNextOne(g);        //绘制游戏得分        paintSource(g);        //绘制当前游戏状态        paintState(g);    }    public void start() {        game_state = PLING;        KeyListener l = new KeyAdapter() {            @Override            public void keyPressed(KeyEvent e) {                int code = e.getKeyCode();                switch (code) {                    case KeyEvent.VK_DOWN:                        sortDropActive();                        break;                    case KeyEvent.VK_LEFT:                        moveleftActive();                        break;                    case KeyEvent.VK_RIGHT:                        moveRightActive();                        break;                    case KeyEvent.VK_UP:                        rotateRightActive();                        break;                    case KeyEvent.VK_SPACE:hadnDropActive();                        break;                    case KeyEvent.VK_P:                        //判断当前游戏状态                        if (game_state == PLING) {game_state = STOP;                        }                        break;                    case KeyEvent.VK_C:                        if (game_state == STOP) {game_state = PLING;                        }                        break;                    case KeyEvent.VK_S:                        //重新开始                        game_state = PLING;                        wall = new Cell[18][9];                        currentOne = Tetromino.randomOne();                        nextOne = Tetromino.randomOne();                        totalScore = 0;                        totalLine = 0;                        break;                }            }        };        //将窗口设置为焦点        this.addKeyListener(l);        this.requestFocus();        while (true) {            if (game_state == PLING) {                try {                    Thread.sleep(500);                } catch (InterruptedException e) {                    e.printStackTrace();                }                if (camDrop()) {                    currentOne.moveDrop();                } else {                    landToWall();                    destroyLine();                    if (isGameOver()) {                        game_state = OVER;                    } else {                        //游戏没有结束                        currentOne = nextOne;                        nextOne = Tetromino.randomOne();                    }                }            }            repaint();        }    }    //创建顺时针旋转    public void rotateRightActive() {        currentOne.rotateRight();        if (outOFBounds() || coincide()) {            currentOne.rotateLeft();        }    }    //瞬间下落    public void hadnDropActive() {        while (true) {            //判断能否下落            if (camDrop()) {                currentOne.moveDrop();            } else {                break;            }        }        //嵌入到墙中        landToWall();        destroyLine();        if (isGameOver()) {            game_state = OVER;        } else {            //游戏没有结束            currentOne = nextOne;            nextOne = Tetromino.randomOne();        }    }    //按键一次,下落一格    public void sortDropActive() {        if (camDrop()) {            //当前四方格下落一格            currentOne.moveDrop();        } else {            landToWall();            destroyLine();            if (isGameOver()) {                game_state = OVER;            } else {                //游戏没有结束                currentOne = nextOne;                nextOne = Tetromino.randomOne();            }        }    }    //单元格嵌入墙中    private void landToWall() {        Cell[] cells = currentOne.cells;        for (Cell cell : cells) {            int row = cell.getRow();            int col = cell.getCol();            wall[row][col] = cell;        }    }    //判断四方格能否下落    public boolean camDrop() {        Cell[] cells = currentOne.cells;        for (Cell cell : cells) {            int row = cell.getRow();            int col = cell.getCol();            //判断是否到达底部            if (row == wall.length - 1) {                return false;            } else if (wall[row + 1][col] != null) {                return false;            }        }        return true;    }    //消除行    public void destroyLine() {        int line = 0;        Cell[] cells = currentOne.cells;        for (Cell cell : cells) {            int row = cell.getRow();            if (isFullLine(row)) {                line++;                for (int i = row; i > 0; i--) {                    System.arraycopy(wall[i - 1], 0, wall[i], 0, wall[0].length);                }                wall[0] = new Cell[9];            }        }        //分数池获取分数,累加到总分        totalScore += scores_pool[line];        //总行数        totalLine += line;    }    //判断当前行是否已经满了    public boolean isFullLine(int row) {        Cell[] cells = wall[row];        for (Cell cell : cells) {            if (cell == null) {                return false;            }        }        return true;    }    //判断游戏是否结束    public boolean isGameOver() {        Cell[] cells = nextOne.cells;        for (Cell cell : cells) {            int row = cell.getRow();            int col = cell.getCol();            if (wall[row][col] != null) {                return true;            }        }        return false;    }    private void paintState(Graphics g) {        if (game_state == PLING) {            g.drawString(show_state[PLING], 500, 660);        } else if (game_state == STOP) {            g.drawString(show_state[STOP], 500, 660);        } else {            g.drawString(show_state[OVER], 500, 660);            g.setColor(Color.RED);            g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 60));            g.drawString("GAME OVER!", 30, 400);        }    }    private void paintSource(Graphics g) {        g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 30));        g.drawString("分数: " + totalScore, 500, 250);        g.drawString("行数: " + totalLine, 500, 430);    }    private void paintNextOne(Graphics g) {        Cell[] cells = nextOne.cells;        for (Cell cell : cells) {            int x = cell.getCol() * CELL_SIZE + 370;            int y = cell.getRow() * CELL_SIZE + 25;            g.drawImage(cell.getImage(), x, y, null);        }    }    private void paintCurrentOne(Graphics g) {        Cell[] cells = currentOne.cells;        for (Cell cell : cells) {            int x = cell.getCol() * CELL_SIZE;            int y = cell.getRow() * CELL_SIZE;            g.drawImage(cell.getImage(), x, y, null);        }    }    private void paintWall(Graphics g) {        for (int i = 0; i < wall.length; i++) {            for (int j = 0; j < wall[i].length; j++) {                int x = j * CELL_SIZE;                int y = i * CELL_SIZE;                Cell cell = wall[i][j];                //判断是否有小方块                if (cell == null) {                    g.drawRect(x, y, CELL_SIZE, CELL_SIZE);                } else {                    g.drawImage(cell.getImage(), x, y, null);                }            }        }    }    //判断是否出界    public boolean outOFBounds() {        Cell[] cells = currentOne.cells;        for (Cell cell : cells) {            int col = cell.getCol();            int row = cell.getRow();            if (row < 0 || row > wall.length - 1 || col < 0 || col > wall[0].length-1) {                return true;            }        }        return false;    }    //按键一次,左移一次    public void moveleftActive() {        currentOne.moveLeft();        //判断是否越界或重合        if (outOFBounds() || coincide()) {            currentOne.moveRight();        }    }    //按键一次,右移一次    public void moveRightActive() {        currentOne.moveRight();        //判断是否越界或重合        if (outOFBounds() || coincide()) {            currentOne.moveLeft();        }    }    //判断是否重合    public boolean coincide() {        Cell[] cells = currentOne.cells;        for (Cell cell : cells) {            int row = cell.getRow();            int col = cell.getCol();            if (wall[row][col] != null) {                return true;            }        }        return false;    }    public static void main(String[] args) {        JFrame jFrame = new JFrame("俄罗斯方块");        //创建游戏界面        Tetris panel = new Tetris();        jFrame.add(panel);        //设置可见        jFrame.setVisible(true);        //设置窗口大小        jFrame.setSize(810, 940);        //设置剧中        jFrame.setLocationRelativeTo(null);        //设置窗口关闭时停止        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        //游戏主要开始逻辑        panel.start();    }}

游戏开始,方快下落,右边区域展示即将下落的方块图、分数、消除的行数以及游戏切换的状态。

按下空格键,方块瞬间下落, 按下P键游戏暂停,消除一行分数为1(此处由分数池进行控制)

 按下C键游戏继续。

 按下S键,游戏重新开始。

 方块占满,游戏结束,此时可以按下S键重新开始游戏。

本次游戏中所使用的素材文件以及所有的源代码文件都已经同步到Github,小伙伴们点击下方链接直接获取。

Github链接地址:点击获取完整源代码,下载到本地即可运行https://github.com/xiaoZ-zhao/Tetris

Gitee地址:Tetris: 【开箱即用】使用Java实现俄罗斯方块,开发工具idea - Gitee.comhttps://gitee.com/xiaoZcode/Tetris/tree/master

来源地址:https://blog.csdn.net/Zp_insist/article/details/124740009

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯