java俄罗斯方块详解

用 java 实现 俄罗斯方块 实现俄罗斯方块的 Java 代码如下: ``` import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Point; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java... 阅读详情

【Java】俄罗斯方块小游戏(附源码)_500行可运行小游戏代码-优快云博客icon-default.png?t=O83Ahttps://blog.youkuaiyun.com/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 类实现了 ActionListener 和 KeyListener 接口,意味着它将实现这些接口定义的方法,用于处理操作和键盘事件。

	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[] = {"start game","restart","decrease level","increase level","pause","exit"};
	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){}// 异常,线程在休眠期间被中断。
       } 
  }
} 

结果展示:

java实现俄罗斯方块游戏 看完美团、字节、腾讯这三家的面试问题,是不是感觉问的特别多,可能咱们又得开启面试造火箭、工作拧螺丝的模式去准备下一次的面试了。开篇有提及我可是足足背下了1000道题目,多少还是有点用的呢,我看了下,上面这些问题大部分都能从我背的题里找到的,所以今天给大家分享一下互联网工程师必备的面试1000题。注意不论是我说的互联网面试1000题,还是后面提及的算法与数据结构、设计模式以及更多的Java学习笔记等,皆可分享给各位朋友互联网工程师必备的面试1000题而且从上面三家来看,算法与数据结构是必备不可少的。 阅读详情

相关推荐

Java俄罗斯方块,老程序员花了一个周末,连接中学年代!

引言: 俄罗斯方块,相信很多80、90后的小伙伴都玩过,也是当年非常火的游戏,当年读中学的时候,有一个同学有这个游戏机,大家都很喜欢玩,这个游戏给当时的我们带来了很多欢乐,时光飞逝,感慨颇多! 人终归是要长大的,回忆再美好,日子也一去不复返了,以前我们只会玩游戏,心里想自己能做一个出来多牛逼啊,长大后,成为程序员的我们有能力自己写游戏玩,我想这就是成长吧! 玩过这个游戏机的小伙伴看到这个图,应该对这个机器多少有些感情,毕竟带给了我们很多的欢乐! 这次利用周末的时间,去写了一个俄罗斯方块Java版本,感觉碰

编程界明世隐的博客 45万+

Java实现俄罗斯方块

3.当区域中某一列横向格子全部由方块填满,则该列会消失并成为玩家的得分。同时删除的列数越多,得分指数上升。2.方块移到区域最下方或是着地到其他方块上无法移动时,就会固定在该处,而新的方块出现在区域上方开始落下。4.当固定的方块堆到区域最上方而无法消除层数时或者大于游戏区域时,则游戏结束。1.方块会从上方缓慢下落,玩家可以通过键盘上的上下左右键来控制方块。

luoyuyanfei的博客 4950

基于Java Swing的现代化俄罗斯方块游戏开发详解

清晰的包结构和职责分离使用MVC架构分离关注点遵循面向对象设计原则使用现代Java特性如枚举和lambda表达式注重代码可读性和可维护性。

2201_76125393的博客 133

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

大家好,我是百思不得小赵。 创作时间:2022 年 5 月 12 日 博客主页: 🔍点此进入博客主页 —— 新时代的农民工 🙊 —— 换一种思维逻辑去看待这个世界 👀 今天是加入优快云的第1167天。觉得有帮助麻烦👏点赞、🍀评论、❤️收藏 目录 一、游戏背景 二、功能实现 三、效果展示 四、总结 一、游戏背景 二、功能实现 三、效果展示 四、总结 Github链接地址:点击获取完整源代码,下载到本地即可运行 ...

我这么骄傲的一个人。 4万+

【2025小米秋招-8月23日-第一题(100分)- 静止俄罗斯方块】(题目+思路+Java&C++&Python解析+在线测试)

题目摘要: 给定一个初始高度非降的方块序列,处理m个从左侧下落的矩形方块。每个方块会停在对应宽度区间内的最高现有高度处,并抬高该区间的高度。要求输出每个方块下落后的底部高度。 关键点: 初始高度数组a非降序排列 每个方块下落时,其底部高度等于当前区间[1,w]的最高高度(max(a[w], 当前平台高度base)) 放置后将该区间统一抬高h个单位高度 使用变量base记录当前被抬高的平台高度 解法:维护一个base变量表示当前平台高度,对于每个方块,计算ans=max(a[w], base),输出后更新ba

m0_73659489的博客 155

Java实现俄罗斯方块游戏详解

本文还有配套的精品资源,点击获取 简介:编写游戏是学习新语言或技术的有趣实践,尤其适合初学者巩固基础和提高编程技能。本详解涉及一个用Java实现的俄罗斯方块游戏,其采用贴图方式展示方块,增强了视觉效果。通过Swing或JavaFX库创建GUI,游戏展现了生成、移动、旋转方块的核心机制,以及消除行的逻辑。代码展示了面向对象编程、图形界面设计和图像处理技术的综合应用。 1...

weixin_36122351的博客 1497

俄罗斯方块代码 java_俄罗斯方块java代码-java编写俄罗斯方块代码详解分享

俄罗斯方块——java源代码提供import java.awt.*; import java.awt.event.*; //俄罗斯方块类 public class ERS_Block extends Frame{ public static boolean isPlay=false; public .我写俄罗斯方块的时候,添加键盘监听,为什么总是监听不到,但是把frame。我的理解:你应该是在F...

weixin_42165508的博客 2018

Java实现俄罗斯方块游戏教程详解

htmltable {th, td {th {pre {简介:本项目为使用Java语言实现的经典俄罗斯方块游戏。通过深入分析源代码,开发者可以学习Java基础语法、面向对象编程、图形用户界面(GUI)设计、事件处理、游戏逻辑、计时器与多线程技术,以及数据结构和算法的应用。项目内容虽缺乏详细文档,但源代码本身提供了一个良好的实践平台,帮助开发者提升编程技能,并深入理解游戏开发流程。

weixin_28721743的博客 797

java俄罗斯方块说明书_俄罗斯方块java代码(java编写俄罗斯方块代码详解)

俄罗斯方块——java源代码提供import java.awt.*; import java.awt.event.*; //俄罗斯方块类 public class ERS_Block extends Frame{ public static boolean isPlay=false; public .我写俄罗斯方块的时候,添加键盘监听,为什么总是监听不到,但是把frame。我的理解:你应该是在Fr...

weixin_33214011的博客 962

Java编程实现俄罗斯方块项目详解

俄罗斯方块(Tetris)是一款经典的电子游戏,由俄罗斯程序员阿列克谢·帕基特诺夫于1984年开发。游戏的目标是在一个10x20的网格中,通过旋转和移动不断下落的方块(Tetriminoes),使得它们在底部拼成完整的水平线。每当完成一行,该行就会消失,玩家获得分数,同时上方的方块继续下落。游戏会随着方块下落速度的增加而变得更具挑战性,直到新方块无法进入网格,游戏结束。游戏的核心规则如下:方块由四个小方格组成,共有七种形状,每种形状都对应不同的几何图形。

weixin_35516624的博客 963

Java实现经典俄罗斯方块游戏完整项目详解

回头看,俄罗斯方块远不止“方块下落”那么简单。我们用类与对象建模实体,用封装保护数据完整性,用继承与多态实现行为统一接口,用设计模式提升架构质量,用线程安全机制保障运行稳定。这正是Java面向对象编程的魅力所在:把复杂的问题,分解成一个个小而美的零件,然后再组装成一台精密运转的机器⚙️。下次当你按下方向键时,不妨想想——那一瞬间,有多少对象在协同工作?又有多少设计原则在默默守护着这场数字舞蹈?

weixin_35749545的博客 735

java俄罗斯方块消除算法_Java实现俄罗斯方块源码下载-算法简单代码详解清楚

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;...

weixin_42128963的博客 363

Java编程实现俄罗斯方块游戏详解.zip

在Java中,事件监听模型主要包括以下几个组成部分:事件源:产生事件的对象,例如键盘按键。事件:描述了一个事件发生时的状态信息。事件监听器:一个接口或抽象类,其中包含了一系列的方法来响应特定类型的事件。事件处理程序:实现了事件监听器接口的具体类,并定义了事件发生时的响应行为。当用户按下键盘上的按键时,事件源(键盘)会生成一个事件对象,并将该事件传递给已注册的事件监听器,监听器会调用对应的方法来处理这个事件。在本章节中,我们深入了解了键盘事件监听机制及其处理流程。

weixin_32252929的博客 965

java俄罗斯方块七中图形类_shell脚本俄罗斯方块--代码真正详解

无意中看到代码,想仔细了解下源码实现,结果网上搜索都是抄袭的一个版本,有的就写了个开头的分析,没有具体代码分析。所以个人就花了点时间,详细分析了一下代码,在这里分享给大家。排版不会弄,将就看吧,转载请注明出处,谢谢#!/bin/bash# Tetris Game# 10.21.2003 xhchen#APP declarationAPP_NAME="${0##*[\\/]}"APP_VERSION...

weixin_31725659的博客 429

Java经典游戏开发实战:俄罗斯方块详解(含完整源码)

游戏的核心视觉呈现依赖于一个自定义的画布组件,通常通过继承JPanel实现。此类组件不仅承担绘图职责,还需集成游戏状态更新与用户交互响应。创建自定义画布的关键在于重写方法,并结合repaint()触发重绘。以下是一个简化版的GamePanel类定义:// 设置首选大小// 黑色背景// 可聚焦以接收键盘事件// 注册键盘监听@Override});// 启动游戏循环// 推进游戏逻辑一步repaint();// 请求重绘});@Override。

weixin_42186387的博客 466

Java课程设计实战:俄罗斯方块游戏完整实现与详解

传统实现常将方块坐标存储为int[][]或,但这导致旋转后需重新计算全部坐标,且无法保证不同旋转态下的坐标集等价性。我们采用“锚点+偏移向量”双层建模法:每个 Tetromino 持有一个不可变的数组,表示四个方格相对于质心(center of mass)的整数偏移量;同时维护一个表示当前世界坐标系下的质心位置。该设计带来三大优势:(1)旋转仅需对offsets数组应用线性变换,anchor保持不变;(2)碰撞检测时,只需将anchor加上各offset。

weixin_36474966的博客 298

59分钟完成编写,成功通过大厂offer,JAVA俄罗斯方块项目

本章课程讲解了一个俄罗斯方块游戏的详细编写思路和流程,即使你刚学java 没多久,只要你简单掌握了该游戏所需要的iavase的基础知识,便可以跟随该教程视频完成属于你自己的俄罗斯方块游戏!同时,还可以加深和巩固你对 java 基础知识的理解。 来,来,来!!! 本课程讲解了一个"俄罗斯方块小游戏",面向刚入门或者有一定java基础的人群。 建立如下类: Cell类:代表最小的方格单位,构成7种图形的最基本图形。 含有row(行号),col(列号),image(对应的图片...

Double6688的博客 435

Java写的带图片纹理的俄罗斯方块小游戏,含完整资源和可运行jar

用Java Swing开发的俄罗斯方块小游戏,所有方块和界面元素都通过JPG图片贴图实现,不是纯色块绘制。包含beijing.jpg(游戏背景)、face.jpg(可能为标题或按钮图)、c.jpg、d.jpg、e.jpg(分别对应不同形状方块的外观贴图),资源缺失会导致对应图形显示为空白。主程序MyFirstGame.java已编译成俄罗斯方块.jar,双击即可运行,无需额外配置。项目结构清晰,含源码文件、图片资源和基础目录,适合刚学完Java基础、想动手实践图形加载与事件响应的新手——能直接看到图片如何绑

rock5的博客 217
上一篇: Cisco Packet Tracer 里的路由器怎么在cli清空配置
下一篇: 已经安装visual studio再安装unity
fqq3
博客等级 码龄4年 114粉丝 45原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值