详细解读java的俄罗斯方块游戏的源代码--【课程设计】

简介: 详细解读java的俄罗斯方块游戏的源代码--【课程设计】

本系列校训

互相伤害互相卷,玩命学习要你管,天生我才必有用,我命由我不由天!

毕设的技术铺垫

环境及工具:

本系列环境

环境 win11
工具 idea 2018
jdk 1.8
数据库
maven
项目导入方式 打开目录
数据库前端工具

项目说明

这个游戏工作量比较小,也比较粗糙。当做学习还是相当的不错的。当毕业设计就有点拿不出手了。

界面:

总体设计

代码部分

文件编码问题。如果出现乱码,请自行根据下图设置项目编码。

项目文件目录如下:

关键核心代码:

应用软件的核心代码是指这个程序最关键部分的代码。例如WinRAR,它的核心代码就是压缩算法部分,而诸如用户界面、操作系统移植等部分就无足轻重了。

商城类的核心代码是指业务层的代码,比如你商城的核心代码就是:商品、购物车、创建订单、支付这些代码就是核心代码。

作为程序员,我们经常需要看懂别人的代码。特别是在开源社区中,我们需要理解许多优秀的开源项目的代码。而在Gitee这样的代码托管平台上,我们如何快速有效地看懂别人的代码呢?本文将为大家介绍一些方法。

1.阅读README和项目介绍

在Gitee上,许多开源项目都会有自己的README文件或项目介绍。这些文件一般会介绍项目的背景、功能、使用方法等内容,可以帮助我们快速了解这个开源项目的基本情况。如果我们能够从这些文件中找到与自己相关的内容,就可以快速入手这个开源项目的代码。

2.了解项目结构和代码组织

在阅读代码之前,我们需要先了解这个开源项目的代码结构和代码组织方式。通常,开源项目会将不同的功能模块封装到不同的代码文件中,并按照一定的目录结构组织起来。如果我们能够了解这个开源项目的代码组织方式,就能更加快速地找到所需的代码。

3.利用IDE和工具

IDE和一些代码阅读工具可以帮助我们更快速、更高效地阅读代码。例如,Java开发者可以使用Eclipse或IntelliJ IDEA这样的IDE,可以快速打开代码文件、查看类、方法和变量等信息。另外,一些代码阅读工具,如Source Insight、CodeCompare等,可以帮助我们更方便地查看代码的结构和关系,以及快速跳转到相关代码。

4.关注代码注释和文档

良好的代码注释和文档可以帮助我们更快速地理解代码。因此,在阅读别人的代码时,我们可以将注意力放在代码注释和文档上。有些开源项目会提供详细的文档,有些则注重代码注释。如果我们能够针对代码注释和文档有一个系统的阅读和理解,就能更快速地掌握别人的代码。

5.跑通测试和运行项目

如果我们想更深入地了解别人的代码,可以试着跑通相关的测试,或者直接运行这个开源项目。通过跑测试和运行项目,我们可以更加直观地了解代码的实现细节和具体的业务逻辑。

总结:

以上就是在Gitee上快速理解他人代码的一些方法,希望对大家有所帮助。当然,阅读代码是一件需要耐心和细心的事情,需要我们多花一点时间和心思。只有沉下心来,慢慢阅读每一行代码,才能真正理解它们的含义和作用。

我方飞机

//Java版简易俄罗斯方块
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class TetrisFrame extends JFrame implements ActionListener{
  static JMenu game = new JMenu("游戏");
  JMenuItem newgame = game.add("新游戏");
  JMenuItem pause = game.add("暂停");
  JMenuItem goon = game.add("继续");
  JMenuItem exit = game.add("退出");
  static JMenu help = new JMenu("帮助");
  JMenuItem about = help.add("关于");
  Tetrisblok a = new Tetrisblok();
  public TetrisFrame() {    
    addKeyListener(a); 
    this.add(a);
    newgame.addActionListener(this); //新游戏菜单项
    pause.addActionListener(this);   //暂停菜单项
    goon.addActionListener(this);   //继续菜单项
    about.addActionListener(this);   //关于菜单项
    exit.addActionListener(this);   //退出菜单项
  }
  public void actionPerformed(ActionEvent e) {
    if(e.getSource()==newgame) //新游戏菜单项
    {
      a.newGame();
    }else if(e.getSource()==pause) //暂停菜单项
    {
      a.pauseGame();
    }else if(e.getSource()==goon) //继续菜单项
    {
      a.continueGame();
    }else if(e.getSource()==about) //关于菜单项
    {
      DisplayToast("左右键移动,向上键旋转");
    }else if(e.getSource()==exit) //退出菜单项
    {
      System.exit(0);
    }
  }
    public void DisplayToast(String str) {
        JOptionPane.showMessageDialog(null, str, "提示", 
                        JOptionPane.ERROR_MESSAGE);
    }
  public static void main(String[] args) {
    TetrisFrame frame = new TetrisFrame();
    JMenuBar menu = new JMenuBar();
    frame.setJMenuBar(menu);
    menu.add(game);
    menu.add(help);
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//结束按钮可用
    frame.setSize(320, 395);
    frame.setTitle("俄罗斯方块1.0版");
    // frame.setUndecorated(true);
    frame.setVisible(true);
    frame.setResizable(false);    
  }
}

解析主程序。

主流程。

TetrisFrame frame = new TetrisFrame();
    JMenuBar menu = new JMenuBar();
    frame.setJMenuBar(menu);
    menu.add(game);
    menu.add(help);
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//结束按钮可用
    frame.setSize(320, 395);
    frame.setTitle("俄罗斯方块1.0版");
    // frame.setUndecorated(true);
    frame.setVisible(true);
    frame.setResizable(false);  

构造

addKeyListener(a); 
    this.add(a);
    newgame.addActionListener(this); //新游戏菜单项
    pause.addActionListener(this);   //暂停菜单项
    goon.addActionListener(this);   //继续菜单项
    about.addActionListener(this);   //关于菜单项
    exit.addActionListener(this);   //退出菜单项

对菜单的响应

public void actionPerformed(ActionEvent e) {
    if(e.getSource()==newgame) //新游戏菜单项
    {
      a.newGame();
    }else if(e.getSource()==pause) //暂停菜单项
    {
      a.pauseGame();
    }else if(e.getSource()==goon) //继续菜单项
    {
      a.continueGame();
    }else if(e.getSource()==about) //关于菜单项
    {
      DisplayToast("左右键移动,向上键旋转");
    }else if(e.getSource()==exit) //退出菜单项
    {
      System.exit(0);
    }
  }

另一个主类 , 用于画。 画方块,画外框。

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;
//2012-7-20
//21:00
//xmj
// 创建一个俄罗斯方块类
class Tetrisblok extends JPanel implements KeyListener {  
  private int blockType;// blockType 代表方块类型 
  private int turnState;// turnState代表方块状态
  private int score = 0;
  private int x,y;    //当前方块位置
  private int nextblockType=-1,nextturnState=-1;  //下一方块类型和状态
  private Timer timer;//定时器
  // 存储已经放下的方块(1)及围墙(2)
  int[][] map = new int[12][21];
  // 方块的形状 
  //第一组代表方块类型有Z、L、J、I、 田、T 6种
  //第二组第三四组为旋转几次后的方块矩阵
  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 } },
        // 倒z字形
      { { 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 } },
      // 田字形
      { { 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 } },
      // ⊥字形
      { { 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() {
    //没有下一方块
    if(nextblockType==-1 && nextturnState==-1){
      blockType = (int) (Math.random() * 1000) % 7;
      turnState = (int) (Math.random() * 1000) % 4;
      nextblockType=(int) (Math.random() * 1000) % 7;
      nextturnState=(int) (Math.random() * 1000) % 4;
    }
    else{//已有下一方块
      blockType = nextblockType;
      turnState = nextturnState;
      nextblockType=(int) (Math.random() * 1000) % 7;
      nextturnState=(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() {
    int i ,j;
    for (i = 0; i < 12; i++) {
      map[i][20] = 2;
    }
    for (j = 0; j < 21; j++) {
      map[11][j] = 2;
      map[0][j] = 2;
    }
  }
  // 初始化地图
  public void newmap() {
    int i ,j;
    for (i = 0; i < 12; i++) {
      for (j = 0; j < 21; j++) {
        map[i][j] = 0;
      }
    }
  }
  // 初始化构造方法
  Tetrisblok() {
    newblock();
    newmap();
    drawwall();
    timer = new Timer(500, new TimerListener());//0.5秒
    timer.start();
  }
  // 定时器监听
  class TimerListener implements ActionListener {
    public void actionPerformed(ActionEvent e) {
      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);
        delline();
        newblock();
      }
      repaint();//屏幕重画
    }
  }
  public void newGame()//新游戏
  {
    newblock();
    newmap();
    drawwall();
  }
  public void pauseGame()//暂停游戏
  {
    timer.stop();
  }
  public void continueGame()//继续游戏
  {
    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 < 21; 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 < 12; 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 (shapes[blockType][turnState][j] == 1) {
          map[x + b + 1][y + a] = shapes[blockType][turnState][j];
        }
        j++;
      }
    }
  }
  int yanse = (int)(Math.random()*10);
  //paint(Graphics g)是屏幕重画的方法。
  public void paint(Graphics g) {
    super.paint(g);//调用父类的paint()方法,实现初始化清屏
    if(yanse>8) g.setColor(Color.BLUE);
    else if (yanse>6) g.setColor(Color.green);
    else if (yanse>4) g.setColor(Color.magenta);
    else if (yanse>2) g.setColor(Color.CYAN);
    else if (yanse>0) g.setColor(Color.pink);
    else g.setColor(Color.CYAN);
    int i ,j;
    // 画当前方块
    for (j = 0; j < 16; j++) {
      if (shapes[blockType][turnState][j] == 1) {
        g.fillRect((j % 4 + x + 1) * 15, (j / 4 + y) * 15, 15, 15);
      }
    }
    // 画已经固定的方块和围墙
    for (j = 0; j < 21; j++) {
      for (i = 0; i < 12; i++) {
        if (map[i][j] == 1) { //画已经固定的方块
          g.fillRect(i * 15, j * 15, 15, 15);
        }
        if (map[i][j] == 2) {//画围墙
          g.drawRect(i * 15, j * 15, 15, 15);
        }
      }
    }
    g.drawString("score=" + score, 225, 15);
    g.drawString("下一方块形状", 225, 50);
    int W=15;
    Image myImage = Toolkit.getDefaultToolkit().getImage("block0.gif");
    //窗口右侧区域绘制下一方块
    for (j = 0; j < 16; j++) {
      if (shapes[nextblockType][nextturnState][j] == 1) {
        g.fillRect(225+(j % 4 ) * 15, (j / 4 ) * 15+100, 15, 15);
        g.drawImage(myImage, 225+(j % 4 ) * 15, (j / 4 ) * 15+200, W, W,this);
      }
    }
//    int W=15;
//    Image myImage = Toolkit.getDefaultToolkit().getImage("block0.gif");
//    g.drawImage(myImage, 100, 200, W, W,this);
  }
  // 键盘监听
  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) {
      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);
        delline();
        newblock();
      }
      repaint();//屏幕重画
    }
  }

这是一个总的思想。

就是说,把这个游戏的“画面” 每秒截屏。

那么,每一次,只要重画这个屏就行了。

根本不需要管什么动态不动态。

这几个关键的点解读好了,那么整个游戏也就比较容易懂了。

。。。

后面的代码用于学习提高好了。

第三个类。Test类。测试之用,跟游戏其实无关。

界面

论文参考

基于java的坦克大战游戏的设计与实现–毕业论文–【毕业论文】

https://blog.csdn.net/dearmite/article/details/131962993

配套资源

详细解读java的俄罗斯方块游戏的源代码–【课程设计】

相关文章
|
5月前
|
Java 索引
Java实现扑克牌游戏 | 随机发牌 ( 过程拆分详解+完整代码 )
Java实现扑克牌游戏 | 随机发牌 ( 过程拆分详解+完整代码 )
132 3
|
2月前
|
开发框架 IDE Java
java制作游戏,如何使用libgdx,入门级别教学
本文是一篇入门级教程,介绍了如何使用libgdx游戏开发框架创建一个简单的游戏项目,包括访问libgdx官网、设置项目、下载项目生成工具,并在IDE中运行生成的项目。
63 1
java制作游戏,如何使用libgdx,入门级别教学
|
4月前
|
人工智能 算法 Java
LeetCode经典算法题:井字游戏+优势洗牌+Dota2参议院java解法
LeetCode经典算法题:井字游戏+优势洗牌+Dota2参议院java解法
55 1
|
5月前
|
Java 编译器 开发者
Java演进问题之Truffle处理不同编程语言的源代码或中间格式如何解决
Java演进问题之Truffle处理不同编程语言的源代码或中间格式如何解决
|
6月前
|
存储 Java C语言
Java面向对象课程设计--类管理系统
Java面向对象课程设计--类管理系统
38 1
|
6月前
|
前端开发 JavaScript Java
计算机Java项目|游戏美术外包管理信息系统
计算机Java项目|游戏美术外包管理信息系统
|
6月前
|
Java 编译器 C语言
JAVA如何编译源代码
JAVA如何编译源代码
38 0
|
6月前
|
Java
使用java编写猜数字游戏
使用java编写猜数字游戏
|
6月前
|
Java API 开发工具
个人微信api接口java调用源代码
个人微信api接口java调用源代码
|
Java Maven
【号外】-一款高效的Java源代码解析器
【号外】-一款高效的Java源代码解析器QDox
1817 0
【号外】-一款高效的Java源代码解析器