java俄罗斯方块详解

【Java】俄罗斯方块小游戏(附源码)_500行可运行小游戏代码-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/weixin_48701521/article/details/121709104本文是对上面文章代码的解释。

一:一些包和类

package 俄罗斯方块;//定义了一个名为俄罗斯方块的包。包是用来组织类和接口的一种机制,通常为了避免类名冲突和方便管理代码

import java.awt.*;//导入Java AWT(Abstract Window Toolkit)库中的所有类。AWT是Java用于创建图形用户界面的工具包。*指所有
import java.awt.event.*;//这些类用于处理事件(例如鼠标点击、键盘输入等)
import javax.swing.*; //Swing用于创建图形用户界面的更现代化的工具包,相对于AWT提供了更丰富的组件和更强的功能。
import java.applet.*;//Applet是用于创建嵌入在网页中的小型应用程序的类,不过在现代Java应用中已经很少使用
import java.lang.String.*;//导入java.lang.String类中的所有嵌套类,java.lang.String:用于处理字符串的类
import java.lang.*;//包含了Java语言的核心类(例如基本类型的包装类、基本的数学函数、系统相关的实用工具类等
import java.io.*;//这些类用于处理输入和输出操作,例如文件读写、数据流操作等

public class Block extends JPanel implements ActionListener,KeyListener//应该是继承JPanel
{
//定义了一个名为 Block 的类,该类继承自 JPanel 并实现了 ActionListener 和 KeyListener 接口。
  • Block 类继承自 JPanel,意味着它是一个可以作为 Swing 容器使用的组件。
  • Block 类实现了 ActionListenerKeyListener 接口,意味着它将实现这些接口定义的方法,用于处理操作和键盘事件。

	static Button but[] = new Button[6];
	static Button noStop = new Button("取 消 暂 停");//定义了一个静态的Button对象,命名为noStop,按钮上的标签为“取消暂停”。这是一个用来创建图形用户界面按钮的组件,当用户点击这个按钮时,程序可以取消当前的暂停状态。
	static Label scoreLab = new Label("分数:");//定静Label对象,名scoreLab,标签的文本内容为“分数:”。用于在图形用户界面上显示文本的组件,这里用于显示分数的标签说明。
	static Label infoLab = new Label("提示:");//同scoreLab,显示提示信息的标签说明。
	static Label speedLab = new Label("级数:");//显示游戏级别(速度)的标签说明。
	static Label scoreTex = new Label("0");//显示当前分数的组件,初始分数为0
	static Label infoTex = new Label(" ");//提示信息内容的组件,初始内容为空
	static Label speedTex = new Label("1");//显示当前游戏级别(速度)的组件,初始级别为1。
	
	static JFrame jf = new JFrame();//定义并初始化 JFrame 对象 jf,用作游戏的主窗口
	static MyTimer timer; //声明一个静态的 MyTimer 对象 timer,用于游戏的计时。
	static ImageIcon icon=new ImageIcon("resource/Block.jpg");//初始化,加载位于 "resource/Block.jpg" 的图像,
	static JMenuBar mb = new JMenuBar();//静态的 JMenuBar 对象 mb,这是一个菜单栏。
	static JMenu menu0 = new JMenu("游  戏 ");//初始化,菜单的标题为“游戏”。
	static JMenu menu1 = new JMenu("帮  助 ");//菜单的标题为“帮助”
	static JMenuItem mi0 = new JMenuItem("新 游 戏");//同上
	static JMenuItem mi1 = new JMenuItem("退  出");//同上
	static JMenuItem mi1_0 = new JMenuItem("关  于");//同上
   static JDialog dlg_1;//JDialog 对象 dlg_1,可能用于弹出对话框。
	static JTextArea dlg_1_text = new JTextArea();//表示游戏的状态。0 表示未开始,1 表示开始,2 表示暂停。
	static int startSign = 0;//游戏开始标志 0 未开始 1 开始 2 暂停
	static String butLab[] = {"开 始 游 戏","重 新 开 始","降 低 级 数","提 高 级 数","游 戏 暂 停","退 出 游 戏"};
	static int game_body[][] = new int[19][10];//初始化二维数组 game_body,用于表示游戏的主要区域。
	static int game_sign_x[] = new int[4];//用于记录4个方格的水平位置
	static int game_sign_y[] = new int[4];//用于记录4个方格的垂直位置
	static boolean downSign = false;//是否落下
	static int blockNumber = 1;//砖块的编号
	static int gameScore = 0;//游戏分数
	static int speedMark = 1;//游戏速度等级
	
	

public static void main(String args[]) 
	{
		Block myBlock = new Block();//是游戏的主要组件,负责绘制和管理游戏逻辑。
		mb.add(menu0);
		mb.add(menu1);//将两个菜单 menu0(“游戏”)和 menu1(“帮助”)添加到菜单栏 mb
		menu0.add(mi0);
		menu0.add(mi1);//菜单项 mi0(“新游戏”)和 mi1(“退出”)添加到 menu0(“游戏”)菜单中。
		menu1.add(mi1_0);//将菜单项 mi1_0(“关于”)添加到 menu1(“帮助”)菜单中。

	    jf.setJMenuBar(mb);	//将菜单栏 mb 设置为主窗口 jf 的菜单栏。
	    
	    myBlock.init();//初始化 Block 对象,设置游戏的初始状态
	    jf.add(myBlock);//将 myBlock 添加到主窗口 jf 中,使其成为窗口的一个组件。
	    jf.setSize(565,501);//设置主窗口 jf 的大小,宽,高
		jf.setResizable(false);//禁止用户调整主窗口 jf 的大小
		jf.setTitle("俄罗斯方块");//设置主窗口 jf 的标题
		jf.setIconImage(icon.getImage());//设置主窗口 jf 的图标为加载的 icon 图像。


		jf.setLocation(200,100);//设置主窗口 jf 的初始位置,显示在屏幕上坐标 (200, 100) 
		jf.show();//这个方法已经过时,用jf.setVisible(true)!!!!!!!!!!!!!!!!!
		timer = new MyTimer(myBlock); //启动线程,创建一个 MyTimer 类的实例 timer,传递 myBlock 作为参数,假设 MyTimer 是一个用于控制游戏时间和逻辑的线程。
       timer.setDaemon(true);//timer 线程设置为守护线程,这意味着当所有非守护线程结束时,程序将自动退出。

java

       timer.start();//启动 timer 线程
       timer.suspend();//挂起 timer 线程的执行。请注意,suspend 方法是过时的且不安全的,在现代Java应用中应使用其他方式来控制线程的执行(例如,使用 wait 和 notify 方法)
	}

public void init()//公共方法 init,用于初始化界面组件和布局
	{

setLayout(null);//布局管理器设置为 null,表示使用绝对布局,即手动设置每个组件的位置和大小。
   	
for(int i = 0;i < 6;i++)//使用一个循环初始化 6 个按钮
   	{
   		but[i] = new Button(butLab[i]);//创建一个按钮,标签为 butLab 数组中的第 i 个元素。
   		add(but[i]);//将按钮添加到当前容器中
   		but[i].addActionListener(this);//为按钮添加一个动作事件监听器。
   		but[i].addKeyListener(this);//添加键盘事件监听器
   		but[i].setBounds(360,(240 + 30 * i),160,25);//设置按钮的位置和大小
   	}
       
       add(scoreLab);//将标签和文本框组件添加到当前容器中。
       add(scoreTex);

       add(speedLab);
       add(speedTex);

       add(infoLab);
       add(infoTex);

       add(scoreLab);//重复添加了!!!!!!!!!!!
       scoreLab.setBounds(320,15,30,20);//scoreLab 的位置和大小。
       scoreTex.setBounds(360,15,160,20);//scoreTex 的位置和大小。
       scoreTex.setBackground(Color.white);//设置 scoreTex 的背景颜色为白色。
		
       speedLab.setBounds(320,45,30,20);//同上
       speedTex.setBounds(360,45,160,20);
       speedTex.setBackground(Color.white);
		
       infoLab.setBounds(320,75,30,20);//同上
       infoTex.setBounds(360,75,160,20);
       infoTex.setBackground(Color.white);
		
		but[1].setEnabled(false);//禁用 but 数组中的第 1 和第 4 个按钮。
		but[4].setEnabled(false);
		
		noStop.setBounds(360,360,160,25);
		noStop.addActionListener(this);//为 noStop 按钮添加一个动作事件监听器。
		noStop.addKeyListener(this);//添加一个键盘事件监听器。
		
		mi0.addActionListener(this);// mi0、mi1 和 mi1_0 添加动作事件监听器。
		mi1.addActionListener(this);
		mi1_0.addActionListener(this);
		
		num_csh_game();//始化游戏数字缓存。
		rand_block();//调用 rand_block 用于生成随机方块
   }
   

 public void actionPerformed(ActionEvent e)//处理按钮和菜单项的点击事件。

   {
   	if(e.getSource() == but[0])//开始游戏检查事件源是否为 but[0] 按钮(开始游戏按钮)。
   	{
   		startSign = 1;//表示游戏开始。
   		infoTex.setText("游戏已经开始!");//在 infoTex 文本框中显示 "游戏已经开始!"。
   		but[0].setEnabled(false);//禁用 but[0](开始游戏 )按钮。
   		but[1].setEnabled(true);//启用 but[1] 和 but[4] 按钮。
		but[4].setEnabled(true);
		timer.resume(); //调用 timer.resume() 恢复计时器(启动游戏计时)。
   	}

   	if(e.getSource() == but[1]||e.getSource() == mi0)//重新开始游戏或 mi0 菜单项。
	{
   		startSign = 0;//游戏停止。
   		gameScore = 0;//重置游戏分数 gameScore 为 0。
   		timer.suspend();//暂停计时器
   		num_csh_restart();//重置游戏状态。
   		repaint();//重新绘制游戏界面。
   		rand_block();//生成新的方块。
   		scoreTex.setText("0");//scoreTex 文本框中显示 "0"。
   		infoTex.setText("新游戏!");//infoTex 文本框中显示 "新游戏!"。
   		but[0].setEnabled(true);//启用 开始游戏 按钮
   		but[1].setEnabled(false);//禁用 重新开始 和 but[4] 按钮。
		but[4].setEnabled(false);
   	}
   	if(e.getSource() == but[2])//降低级数
   	{
   		infoTex.setText("降低级数!");显示 "降低级数!"。

   		speedMark--;//减少 speedMark 值
   		if(speedMark <= 1)
   		{//如果 speedMark 小于或等于 1,将其设置为 1,并在 infoTex 文本框中显示 "已经是最低级数!"。
   			speedMark = 1;
   			infoTex.setText("已经是最低级数!");
   		}
   		speedTex.setText(speedMark + "");//在 speedTex 文本框中显示 speedMark 的值
   	}
   	if(e.getSource() == but[3])//提高级数  同上
   	{
   		infoTex.setText("提高级数!");
   		speedMark++;
   		if(speedMark >= 9)
   		{
   			speedMark = 9;
   			infoTex.setText("已经是最高级数!");
   		}
   		speedTex.setText(speedMark + "");
   	}
   	if(e.getSource() == but[4])//游戏暂停
   	{
   		this.add(noStop);将 noStop 按钮添加到当前容器。



   		this.remove(but[4]);//从当前容器中移除暂停游戏 按钮。
   		infoTex.setText("游戏暂停!");//infoTex 文本框显示 "游戏暂停!"。
   		timer.suspend();//暂停计时器。
   	}
   	if(e.getSource() == noStop)//取消暂停
   	{
   		this.remove(noStop);从当前容器中移除 noStop 按钮。
   		this.add(but[4]);//将 游戏暂停 按钮添加到当前容器。
   		infoTex.setText("继续游戏!");
   		timer.resume();//恢复计时器
   	}
   	if(e.getSource() == but[5]||e.getSource() == mi1)//退出游戏
   	{
   		jf.dispose();//调用 jf.dispose() 关闭游戏窗口并退出程序。
   	}
   	if(e.getSource() == mi1_0)/创建一个新的 JDialog 对象 dlg_1,标题为 "关 于"。



   	{
   		dlg_1 = new JDialog(jf,"关 于");
		    try{//尝试读取文件 resource/guanyu.txt 中的内容:
		    	FileInputStream io = new FileInputStream("resource/guanyu.txt");//得到路径//创建 FileInputStream 对象 io。
		        byte a[] = new byte[io.available()];
		        io.read(a);//读取文件内容到字节数组 a 中。
		        io.close();//关闭输入流 io。
		        String str = new String(a);//将字节数组 a 转换为字符串 str 并设置到 dlg_1_text 文本框中
		        dlg_1_text.setText(str);
		        }
		        catch(Exception g){g.printStackTrace();}//如果读取文件时出现异常,打印堆栈跟踪信息。
		        dlg_1_text.setEditable(false);//文本框为不可编辑。
		        dlg_1.add(dlg_1_text);//文本框添加到 dlg_1 对话框中
			    dlg_1.pack();//调整对话框大小以适应内容。
               dlg_1.setResizable(false);//设置对话框不可调整大小。
               dlg_1.setSize(200, 120);//设置对话框的大小为 200x120 像素。
               dlg_1.setLocation(400, 240);//设置对话框的位置为 (400, 240)。
               dlg_1.show();//显示对话框 dlg_1
   	}
}
   


public void change_body(int blockNumber)//改变砖块状态
   {
    dingwei();
   	if(blockNumber == 1&&downSign == false)//变换长条2种情况
   	{
   		if(game_sign_y[0] == game_sign_y[1]&&game_sign_y[3] <= 16)//说明长条是横着的
   		{
   			if(game_body[game_sign_y[0] - 1][game_sign_x[0] + 1] != 2&&game_body[game_sign_y[3] + 2][game_sign_x[3] - 2] != 2)
   			{
   				num_csh_game();
   			    game_body[game_sign_y[0] - 1][game_sign_x[0] + 1] = 1;
   			    game_body[game_sign_y[1]][game_sign_x[1]] = 1;
   			    game_body[game_sign_y[2] + 1][game_sign_x[2] - 1] = 1;
   			    game_body[game_sign_y[3] + 2][game_sign_x[3] - 2] = 1;
   			    infoTex.setText("游戏进行中!");
   			    repaint();
   			}
   		}
   		if(game_sign_x[0] == game_sign_x[1]&&game_sign_x[0] >= 1&&game_sign_x[3] <= 7)//说明长条是竖着的
   		{
   			if(game_body[game_sign_y[0] + 1][game_sign_x[0]-1] != 2&&game_body[game_sign_y[3] - 2][game_sign_x[3] + 2] != 2)
   			{
   				num_csh_game();
   			    game_body[game_sign_y[0] + 1][game_sign_x[0] - 1] = 1;
   			    game_body[game_sign_y[1]][game_sign_x[1]]=1;
   			    game_body[game_sign_y[2] - 1][game_sign_x[2] + 1] = 1;
   			    game_body[game_sign_y[3] - 2][game_sign_x[3] + 2] = 1;
   			    infoTex.setText("游戏进行中!");
   			    repaint();
   			}
   		}
   	}
   	if(blockNumber == 3&&downSign == false)//变换转弯1有4种情况
   	{
   		if(game_sign_x[0] == game_sign_x[1]&&game_sign_x[0] == game_sign_x[2]&&game_sign_y[2] == game_sign_y[3]&&game_sign_x[0] >= 1)
   		{
   			if(game_body[game_sign_y[0] + 1][game_sign_x[0] - 1] != 2&&game_body[game_sign_y[2] - 1][game_sign_x[2] + 1] != 2&&game_body[game_sign_y[3] - 2][game_sign_x[3]] != 2)
   			{
   			    num_csh_game();
   			    game_body[game_sign_y[0] + 1][game_sign_x[0] - 1] = 1;
   			    game_body[game_sign_y[1]][game_sign_x[1]] = 1;
   			    game_body[game_sign_y[2] - 1][game_sign_x[2] + 1] = 1;
   			    game_body[game_sign_y[3] - 2][game_sign_x[3]] = 1;
   			    infoTex.setText("游戏进行中!");
   			    repaint();
   			}	
   		}
   		if(game_sign_y[1] == game_sign_y[2]&&game_sign_y[2] == game_sign_y[3]&&game_sign_x[0] == game_sign_x[3]&&game_sign_y[1] <= 17)
   		{
   			if(game_body[game_sign_y[0]][game_sign_x[0] - 2] != 2&&game_body[game_sign_y[1] + 1][game_sign_x[1] + 1] != 2&&game_body[game_sign_y[3] - 1][game_sign_x[3] - 1] != 2)
   			{
       			num_csh_game();
   			    game_body[game_sign_y[0]][game_sign_x[0] - 2] = 1;	
   			    game_body[game_sign_y[1] + 1][game_sign_x[1] + 1] = 1;
   			    game_body[game_sign_y[2]][game_sign_x[2]] = 1;
   			    game_body[game_sign_y[3] - 1][game_sign_x[3] - 1] = 1;
   			    infoTex.setText("游戏进行中!");
   			    repaint();
   			}	
   		}
   		if(game_sign_x[1] == game_sign_x[2]&&game_sign_x[1] == game_sign_x[3]&&game_sign_y[0] == game_sign_y[1]&&game_sign_x[3] <= 8)
   		{
   			if(game_body[game_sign_y[0] + 2][game_sign_x[0]] != 2&&game_body[game_sign_y[1] + 1][game_sign_x[1] - 1] != 2&&game_body[game_sign_y[3] - 1][game_sign_x[3] + 1] != 2)
   			{
       			num_csh_game();
   			    game_body[game_sign_y[0] + 2][game_sign_x[0]] = 1;	
   			    game_body[game_sign_y[1] + 1][game_sign_x[1] - 1] = 1;
   			    game_body[game_sign_y[2]][game_sign_x[2]] = 1;
   			    game_body[game_sign_y[3] - 1][game_sign_x[3] + 1] = 1;
   			    infoTex.setText("游戏进行中!");
   			    repaint();
   			}	
   		}
   		if(game_sign_y[0] == game_sign_y[1]&&game_sign_y[1] == game_sign_y[2]&&game_sign_x[0] == game_sign_x[3])
   		{
   			if(game_body[game_sign_y[0] + 1][game_sign_x[0] + 1] != 2&&game_body[game_sign_y[2] - 1][game_sign_x[2] - 1] != 2&&game_body[game_sign_y[3]][game_sign_x[3] + 2] != 2)
   			{
       			num_csh_game();
   			    game_body[game_sign_y[0] + 1][game_sign_x[0] + 1] = 1;
   			    game_body[game_sign_y[1]][game_sign_x[1]] = 1;
   			    game_body[game_sign_y[2] - 1][game_sign_x[2] - 1] = 1;
   			    game_body[game_sign_y[3]][game_sign_x[3] + 2] = 1;
   			    infoTex.setText("游戏进行中!");
   			    repaint();
   			}	
   		}
   	}
   	if(blockNumber == 4&&downSign == false)//变换转弯2有4种情况
   	{
   		if(game_sign_x[0] == game_sign_x[1]&&game_sign_x[0] == game_sign_x[3]&&game_sign_y[1] == game_sign_y[2]&&game_sign_x[3] <= 7)
   		{
   			if(game_body[game_sign_y[0] + 2][game_sign_x[0]] != 2&&game_body[game_sign_y[1] + 1][game_sign_x[1] + 1] != 2&&game_body[game_sign_y[3]][game_sign_x[3] + 2] != 2)
   			{
       			num_csh_game();
   			    game_body[game_sign_y[0] + 2][game_sign_x[0]] = 1;
   			    game_body[game_sign_y[1] + 1][game_sign_x[1] + 1] = 1;
   			    game_body[game_sign_y[2]][game_sign_x[2]] = 1;
   			    game_body[game_sign_y[3]][game_sign_x[3] + 2] = 1;
   			    infoTex.setText("游戏进行中!");
   			    repaint();
   			}	
   		}
   		if(game_sign_y[1] == game_sign_y[2]&&game_sign_y[1] == game_sign_y[3]&&game_sign_x[0] == game_sign_x[2])
   		{
   			if(game_body[game_sign_y[1]][game_sign_x[1] + 2] != 2&&game_body[game_sign_y[2] - 1][game_sign_x[2] + 1] != 2&&game_body[game_sign_y[3] - 2][game_sign_x[3]] != 2)
   			{
       			num_csh_game();
   			    game_body[game_sign_y[0]][game_sign_x[0]] = 1;
   			    game_body[game_sign_y[1]][game_sign_x[1] + 2] = 1;
   			    game_body[game_sign_y[2] - 1][game_sign_x[2] + 1] = 1;
   			    game_body[game_sign_y[3] - 2][game_sign_x[3]] = 1;
   			    infoTex.setText("游戏进行中!");
   			    repaint();
   			}	
   		}
   		if(game_sign_x[0] == game_sign_x[2]&&game_sign_x[0] == game_sign_x[3]&&game_sign_y[1] == game_sign_y[2]&&game_sign_x[0] >= 2)
   		{
   			if(game_body[game_sign_y[0]][game_sign_x[0] - 2] != 2&&game_body[game_sign_y[2] - 1][game_sign_x[2] - 1] != 2&&game_body[game_sign_y[3] - 2][game_sign_x[3]] != 2)
   			{
       			num_csh_game();
   		    	game_body[game_sign_y[0]][game_sign_x[0] - 2] = 1;
   		    	game_body[game_sign_y[1]][game_sign_x[1]] = 1;
   		    	game_body[game_sign_y[2] - 1][game_sign_x[2] - 1] = 1;
   			    game_body[game_sign_y[3] - 2][game_sign_x[3]] = 1;
   			    infoTex.setText("游戏进行中!");
   			    repaint();
   			}	
   		}
   		if(game_sign_y[0] == game_sign_y[1]&&game_sign_y[0] == game_sign_y[2]&&game_sign_x[1] == game_sign_x[3]&&game_sign_y[0] <= 16)
   		{
   			if(game_body[game_sign_y[0] + 2][game_sign_x[0]] != 2&&game_body[game_sign_y[1] + 1][game_sign_x[1] - 1] != 2&&game_body[game_sign_y[2]][game_sign_x[2] - 2] != 2)
   			{
       			num_csh_game();
   			    game_body[game_sign_y[0] + 2][game_sign_x[0]] = 1;
   			    game_body[game_sign_y[1] + 1][game_sign_x[1] - 1] = 1;
   			    game_body[game_sign_y[2]][game_sign_x[2] - 2] = 1;
   			    game_body[game_sign_y[3]][game_sign_x[3]] = 1;
   			    infoTex.setText("游戏进行中!");
   			    repaint();
   			}	
   		}
   	}
   	if(blockNumber == 5&&downSign == false)//变换转弯3有4种情况
   	{
   		if(game_sign_x[0] == game_sign_x[2]&&game_sign_x[2] == game_sign_x[3]&&game_sign_y[0] == game_sign_y[1]&&game_sign_x[1] >= 2)
   		{
   			if(game_body[game_sign_y[0] + 1][game_sign_x[0] - 1] != 2&&game_body[game_sign_y[1]][game_sign_x[1] - 2] != 2&&game_body[game_sign_y[3] - 1][game_sign_x[3] + 1] != 2)
   			{
       			num_csh_game();
   			    game_body[game_sign_y[0] + 1][game_sign_x[0] - 1] = 1;
   			    game_body[game_sign_y[1]][game_sign_x[1] - 2] = 1;
   			    game_body[game_sign_y[2]][game_sign_x[2]] = 1;
   			    game_body[game_sign_y[3] - 1][game_sign_x[3] + 1] = 1;
   			    infoTex.setText("游戏进行中!");
   			    repaint();
   			}
   		}
   		if(game_sign_y[1] == game_sign_y[2]&&game_sign_y[2] == game_sign_y[3]&&game_sign_x[0] == game_sign_x[1]&&game_sign_y[0] <= 16)
   		{
   			if(game_body[game_sign_y[0] + 2][game_sign_x[0]] != 2&&game_body[game_sign_y[1] + 1][game_sign_x[1] + 1] != 2&&game_body[game_sign_y[3] - 1][game_sign_x[3] - 1] != 2)
   			{
      			    num_csh_game();
   			    game_body[game_sign_y[0] + 2][game_sign_x[0]] = 1;
   		     	game_body[game_sign_y[1] + 1][game_sign_x[1] + 1] = 1;
   		    	game_body[game_sign_y[2]][game_sign_x[2]] = 1;
   			    game_body[game_sign_y[3] - 1][game_sign_x[3] - 1] = 1;
   			    infoTex.setText("游戏进行中!");
   			    repaint();
   			}
   		}
   		if(game_sign_x[0] == game_sign_x[1]&&game_sign_x[1] == game_sign_x[3]&&game_sign_y[2] == game_sign_y[3])
   		{
   			if(game_body[game_sign_y[0] + 1][game_sign_x[0] - 1] != 2&&game_body[game_sign_y[2]][game_sign_x[2] + 2] != 2&&game_body[game_sign_y[3] - 1][game_sign_x[3] + 1] != 2)
   			{
       			num_csh_game();
   			    game_body[game_sign_y[0] + 1][game_sign_x[0] - 1] = 1;
   			    game_body[game_sign_y[1]][game_sign_x[1]] = 1;
   			    game_body[game_sign_y[2]][game_sign_x[2] + 2] = 1;
   			    game_body[game_sign_y[3] - 1][game_sign_x[3] + 1] = 1;
   			    infoTex.setText("游戏进行中!");
   			    repaint();
   			}
   		}
   		if(game_sign_y[0] == game_sign_y[1]&&game_sign_y[1] == game_sign_y[2]&&game_sign_x[2] == game_sign_x[3])
   		{
   			if(game_body[game_sign_y[0] + 1][game_sign_x[0] + 1] != 2&&game_body[game_sign_y[2] - 1][game_sign_x[2] - 1] != 2&&game_body[game_sign_y[3] - 2][game_sign_x[3]] != 2)
   			{
       			num_csh_game();
   			    game_body[game_sign_y[0] + 1][game_sign_x[0] + 1] = 1;
   			    game_body[game_sign_y[1]][game_sign_x[1]] = 1;
   			    game_body[game_sign_y[2] - 1][game_sign_x[2] - 1] = 1;
   			    game_body[game_sign_y[3] - 2][game_sign_x[3]] = 1;
   			    infoTex.setText("游戏进行中!");
   			    repaint();
   			}
   		}
   	}
   	if(blockNumber == 6&&downSign == false)//变换两层砖块1的2种情况
   	{
   		if(game_sign_x[0] == game_sign_x[2]&&game_sign_x[0] >= 2)
   		{
   			if(game_body[game_sign_y[0]][game_sign_x[0] - 2] != 2&&game_body[game_sign_y[2] - 1][game_sign_x[2] -1 ] != 2&&game_body[game_sign_y[3] - 1][game_sign_x[3] + 1] != 2)
   			{
       			num_csh_game();
   			    game_body[game_sign_y[0]][game_sign_x[0] - 2] = 1;
   			    game_body[game_sign_y[1]][game_sign_x[1]] = 1;
   			    game_body[game_sign_y[2] - 1][game_sign_x[2] - 1] = 1;
   			    game_body[game_sign_y[3] - 1][game_sign_x[3] + 1] = 1;
   			    infoTex.setText("游戏进行中!");
   			    repaint();
   			}
   		}
   		if(game_sign_y[0] == game_sign_y[1]&&game_sign_y[3] <= 17)
   		{
   			if(game_body[game_sign_y[0]][game_sign_x[0] + 2] != 2&&game_body[game_sign_y[1] + 1][game_sign_x[1] + 1] != 2&&game_body[game_sign_y[3] + 1][game_sign_x[3] - 1] != 2)
   			{
      			    num_csh_game();
   			    game_body[game_sign_y[0]][game_sign_x[0] + 2] = 1;
   			    game_body[game_sign_y[1] + 1][game_sign_x[1] + 1] = 1;
   			    game_body[game_sign_y[2]][game_sign_x[2]] = 1;
   			    game_body[game_sign_y[3] + 1][game_sign_x[3] - 1] = 1;
   			    infoTex.setText("游戏进行中!");
   			    repaint();
   			}
   		}
   	}
   	if(blockNumber == 7&&downSign == false)//变换两层砖块2的2种情况
   	{
   		if(game_sign_x[0] == game_sign_x[1]&&game_sign_x[0] <= 16)
   		{
   			if(game_body[game_sign_y[0]][game_sign_x[0] + 2] != 2&&game_body[game_sign_y[1] - 1][game_sign_x[1] + 1] != 2&&game_body[game_sign_y[3] - 1][game_sign_x[3] - 1] != 2)
   			{
       			num_csh_game();
   			    game_body[game_sign_y[0]][game_sign_x[0] + 2] = 1;
   			    game_body[game_sign_y[1] - 1][game_sign_x[1] + 1] = 1;
   			    game_body[game_sign_y[2]][game_sign_x[2]] = 1;
   			    game_body[game_sign_y[3] - 1][game_sign_x[3] - 1] = 1;
   			    infoTex.setText("游戏进行中!");
   			    repaint();
   			}
   		}
   		if(game_sign_y[0] == game_sign_y[1]&&game_sign_y[2] <= 17)
   		{
   			if(game_body[game_sign_y[0] + 1][game_sign_x[0] - 1] != 2&&game_body[game_sign_y[1]][game_sign_x[1] - 2] != 2&&game_body[game_sign_y[2] + 1][game_sign_x[2] + 1] != 2)
   			{
       			num_csh_game();
   			    game_body[game_sign_y[0] + 1][game_sign_x[0] - 1] = 1;
   			    game_body[game_sign_y[1]][game_sign_x[1] - 2] = 1;
   			    game_body[game_sign_y[2] + 1][game_sign_x[2] + 1] = 1;
   			    game_body[game_sign_y[3]][game_sign_x[3]] = 1;
   			    infoTex.setText("游戏进行中!");
   			    repaint();
   			}
   		}
   	}
  }

   public void num_csh_game()//数组清零 用于将游戏数组 game_body 中的值重置
   {
   	for(int i = 0;i < 19;i++)//开始一个外层 for 循环,循环变量 i 从 0 到 18,用于遍历 game_body 数组的行(共 19 行)。
   	{
   		for(int j = 0;j < 10;j++)//遍历 game_body 数组的列(共 10 列)。
   		{
   			if(game_body[i][j] == 2)//如果 game_body 数组中位于 [i][j] 位置的元素等于 2,保持 game_body[i][j] 的值为 2。

   			{
   				game_body[i][j] = 2;
   			}
   			else
   			{//不等于 2,则将其重置为 0
   				game_body[i][j] = 0;
   			}
   		}
   	}
   }

 public void num_csh_restart()//重新开始时数组清零
   {
   	for(int i = 0;i < 19;i++)
   	{
   		for(int j = 0;j < 10;j++)
   		{
   			game_body[i][j] = 0;//清空所有位置
   		}
   	}
   }

public void keyTyped(KeyEvent e){}    
   
   public void keyPressed(KeyEvent e)
   {
   	if(e.getKeyCode() == KeyEvent.VK_DOWN&&startSign == 1)//处理下键
   	{
   		this.down();
   	}
   	if(e.getKeyCode() == KeyEvent.VK_LEFT&&startSign == 1)//处理左键
   	{
   		this.left();
   	}
   	if(e.getKeyCode() == KeyEvent.VK_RIGHT&&startSign == 1)//处理右键
   	{
   		this.right();
   	}
   	if(e.getKeyCode() == KeyEvent.VK_UP&&startSign == 1)//处理上键转换
   	{
   		this.change_body(blockNumber);
   	}
   	if(startSign == 0)
   	{
   		infoTex.setText("游戏未开始或已结束!");
   	}
   }

public void keyReleased(KeyEvent e){}
   
     public void paint(Graphics g)//接收一个 Graphics 对象 g 作为参数,用于绘制图形。
	{
		g.setColor(Color.black);//绘图颜色为黑色。
		g.fill3DRect(0,0,300,450,true);//绘制3D矩形,左上角坐标为 (0, 0),宽度为 300,高度为 450,并且绘制凸起效果的3D矩形背景。
		for(int i = 0;i < 19;i++)
		{
			for(int j = 0;j < 10;j++)
			{
				if(game_body[i][j] == 1)//若game_body [i][j] 等于 1,
				
				{
				    g.setColor(Color.blue);//将绘图颜色设置为蓝色。
		            g.fill3DRect(30*j,30*(i-4),30,30,true);//绘制一个填充的3D矩形,左上角坐标为 (30 * j, 30 * (i - 4)),宽度和高度均为 30,并且绘制凸起效果的3D矩形。
				}
				if(game_body[i][j] == 2)//等于 2。
				{
				    g.setColor(Color.magenta);//将绘图颜色设置为品红色
		            g.fill3DRect(30*j,30*(i-4),30,30,true);//绘制矩形
				}
			}
		}	
	}

	public void left()//向左移动
	{
		int sign = 0;//标记是否可以向左移动
		dingwei();//更新或获取当前方块的位置信息。
		for(int k = 0;k < 4;k++)//遍历当前方块的四个方格
		{
			if(game_sign_x[k] == 0||game_body[game_sign_y[k]][game_sign_x[k] - 1] == 2)
			{
				sign = 1;//检查当前方块的每个方格是否位于最左边的列(game_sign_x[k] == 0)。
						//或者检查当前方格左边的格子是否已经被占用(game_body[game_sign_y[k]][game_sign_x[k] - 1] == 2)。
						//如果上述任一条件为真,将 sign 设置为 1,表示不能向左移动。
			}
		}
		if(sign == 0&&downSign == false) 
		{//检查 sign 是否仍然为 0(表示可以向左移动),并且 downSign 是否为 false(表示当前方块还未落下)。
			num_csh_game();//重置游戏数组 game_body,但保留值为 2 的元素(已固定的方块)。
			for(int k = 0;k < 4;k++)
		    {//将当前方块的每个方格在游戏数组中向左移动一格,即将当前位置左边的格子设置为 1。
		    	game_body[game_sign_y[k]][game_sign_x[k] - 1] = 1;
		    }
		    infoTex.setText("向左移动!");
		    repaint();
		}
	}
	
	public void right()//向右移动
	{
		int sign = 0;
		dingwei();
		for(int k = 0;k < 4;k++)
		{
			if(game_sign_x[k] == 9||game_body[game_sign_y[k]][game_sign_x[k] + 1] == 2)
			{
				sign = 1;
			}
		}
		if(sign == 0&&downSign == false)
		{
			num_csh_game();
			for(int k = 0;k < 4;k++)
		    {
		    	game_body[game_sign_y[k]][game_sign_x[k] + 1] = 1;
		    }
		    infoTex.setText("向右移动!");
		    repaint();
		}
	}
	
	public void down()//下落
	{
		int sign = 0;
		dingwei();
		for(int k = 0;k < 4;k++)
		{
			if(game_sign_y[k] == 18||game_body[game_sign_y[k] + 1][game_sign_x[k]] == 2)
			{
				sign = 1;
				downSign = true;
				changeColor();
				cancelDW();
				getScore();
				if(game_over() == false)
				{
				    rand_block();
				    repaint();
				}
			}
		}
		if(sign == 0)
		{
			num_csh_game();
		    for(int k = 0;k < 4;k++)
		    {
		        game_body[game_sign_y[k] + 1][game_sign_x[k]] = 1;
		    }
		    infoTex.setText("游戏进行中!");
		    repaint();
		}
	}
	

	public boolean game_over()//判断游戏是否结束
	{
		int sign=0;//标记游戏是否结束
		for(int i = 0;i < 10;i++)//用于检测是否有方块到达顶部
		{
			if(game_body[4][i] == 2)
			{
				sign = 1;
			}
		}
		if(sign == 1)
		{
			infoTex.setText("游戏结束!");
			changeColor();//用于改变界面的颜色以表示游戏结束(
			repaint();//重绘组件以显示游戏结束的状态。
			startSign = 0;//startSign 设置为 0,表示游戏停止
			timer.suspend();
			return true;//。
		}
		else
		return false;//没有结束。
	}

public void getScore()//满行消除方法
	{
		for(int i = 0;i < 19;i++)
		{
			int sign = 0;//记录当前行被填满的方块数量。
			for(int j = 0;j < 10;j++)
			{
				if(game_body[i][j] == 2)
				{//如果当前格子是否被固定方块占据,将 sign 增加 1。
					sign++;
				}
			}
			if(sign == 10) //是否当前行的所有格子都被填满)
			{
				gameScore += 100;//gameScore 增加 100。
				scoreTex.setText(gameScore+"");
				infoTex.setText("恭喜得分!");
				for(int j = i;j >= 1;j--)
				{
					for(int k = 0;k < 10;k++)
				    {
					    game_body[j][k] = game_body[j - 1][k];
					    //将上面一行的内容复制到当前行,以清除当前行并将上面的行向下移动。
				    }
				}
			}
		}
	}

public void changeColor()//给已经落下的块换色
	{
		downSign = false;// downSign 变量设置为 false,表示当前方块不再下落。
		for(int k = 0;k < 4;k++)
		{
		    game_body[game_sign_y[k]][game_sign_x[k]] = 2;
		    //将当前方块的每个方格在 game_body 数组中的值设置为 2,表示方块已经固定
		}
	}

public void dingwei()//确定其位置
	{
		int k = 0;//记录当前方块的格子数目。
		cancelDW();//将定位数组初始化。
		for(int i = 0;i < 19;i++)
		{
			for(int j = 0;j < 10;j++)
			{
				if(game_body[i][j] == 1)
				{//如果当前格子属于当前活动方块,将当前格子的列索引 j 赋值给 game_sign_x[k],行索引 i 赋值给 game_sign_y[k]。将 k 增加 1,记录下一个方块的位置。
					game_sign_x[k] = j;
					game_sign_y[k] = i;
					k++;
				}
			}
		}
	}

public void cancelDW()//将定位数组初始化
	{
		for(int k = 0;k < 4;k++)//遍历定位数组的所有元素
		{
			game_sign_x[k] = 0;
			game_sign_y[k] = 0;
		}
	}
	
	public void block1()//长条
	{
		game_body[0][4] = 1;
		game_body[1][4] = 1;
		game_body[2][4] = 1;
		game_body[3][4] = 1;
	}
	
	public void block2()//正方形
	{
		game_body[3][4] = 1;
		game_body[2][4] = 1;
		game_body[3][5] = 1;
		game_body[2][5] = 1;
	}
	public void block3()//3加1(下)
	{
		game_body[1][4] = 1;
		game_body[2][4] = 1;
		game_body[3][4] = 1;
		game_body[3][5] = 1;
	}
	public void block4()//3加1(中)
	{
		game_body[1][4] = 1;
		game_body[2][4] = 1;
		game_body[3][4] = 1;
		game_body[2][5] = 1;
	}
	public void block5()//3加1(上)
	{
		game_body[1][4] = 1;
		game_body[2][4] = 1;
	    game_body[3][4] = 1;
		game_body[1][5] = 1;
	}
	public void block6()//转折1
	{
		game_body[1][5] = 1;
		game_body[2][5] = 1;
		game_body[2][4] = 1;
		game_body[3][4] = 1;
	}
	public void block7()//转折2
	{
		game_body[1][4] = 1;
		game_body[2][4] = 1;
		game_body[2][5] = 1;
		game_body[3][5] = 1;
	}
}

}

class MyTimer extends Thread
{
	Block myBlock; //声明一个 Block 类型的成员变量,引用游戏中的方块对象
   public MyTimer(Block myBlock)//构造方法
   {
   	this.myBlock = myBlock;
   }
   public void run()//线程执行的入口点,重写了 Thread 类的 run 方法。
   {
       while(myBlock.startSign == 1)//只要 myBlock.startSign 等于 1,循环将继续执行。startSign 是一个标志位,表示游戏是否正在进行。
       {
       	try{
       	    sleep((10-myBlock.speedMark + 1)*100); //使当前线程休眠一段时间,休眠时间由 (10 - myBlock.speedMark + 1) * 100 计算得出,单位是毫秒。
       	    myBlock.down();//使方块向下移动一格
           }
           catch(InterruptedException e){}// 异常,线程在休眠期间被中断。
       } 
  }
} 

  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值