Java小白思路写出俄罗斯方块小游戏(完整代码供大家白嫖)

先看看成品的效果
在这里插入图片描述

以下是完整代码

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Random;
import java.util.ArrayList;
import java.util.Collections;


public class Tetris
{
	//主窗口
	private JFrame mainWin = new JFrame("俄罗斯方块");
	
	//菜单
	private JMenuBar menubar = new JMenuBar();
	//1
	private JMenu control = new JMenu("控制");
	private JMenuItem start = new JMenuItem("开始游戏");
	private JMenuItem parse = new JMenuItem("暂停");
	private JMenuItem end = new JMenuItem("结束游戏");
	//2
	private JMenu help = new JMenu("帮助");
	private JMenuItem helpshow = new JMenuItem("帮助说明");
	

	//菜单事件监听器
	private MenuActionListener menulistener = new MenuActionListener();
	
	//设置一个数组用来存储是否已经被填充了。
	private int[][] store = new int[27][20];
	/*
	10和20根据窗体大小调整
	根据实际情况,宽是400,高是600,每个方块边长20
	所以横向可以放20个,纵向可以放30个
	*/
	
	//左边的游戏界面
	private GamePanel gamePanel =new GamePanel();

	//现在正在掉落的方块
	AllShapes falling = new AllShapes();

	//键盘事件
	MyKeyListener myKeyListener = new MyKeyListener();
	
	//定时器
	private Timer timer;
	private TimerTask task;

	//随机位置
	Random rand = new Random();
	int nextshape = 0;
	int nowshape = 0;

	//记录得分
	int score = 0;

	//显示得分和下一个图形的JPanel
	ShowNextPanel showNextPanel = new ShowNextPanel();
	
	//防止一开始有一个小方块
	boolean newgame = false;

	public Tetris()
	{
		//初始化一下现在的和下一个形状
		nowshape = rand.nextInt(7);
		nextshape = rand.nextInt(7);
	}
	
	
	
	public void init()
	{
		
		JSplitPane splitPane = new JSplitPane();
		splitPane.setDividerLocation(405);
		splitPane.disable();
		mainWin.add(splitPane);
	
		
		splitPane.setLeftComponent(gamePanel);

		JSplitPane leftsplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
		leftsplitPane.setTopComponent(showNextPanel);


		RightLowPanel rightlowpane = new RightLowPanel();
		Button startBn = new Button("开始");
		startBn.addActionListener(evt -> {
			if( !newgame)
			{
				TimerModeInit();
				newgame = true;
			}
		});
		rightlowpane.add(startBn);
		leftsplitPane.setBottomComponent(rightlowpane);
		leftsplitPane.setDividerLocation(200);
		leftsplitPane.disable();
		splitPane.setRightComponent(leftsplitPane);
		
		//设置菜单按钮
		mainWin.setJMenuBar(menubar);
		//1
		menubar.add(control);
		control.add(start);
		control.add(parse);
		control.add(end);
		//2
		menubar.add(help);
		help.add(helpshow);
		
		
		//设置菜单的监听事件
		start.addActionListener(menulistener);
		parse.addActionListener(menulistener);
		end.addActionListener(menulistener);

		
	
				
		//System.out.println("数组内的默认值"+store[0][0]);
		
		mainWin.addKeyListener(myKeyListener);

		//设置主界面
		mainWin.setSize(600,603);
		mainWin.setLocationRelativeTo(null);//居中
		//mainWin.pack();
		mainWin.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		mainWin.setVisible(true);
		mainWin.setResizable(false);//设置不准改变窗体大小
		
		
		
		
	}
	public void TimerModeInit()
	{
		
		timer = new Timer();
		task = new TimerTask()
		{
			@Override
			public void run()
			{
				//现在的图形
				int[][] data = falling.getdata(nowshape);
				boolean yes = falling.checkyes(data);//如果没有一个的底下为1的话就可以加1,
				
				if((falling.y < 25) && yes)
				{
					falling.y += 1;
					gamePanel.repaint();
					showNextPanel.repaint();
				}
				else
				{
					
					falling.storeshape(data);
					falling.resetxy();
					nowshape = nextshape;
					nextshape = rand.nextInt(7);
					showNextPanel.repaint();
					falling.resetrotate();
				}

				//每次循环检查
				int count = 0;
				for( int i = store.length-1; i>=0;i--)
				{

					
					
					

					boolean clean = true;
					for( int j = 0 ; j<store[i].length; j++)
					{
						if( store[i][j]== 0)
						{
							clean = false;
						}
					}
					if( clean)
					{

						
						for( int p = i; p>0; p--)
						{
							store[p] = store[p-1];
						}
						store[0] = new int[20];
						score += 20;
						
					}
					//经过前面的清理之后,如果还是有20个的行有黑格子的话,就结束游戏
					int hangcount = 0;
					for( int j= 0 ;j< store[i].length; j++)
						if( store[i][j] == 1)
							hangcount ++;
					if( hangcount > 0)
						count++;
				}
				if(count >= 27)
				{
					System.out.println("游戏结束");
					
					cancel();
					
				}


			}
		};
		timer.schedule(task,0,1000);
		
	}
							
	public static void main(String[] args)
	{
		new Tetris().init();
	}
	class GamePanel extends JPanel
	{
	
		@Override
		public void paint(Graphics g)
		{

		
			/*
			//模拟数据
			store[0][18] = 2;
			store[1][18] = 1;	
			store[1][19] = 2;
			store[1][17] = 2;
			*/


			//白色背景
			g.setColor(new Color(255,255,255));
			g.fillRect(0,0,400,600);
		
			//根据数组内容绘制
			
			for(int i = 0 ; i < store[0].length; i++)
			{
				for( int j = 0 ; j< 27; j++)
				{
					//遍历数组,只要不为0,就绘制出来
					if( store[j][i] != 0)
					{
						g.setColor(new Color(150,150,150));
						g.fillRect(i*20,j*20,18,18);
					}
					else//不然的话,就绘制背景网格
					{
						int colorparam = 240;
						g.setColor(new Color(colorparam,colorparam,colorparam));
						g.fillRect(i*20, j*20, 18,18);
					}				


				}
		
			}	

			//画一个方块看看
			//g.setColor(new Color(150,150,150));
			//g.fillRect(100,100,20,20);

			
			
			if(newgame == true)
			{
				g.setColor(new Color(150,150,150));
				int[][] data = falling.getdata(nowshape);
				for( int i = 0; i < data.length ; i++)
				{		
					g.fillRect((data[i][0]+falling.x)*20,(data[i][1]+falling.y)*20,18,18);	
				}
			}
			
		
			
		
		
		}

	}
	class ShowNextPanel extends JPanel
	{
		@Override
		public void paint(Graphics g)
		{
			//白色背景
			g.setColor(new Color(255,255,255));
			g.fillRect(0,0,200,200);
			
			/*
			//网格背景
			g.setColor(new Color(240,240,240));
			for(int i = 0;i< 10;i++)
			{
				for( int j = 2; j< 10;j ++)
				{
					
					g.fillRect(i*20,j*20,18,18);
				}
			}
			*/
						
			int[][] data = falling.getdata(nextshape);
			g.setColor(new Color(150,150,150));
			for( int i = 0 ; i < data.length; i++)
			{
				g.fillRect((data[i][0]+3)*20-5,(data[i][1]+4)*20+20,18,18);
			}
		

			//文字放最上面以防被覆盖
			g.setColor(new Color(0,0,0));
			g.drawString("得分:"+score,10,30);	
			
			g.drawString("下一个图形:", 10,50);
					
			
			
		}
	}
	class RightLowPanel extends JPanel
	{
		@Override
		public void paint(Graphics g)
		{
			g.setColor(new Color(255,255,255));
			g.fillRect(0,0,200,400);
		}
	}
		
	class MyKeyListener implements KeyListener
	{
		
		public void keyPressed(KeyEvent e)
		{
			int key = e.getKeyCode();
			
			int[][] data = falling.getdata(nowshape);
			switch(key)
			{
				case KeyEvent.VK_UP:
					if(falling.canrotate(data)  )//如果可以翻转的话
						falling.rotate(nowshape);
						
					
					break;
				case KeyEvent.VK_DOWN:
						
					if( falling.checkfall(data))
						falling.y += 1;
					break;
				case KeyEvent.VK_LEFT:
					if( falling.checksubsideyes(data))
					{
						falling.x -=1;
					
					}
						
					break;
				case KeyEvent.VK_RIGHT:
					if( falling.checkaddsideyes(data))
					{
						falling.x +=1;
					}
					break;
			}
			gamePanel.repaint();
		}
	
		public void keyReleased(KeyEvent e){}
		public void keyTyped(KeyEvent e){}
		
	}
	class MenuActionListener implements ActionListener
	{
		public void actionPerformed(ActionEvent e)
		{
			switch(e.getActionCommand())
			{
				case "开始游戏":
					System.out.println("开始游戏");
					nextshape = rand.nextInt(7);
					if( !newgame )
					{
						newgame = true;
						gamePanel.repaint();
						//定时线程
						//定时任务初始化
						TimerModeInit();
					}
					
					break;
				case "暂停":
					if( newgame)
					{
						System.out.println("暂停");
						timer.cancel();
						timer.purge();
						timer = null;
						newgame = false;
					}
					break;
				case "结束游戏":
					System.out.println("结束游戏");
					break;
			}
		}
	}
	
	class AllShapes
	{	
		Random rand = new Random();
	
		public int x = rand.nextInt(17)+1;
		public int y =0;

		private int[][] data1 = {{-1,0},{0,0},{1,0},{2,0}};// —
		private int[][] data2 = {{-1,0},{0,0},{1,0},{-1,1}}; // L 左边突出
		private int[][] data3 = {{-1,0},{0,0},{1,0},{1,1}}; // L 右边突出
		private int[][] data4 = {{0,0},{1,0},{0,1},{1,1}}; //田
		private int[][] data5 = {{-1,0},{0,0},{1,0},{0,1}}; // T
		private int[][] data6 = {{-1,0},{0,0},{0,1},{1,1}}; //Z 
		private int[][] data7 = {{0,0},{1,0},{-1,1},{0,1}}; //反Z 
		private ArrayList<int[][]> list = new ArrayList<>();
		public AllShapes(){
		
			Collections.addAll(list,data1,data2,data3,data4,data5,data6,data7);
		}
		public void resetxy()
		{
			x = rand.nextInt(17)+1;
			y = 0;
		}
		public void rotate(int nowshape)
		{
			for( int i = 0; i < list.get(nowshape).length; i ++)
			{
				int x = list.get(nowshape)[i][0];
				list.get(nowshape)[i][0] = -list.get(nowshape)[i][1];
				list.get(nowshape)[i][1] = x;
			}
			
		}
		public void resetrotate()
		{
			int[][] data1 = {{-1,0},{0,0},{1,0},{2,0}};// —
			int[][] data2 = {{-1,0},{0,0},{1,0},{-1,1}}; // L 左边突出
			int[][] data3 = {{-1,0},{0,0},{1,0},{1,1}}; // L 右边突出
			int[][] data4 = {{0,0},{1,0},{0,1},{1,1}}; //田
			int[][] data5 = {{-1,0},{0,0},{1,0},{0,1}}; // T
			int[][] data6 = {{-1,0},{0,0},{0,1},{1,1}}; //Z 
			int[][] data7 = {{0,0},{1,0},{-1,1},{0,1}}; //反Z 
			list.clear();
			Collections.addAll(list,data1,data2,data3,data4,data5,data6,data7);
		}
			
		public boolean canrotate(int[][] data)
		{
			for( int i = 0; i < data.length; i++)
			{
				int temy = data[i][0];
				int temx  = -data[i][1];
				
				if( temx+x > 19 || temx+x < 0 )
					return false;
				if( temy+y > 26 || temy+y < 0)
					return false;
				if( store[temy+y][temx+x] == 1 )
					return false;
			}
			
			return true;
		}
		public int[][] getdata(int i)
		{
			return list.get(i);
		}	
		
		public boolean checkyes(int[][] data)
		{
			boolean yes = true;
			
			for(int i = 0; i < data.length; i++)
			{
				if( data[i][1] + y+1 >26 || store[data[i][1]+y+1][data[i][0]+x] == 1)
				{
					yes = false;
				}
			}
				
			return yes;
		}
		public boolean checkfall(int[][] data)
		{
			
			for( int i = 0; i < data.length; i++)
			{
				if( data[i][1]+y+1 >= 27 || store[data[i][1]+y+1][data[i][0]+x] ==1)
					return false;
				
			}
			return true;
		}
		public boolean checkaddsideyes( int[][] data)
		{
			for( int i=0; i< data.length; i++)
			{
				if( data[i][0]+x+1 > 19 || store[data[i][1]+y][data[i][0]+x+1]==1)
					return false;
			}
			return true;
		}
		public boolean checksubsideyes(int[][] data)
		{
			
			for( int i = 0 ; i < data.length; i ++)
			{
				if( data[i][0] + x -1 < 0 || store[data[i][1]+y][data[i][0]+x-1] ==1)
					return false;
			}
			
			return true;
		}
				
		public void storeshape(int[][] data)
		{
			for( int i = 0; i < data.length; i++)
			{
				
				store[data[i][1]+y][data[i][0]+x] = 1;
			}
		}
	
		
	}
			
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

细水长流cpu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值