亲宝软件园·资讯

展开

Java俄罗斯方块

错过了时间 人气:0

俄罗斯方块小游戏

简单的实现俄罗斯方块,只有一个主代码,很好理解的,有暂停/继续、重新开始、结束游戏的简单功能。这里就不多说实现的原理了,可以在网上进行相关的查询。这里就直接给出了源代码,这个也是我参考网上的,自己进行了相关的更改,增加了一些功能。

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import javax.imageio.*;
import javax.swing.*;
import javax.swing.Timer;


public class MyGame extends JFrame {

	   public MyGame(){
		GameBody gamebody=new GameBody();
		gamebody.setBounds(5,10,500,600);  //
	    gamebody.setOpaque(false);
		gamebody.setLayout(null);
		addKeyListener(gamebody);
		add(gamebody);
		

		int w=Toolkit.getDefaultToolkit().getScreenSize().width;
        int h=Toolkit.getDefaultToolkit().getScreenSize().height;
		JLabel image=new JLabel(new ImageIcon("13.jpg"));
		image.setBounds(0,0,500,600);
	    getLayeredPane().setLayout(null);
		getLayeredPane().add(image,new Integer(Integer.MIN_VALUE));
		((JPanel)getContentPane()).setOpaque(false);

		final JButton login=new JButton(new ImageIcon("login4.PNG"));
		login.setContentAreaFilled(false);
		login.setMargin(new Insets(0,0,0,0));
		login.setBorderPainted(false);
		login.setBounds(340,320,120,26);
		gamebody.add(login);

		login.addActionListener(new ActionListener(){
		   public void actionPerformed(ActionEvent e) {    //登录的按钮
				if(e.getSource()==login){
				requestFocus(true);    //获得焦点,不用失去焦点
				gamebody.resetMap();   //重置地图
				gamebody.drawWall();   //冲重新绘制边界墙体
				gamebody.createshape();   //重新产生新的地图
				gamebody.setStart(false);  //唤醒定时下落的线程
			    gamebody.score=0;       //将分数置为零
			    repaint();
				}
		   }
		});

		final JButton pauselogin=new JButton(new ImageIcon("login6.PNG"));
		pauselogin.setContentAreaFilled(false);
		pauselogin.setMargin(new Insets(0,0,0,0));
		pauselogin.setBorderPainted(false);
		pauselogin.setBounds(340,370,120,26);
		gamebody.add(pauselogin);

		pauselogin.addMouseListener(new MouseListener(){   //暂停的按钮
		  /* public void actionPerformed(ActionEvent e) {   //用事件监听,没用实现再次按暂停键后继续游戏
				//while(true){
				if (e.getSource()==pauselogin)
				{
					gamebody.setStart(true);
					requestFocus(true);

				}if(e.getSource()==login){
					new GameBody.setStart(false);
					requestFocus(true);
				}
				//}
		   }*/

		 //鼠标点击事件,可以分别判断不同的事件,做出不同的反应 
		public void mouseClicked(MouseEvent e){
			if(e.getButton()==e.BUTTON1 ){     //单击左键暂停
				gamebody.setStart(true);   //将自动下落线程关闭
				//requestFocus(true);    //同时整个JFrame失去焦点,无法操作,但可以点击按钮
			}
        else if(e.getButton()==e.BUTTON3 ){   //右击暂停,继续游戏
                gamebody.setStart(false);   //唤醒自动下落线程
				requestFocus(true);
			}
        if(e.getClickCount()==2){     //左键双击,也可以继续游戏
                gamebody.setStart(false);
			    requestFocus(true);
			}
		}
		public void mouseEntered(MouseEvent e){}
		public void mouseExited(MouseEvent e){}
		public void mousePressed(MouseEvent e){}
		public void mouseReleased(MouseEvent e){}
		   
		});

		final JButton overlogin=new JButton(new ImageIcon("login5.PNG"));   //退出的按钮
		overlogin.setMargin(new Insets(0,0,0,0));
		overlogin.setContentAreaFilled(false);
		overlogin.setBounds(340,420,120,26);
		overlogin.setBorderPainted(false);
		add(overlogin);

		overlogin.addActionListener(new ActionListener(){
		   public void actionPerformed(ActionEvent e) {
		      System.exit(1);
		   }
		});
        
		setTitle("俄罗斯方块 V.1.0");
		setResizable(false);
		setFocusable(true);
		setBounds((w-500)/2,(h-600)/2,500,600);
		setLayout(null);

		setVisible(true);
		setDefaultCloseOperation(3);
	}
	public static void main(String[] args) {
		new MyGame();
	}

	//创建需要定义的局部变量和游戏类
	 class GameBody extends JPanel implements KeyListener{
		private int shapeType=-1;  //定义方块的类型  定义的为7中
		private int shapeState=-1; //定义方块为何种状态,每种都有四种状态
		private int nextshapeType=-1;  //定义下一块产生的类型
		private int nextshapeState=-1;  //定义下一块的方块的状态
		private final int CELL=25;   //定义方格的大小
		private int score=0;    //定义显示的成绩
		private int left;       //定义初始图形与两边的墙的距离
		private int top;        //定义初始图形与上下墙的距离
		private int i=0;        //表示列
		private int j=0;        //表示行
		public int flag=0;
		public  volatile boolean start=false;  //暂停的判断条件,为轻量锁,保持同步的
		//public boolean start=false;
		//Timer t;
		Random randomcolor=new Random();
		Random random=new Random();

		//定义地图的大小,创建二位的数组
		int[][] map=new int[13][23];

		//初始化地图
		public void resetMap(){
		  for(i=0;i<12;i++){
		     for(j=0;j<22;j++){  //遍历的范围不能小
			  map[i][j]=0;
			}
		  }
		}

		//画围墙的方法
		public void drawWall(){
		  for(j=0;j<22;j++)  //0到21行
		  {
			map[0][j]=2;
			map[11][j]=2;    //第0行和第11行为墙
		  }
		  for(i=0;i<12;i++){  //0到11列
		    map[i][21]=2;    //第21行划墙
		  }
		}


		//定义随机的图形种类
		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 } },
	          // s
	          {		{ 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 } },
	          // o
	          {		{ 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 } },
	          // t
	          {		{ 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 createshape(){
			if(shapeType==-1&&shapeState==-1){
			  shapeType = random.nextInt(shapes.length);
			  shapeState = random.nextInt(shapes[0].length);
			}else{
			  shapeType=nextshapeType;
			  shapeState=nextshapeState;
			}
			  nextshapeType = random.nextInt(shapes.length);
              nextshapeState = random.nextInt(shapes[0].length);
			//shapeType=(int)(Math.random()*1000)%7;   //在7中类型中随机选取
			//shapeState=(int)(Math.random()*1000)%4;  //在四种状态中随机选取 
			left=4; top=0;  //图形产生的初始位置为(4,0)\
			if(gameOver(left,top)==1){ 
			//判断游戏
			  resetMap();
			  drawWall();
			  score=0;
	        JOptionPane.showMessageDialog(null, "GAME OVER");
			}
		}

		//遍历[4][4]数组产生的方块并判断状态
		public int judgeState(int left,int top,int shapeType,int shapeState){
			for(int a=0;a<4;a++){
			  for(int b=0;b<4;b++){
			    if(((shapes[shapeType][shapeState][a*4+b]==1 &&   //遍历数组中为1的个数,即判断是否有图形
					map[left+b+1][top+a]==1))||                   //判断地图中是否还有障碍物
					((shapes[shapeType][shapeState][a*4+b]==1 &&   //遍历数组中为1的个数,即判断是否有图形
					map[left+b+1][top+a]==2))){                   //判断是否撞墙
					      return 0;    //表明无法不能正常运行
					}                 
			  }
			}
		    return 1;
		}


		//创建键盘事件监听
		public void keyPressed(KeyEvent e){
		//if (start){
		  switch(e.getKeyCode()){
			case KeyEvent.VK_LEFT:
			leftMove();//调用左移的方法
			repaint();
			break;
			case KeyEvent.VK_RIGHT:
			rightMove();//调用右移的方法
			repaint();
			break;
			case KeyEvent.VK_DOWN:
			downMove();//调用左移的方法
			repaint();
			break;
			case KeyEvent.VK_UP:
			turnShape();//调用变形的方法
			repaint();
			break;
		  }
		// }
		}
	  public void keyReleased(KeyEvent e) {
	  }
	  public void keyTyped(KeyEvent e) {
	  }



	  //创建左移的方法
		public void leftMove(){
			if(judgeState(left-1,top,shapeType,shapeState)==1){
				left-=1;
				}
		}
		//创建右移的方法
	  public void rightMove(){
		    if(judgeState(left+1,top,shapeType,shapeState)==1){
				left+=1;
				};
			
		}
		//创建下移的方法
		public void downMove(){
		    if(judgeState(left,top+1,shapeType,shapeState)==1){  //判断有图形
				top+=1;
				deleteLine();   //判断下移后是否有满行
				}
			if(judgeState(left,top+1,shapeType,shapeState)==0){   //判断没有图形
			    
				addshape(left,top,shapeType,shapeState);
				createshape();
				deleteLine();
			}
		}


		//创建旋转变形的方法
		public void turnShape(){
		  int tempshape=shapeState;
		  shapeState=(shapeState+1)%4; //在四中的状态中选取
		  if(judgeState(left,top,shapeType,shapeState)==1){
			  
		  }
		  if(judgeState(left,top,shapeType,shapeState)==0){
		        shapeState=tempshape;   //没有图形,不能进行旋转,还原原来状态
		  }
				repaint();
		}

		//绘图方法
		public void paintComponent(Graphics g){
		   super.paintComponent(g);
		   int t=randomcolor.nextInt(5);
		   int count=randomcolor.nextInt(5);
		   Color[] color=new Color[]{Color.pink,Color.green,Color.red,Color.yellow,Color.blue};
		  /* Image image = null;
		try {
			image = ImageIO.read(new File("1.jpg"));
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
			g.drawImage(image, 0, 0,this);
		}*/
		   
		  //绘制围墙
		   for(j=0;j<22;j++){
		     for(i=0;i<12;i++){
			   if(map[i][j]==2){//判断是否为墙并绘制
				 g.setColor(Color.blue);
			     g.fill3DRect(i*CELL,j*CELL,CELL,CELL,true);
			   }
               if(map[i][j]==0){//判断是否为墙并绘制
				 g.setColor(Color.red);
			     g.drawRoundRect(i*CELL,j*CELL,CELL,CELL,6,6);}
			 }
		   }
		   
		   //绘制正在下落的图形
		   for(int k=0;k<16;k++){
		     if(shapes[shapeType][shapeState][k]==1){
			   g.setColor(Color.red);
			   g.fill3DRect((left+k%4+1)*CELL,(top+k/4)*CELL,CELL,CELL,true);  //left\top为左上角的坐标
			 }
		   }

		   //绘制落下的图形
		   for(j=0;j<22;j++){  
		     for(i=0;i<12;i++){
			   if(map[i][j]==1){
				 g.setColor(Color.green);
			     g.fill3DRect(i*CELL,j*CELL,CELL,CELL,true);
			   }
			 }
		   }   

           //显示右边预览图形
		   for(int i = 0; i < 4; i++) {
			 for(int j = 0; j < 4; j++){
				if(shapes[nextshapeType][nextshapeState][i*4+j] == 1) {
					g.setColor(Color.red);
					g.fill3DRect(375+(j*(CELL-10)),190+(i*(CELL-10)), CELL-10, CELL-10,true);
					}
				 }
			}
			//添加右边预览图形方格
			for(int i = 0; i < 5; i++) {
			 for(int j = 0; j < 5; j++){
					g.setColor(Color.blue);
					g.drawRoundRect(360+(j*(CELL-10)),175+(i*(CELL-10)),CELL-10, CELL-10,3,3);
				 }
			}
		   g.setFont(new Font("楷书",Font.BOLD,20));
		   g.setColor(Color.BLUE);
		   g.drawString("游戏分数:", 310, 70);
		   g.setColor(Color.RED);
		   g.drawString(score+"  ", 420, 70);
		   g.setColor(Color.BLUE);
		   g.drawString("  分", 450, 70);

		}


	//创建添加新图形到地图的方法、
		public void addshape(int left,int top,int shapeType,int shapeState){
	     int temp=0;
		   for(int a=0;a<4;a++){
		     for(int b=0;b<4;b++){   //对存储方块队的[4][4]数组遍历
				if(map[left+b+1][top+a]==0){ //表明[4][4]数组没有方块
					
				    map[left+b+1][top+a]=shapes[shapeType][shapeState][temp];
				}
				temp++;
			 }	 
		   }
		}


	  

		//创建消行的方法,即将满行以上的部分整体下移
	  public void deleteLine(){
		  int tempscore=0;      //定义满行的列个数满足1
		  for(int a=0;a<22;a++){   //对地图进行遍历
		    for(int b=0;b<12;b++){
			  if(map[b][a]==1){    //表示找到满行
			     tempscore++;     // 记录一行有多少个1
				 if(tempscore==10){
				   score+=10;
				 for(int k=a;k>0;k--){     //从满行开始回历
				   for(int c=1;c<12;c++){
				      map[c][k]=map[c][k-1];  //将图形整体下移一行
				   }
				 }
				 }
			}
		  }
			tempscore=0;
		  }
		}



	  //判断游戏结束,1、判断新块的状态是否不存在,即judgeState()==0
		//2、判断初始产生的位置是否一直为1;
		public int gameOver(int left,int top){
		  if(judgeState(left,top,shapeType,shapeState)==0){
		     return 1;
		  }
		  return 0;
		}

		//创建构造方法
		public GameBody(){
			resetMap();
			drawWall();
			createshape();
			//Timer timer=new Timer(1000,new TimeListener());
			Thread timer=new Thread(new	TimeListener());
			timer.start();
		}

		public void setStart(boolean start){   //改变start值的方法
			this.start=start;
		}

		//创建定时下落的监听器
		class TimeListener implements Runnable{
		  public void run(){
			  while(true){
				if(!start){
			  try{
				repaint();
				if(judgeState(left,top+1,shapeType,shapeState)==1){
				      top+=1;
				      deleteLine();}
				if(judgeState(left,top+1,shapeType,shapeState)==0){
					if(flag==1){
					  addshape(left,top,shapeType,shapeState);
					  deleteLine();
					  createshape();
					  flag=0;
					}
					flag=1;
				}
				Thread.sleep(800);
		  }catch(Exception e){
			e.getMessage();
			   }
			 } 
			}
		  }
	    }	
   } 	 
} //外层

下面是游戏演示的一些界面效果图:

这里说一下,我是把图片和源代码直接放在了一个文件夹下,对于初学者很好理解,这也是很好的练手项目。图片什么的大家可以在网上直接找一个,然后重命名一下就可了。

加载全部内容

相关教程
猜你喜欢
用户评论