java代码实现俄罗斯方块

本文实例为大家分享了java实现俄罗斯方块的具体代码,供大家参考,具体内容如下

俄罗斯方块设计思想

俄罗斯方块都从小玩到大吧,什么规则大家都知道了吧,以前感觉那玩意贼好玩,但是就是老赢不了,现在学会了自己写一个天天练!

键盘操作:

左键:左移; 右键:右移;
上键:变换造型 下键:加速下掉(没毛病吧,没有继续整)

任意一行的方块满格,这一行就消除,消除一行方块得10分,目前小主我还没有设置关卡,各位喜欢的宝宝们可以自己设置关卡哦;

那么那些方块的造型到底从哪里来的呢,那就是我们自己设计的,常见的几种造型就是:I型,T型,L型,田字格型等等吧,自己个加呗!
那么到底咋整的咧?其实啊就是一个4*4的数组,当然了你开心设计n*n也可以,你牛皮你说了算!
那么下面举了一个例子,用来告诉你们为啥你们看见的造型可以变换的原因就是这样提前设计好,0为空,1为填充格,这样你就可以在你的游戏里面凹造型了!

算了:直接放图先看代码运行结果吧:

喜欢吗?喜欢就直接做吧,可能代码写的不够好,请各位大神多多包涵,我回头也会多总结,会不断更新代码的;

GamePanel类:游戏界面类,整个方块掉落和显示,游戏的逻辑斯洛都在这个类里面实现;

package tetris;

import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Timer;

public class GamePanel extends JPanel implements KeyListener{
 private int mapRow = 21;
 private int mapCol = 12;
 private int mapGame[][] = new int[mapRow][mapCol];//开辟一个二维数组空间,用来存放我们的地图信息

 private Timer timer;
 private int score = 0;//记录成绩
 Random random = new Random();
 private int curShapeType = -1;
 private int curShapeState = -1;//设置当前的形状类型和当前的形状状态
 private int nextShapeType = -1;
 private int nextShapeState = -1;//设置下一次出现的方块组的类型和状态

 private int posx = 0;
 private int posy = 0;

 private final int shapes[][][] = new int[][][]{
  //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}
  },
  //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,1,1,0, 0,0,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,0,0,0, 1,1,1,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},
  {0,0,1,0, 1,1,1,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},
  {1,1,1,0, 1,0,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},
  {1,1,0,0, 1,1,0,0, 0,0,0,0, 0,0,0,0}
  }
 };
 private int rowRect = 4;
 private int colRect = 4;//这里我们把存储的图像看成是一个4*4的二维数组,虽然在上面我们采用一维数组来存储,但实际还是要看成二维数组来实现
 private int RectWidth = 10;

 public GamePanel()//构造函数----创建好地图
 {
 CreateRect();
 initMap();//初始化这个地图
 SetWall();//设置墙
// CreateRect();
 timer = new Timer(500,new TimerListener());
 timer.start();
 }

 class TimerListener implements ActionListener{
 public void actionPerformed(ActionEvent e)
 {
  MoveDown();
 }
 }

 public void SetWall()//第0列和第11列都是墙,第20行也是墙
 {
 for(int i = 0; i < mapRow; i++)//先画列
 {
  mapGame[i][0] = 2;
  mapGame[i][11] = 2;
 }
 for(int j = 1; j < mapCol-1; j++)//画最后一行
 {
  mapGame[20][j] = 2;
 }
 }

 public void initMap()//初始化这个地图,墙的ID是2,空格的ID是0,方块的ID是1
 {
 for(int i = 0; i < mapRow; i++)
 {
  for(int j = 0; j < mapCol; j++)
  {
  mapGame[i][j] = 0;
  }
 }
 }

 public void CreateRect()//创建方块---如果当前的方块类型和状态都存在就设置下一次的,如果不存在就设置当前的并且设置下一次的状态和类型
 {
 if(curShapeType == -1 && curShapeState == -1)//当前的方块状态都为1,表示游戏才开始
 {
  curShapeType = random.nextInt(shapes.length);
  curShapeState = random.nextInt(shapes[0].length);
 }
 else
 {
  curShapeType = nextShapeType;
  curShapeState = nextShapeState;
 }
 nextShapeType = random.nextInt(shapes.length);
 nextShapeState = random.nextInt(shapes[0].length);
 posx = 0;
 posy = 1;//墙的左上角创建方块
 if(GameOver(posx,posy,curShapeType,curShapeState))
 {
  JOptionPane.showConfirmDialog(null, "游戏结束!", "提示", JOptionPane.OK_OPTION);
  System.exit(0);
 }
 }

 public boolean GameOver(int x, int y, int ShapeType, int ShapeState)//判断游戏是否结束
 {
 if(IsOrNoMove(x,y,ShapeType,ShapeState))
 {
  return false;
 }
 return true;
 }

 public boolean IsOrNoMove(int x, int y, int ShapeType, int ShapeState)//判断当前的这个图形是否可以移动,这里重点强调x,y的坐标是指4*4的二维数组(描述图形的那个数组)的左上角目标
 {
 for(int i = 0; i < rowRect ; i++)
 {
  for(int j = 0; j < colRect; j++)
  {
  if(shapes[ShapeType][ShapeState][i*colRect+j] == 1 && mapGame[x+i][y+j] == 1
  || shapes[ShapeType][ShapeState][i*colRect+j] == 1 && mapGame[x+i][y+j] == 2)
  {
   return false;
  }
  }
 }
 return true;
 }

 public void Turn()//旋转
 {
 int temp = curShapeState;
 curShapeState = (curShapeState+1) % shapes[0].length;
 if(IsOrNoMove(posx,posy,curShapeType,curShapeState))
 {
 }
 else
 {
  curShapeState = temp;
 }
 repaint();
 }

 public void MoveDown()//向下移动
 {
 if(IsOrNoMove(posx+1,posy,curShapeType,curShapeState))
 {
  posx++;
 }
 else
 {
  AddToMap();//将此行固定在地图中
  CheckLine();
  CreateRect();//重新创建一个新的方块
 }
 repaint();
 }

 public void MoveLeft()//向左移动
 {
 if(IsOrNoMove(posx,posy-1,curShapeType,curShapeState))
 {
  posy--;
 }
 repaint();
 }

 public void MoveRight()//向右移动
 {
 if(IsOrNoMove(posx,posy+1,curShapeType,curShapeState))
 {
  posy++;
 }
 repaint();
 }

 public void AddToMap()//固定掉下来的这一图像到地图中
 {
 for(int i = 0; i < rowRect; i++)
 {
  for(int j = 0; j < colRect; j++)
  {
  if(shapes[curShapeType][curShapeState][i*colRect+j] == 1)
  {
   mapGame[posx+i][posy+j] = shapes[curShapeType][curShapeState][i*colRect+j];
  }
  }
 }
 }

 public void CheckLine()//检查一下这些行中是否有满行的
 {
 int count = 0;
 for(int i = mapRow-2; i >= 0; i--)
 {
  count = 0;
  for(int j = 1; j < mapCol-1; j++)
  {
  if(mapGame[i][j] == 1)
  {
   count++;
  }
  else
   break;
  }
  if(count >= mapCol-2)
  {
  for(int k = i; k > 0; k--)
  {
   for(int p = 1; p < mapCol-1; p++)
   {
   mapGame[k][p] = mapGame[k-1][p];
   }
  }
  score += 10;
  i++;
  }
 }
 }

 public void paint(Graphics g)//重新绘制窗口
 {
 super.paint(g);
 for(int i = 0; i < rowRect; i++)//绘制正在下落的方块
 {
  for(int j = 0; j < colRect; j++)
  {
  if(shapes[curShapeType][curShapeState][i*colRect+j] == 1)
  {
   g.fillRect((posy+j+1)*RectWidth, (posx+i+1)*RectWidth, RectWidth, RectWidth);
  }
  }
 }
 for(int i = 0; i < mapRow; i++)//绘制地图上面已经固定好的方块信息
 {
  for(int j = 0; j < mapCol; j++)
  {
  if(mapGame[i][j] == 2)//画墙
  {
   g.drawRect((j+1)*RectWidth, (i+1)*RectWidth, RectWidth, RectWidth);
  }
  if(mapGame[i][j] == 1)//画小方格
  {
   g.fillRect((j+1)*RectWidth, (i+1)*RectWidth, RectWidth, RectWidth);
  }
  }
 }
 g.drawString("score = "+ score, 225, 15);
 g.drawString("下一个方块:", 225, 50);
 for(int i = 0; i < rowRect; i++)
 {
  for(int j = 0; j < colRect; j++)
  {
  if(shapes[nextShapeType][nextShapeState][i*colRect+j] == 1)
  {
   g.fillRect(225+(j*RectWidth), 100+(i*RectWidth), RectWidth, RectWidth);
  }
  }
 }
 }

 public void NewGame()//游戏重新开始
 {
 score = 0;
 initMap();
 SetWall();
 CreateRect();
 repaint();
 }

 public void StopGame()//游戏暂停
 {
 timer.stop();
 }

 public void ContinueGame()
 {
 timer.start();
 }

 @Override
 public void keyTyped(KeyEvent e) {

 }

 @Override
 public void keyPressed(KeyEvent e) {
 switch(e.getKeyCode())
 {
 case KeyEvent.VK_UP://上----旋转
  Turn();
  break;
 case KeyEvent.VK_DOWN://下----向下移动
  MoveDown();
  break;
 case KeyEvent.VK_LEFT://左----向左移动
  MoveLeft();
  break;
 case KeyEvent.VK_RIGHT://右----向右移动
  MoveRight();
  break;
 }

 }

 @Override
 public void keyReleased(KeyEvent e) {
 // TODO Auto-generated method stub

 }

}

GameFrame类:整个游戏的进入口,好吧,说白了就是有main()函数的类,这个类里面实现游戏界面的一些设计,你可以理解为一个小小小小的UI;

package tetris;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;

public class GameFrame extends JFrame implements ActionListener{
 private int widthFrame = 500;
 private int heightFrame = 600;
 private JMenu menuone = new JMenu("游戏");//创建一个菜单
 private JMenuItem newGame = menuone.add("重新开始");//创建一个内置菜单选项
 private JMenuItem exitGame = menuone.add("游戏退出");
 private JMenuItem stopGame = menuone.add("游戏暂停");
 private JMenuItem goOnGame = menuone.add("游戏继续");

 private JMenu menutwo = new JMenu("帮助");//创建第二个菜单
 private JMenuItem aboutGame = menutwo.add("关于游戏");
 GamePanel gamepanel = new GamePanel();

 public GameFrame()//构造函数
 {
 addKeyListener(gamepanel);
 newGame.addActionListener(this);
 exitGame.addActionListener(this);
 stopGame.addActionListener(this);
 goOnGame.addActionListener(this);
 aboutGame.addActionListener(this);

 this.add(gamepanel);

 JMenuBar menu = new JMenuBar();
 menu.add(menuone);
 menu.add(menutwo);
 this.setJMenuBar(menu);

 this.setTitle("俄罗斯方块");
 this.setBounds(50, 10, widthFrame, heightFrame);
 this.setVisible(true);
 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

 }

 public void actionPerformed(ActionEvent e)
 {
 if(e.getSource() == newGame)//游戏重新开始
 {
  gamepanel.NewGame();
 }
 if(e.getSource() == exitGame)//游戏退出
 {
  System.exit(0);
 }
 if(e.getSource() == stopGame)//游戏暂停
 {
  gamepanel.StopGame();
 }
 if(e.getSource() == goOnGame)//游戏继续
 {
  gamepanel.ContinueGame();
 }
 if(e.getSource() == aboutGame)//关于游戏信息
 {
  JOptionPane.showMessageDialog(null, "左右键移动,向上建旋转", "提示", JOptionPane.OK_OPTION);
 }
 }

 public static void main(String[] args) {
 new GameFrame();
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Java 小游戏开发之俄罗斯方块

    Java项目 俄罗斯方块 一.心得 二.游戏实例 游戏截图 目录结构 三.代码 1.主界面 Tetris.java package com.fry.tetris; import java.util.Arrays; import java.util.Random; /** * 4格方块 */ public class Tetromino { protected Cell[] cells = new Cell[4]; /** 保存旋转的相对于轴位置状态 */ protected State[] st

  • java实现俄罗斯方块

    假期闲着无事,就用一周多的时间看了百度java吧的一位大神(alwing)发布的视频,学着用java写了一个俄罗斯方块,在此就以发布源代码以及必要讲解的形式来感谢他的帮助.当然我这里也是做了一些改动,做出来的程序界面以及功能没有和他的完全一样. 整个程序运行起来的界面如下所示: 程序包含的功能有: 俄罗斯方块本身基本的游戏元素 显示下一轮出现的方块.当前等级.分数.消行数等数值 以值槽形式显示当前等级到下一等级的距离 左上角头像以及背景图片会随着等级的升高而改变 循环播放背景音乐 一. 整个程序

  • java实现俄罗斯方块小程序

    这是java课最后做的课程设计,由于java是初学的,所以做的时候有参考一些技术大牛的博客,在此表示感谢. 发在这里跟大家交流学习一下. 如需要完整工程文件.说明文档以及可运行jar文件,下载地址:点击打开链接 RussianBlocksGame.java package RussiaBlocksGame; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.Bor

  • java实现俄罗斯方块小游戏

    本文实例为大家分享了java实现俄罗斯方块的具体代码,供大家参考,具体内容如下 使用一个二维数组保存游戏的地图: // 游戏地图格子,每个格子保存一个方块,数组纪录方块的状态 private State map[][] = new State[rows][columns]; 游戏前先将所有地图中的格子初始化为空: /* 初始化所有的方块为空 */ for (int i = 0; i < map.length; i++) { for (int j = 0; j < map[i].length;

  • Java游戏俄罗斯方块的实现实例

    Java游戏俄罗斯方块的实现实例 java小游戏主要理解应用java Swing,awt等基础组件的知识,通过本例应当掌握面向对象的知识. 实现代码: package cn.hncu.games; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import

  • Java俄罗斯方块小游戏

    去年就已经学了这个技术了,一直没去写,现在抽个时间写了个俄罗斯方块游戏. 只有简单的新游戏,暂停,继续,积分功能.简单的实现了俄罗斯的经典功能. 不介绍了,有兴趣的自己运行一下,后面贴出了图片. 代码: package cn.hncu; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.Act

  • java代码实现俄罗斯方块

    本文实例为大家分享了java实现俄罗斯方块的具体代码,供大家参考,具体内容如下 俄罗斯方块设计思想 俄罗斯方块都从小玩到大吧,什么规则大家都知道了吧,以前感觉那玩意贼好玩,但是就是老赢不了,现在学会了自己写一个天天练! 键盘操作: 左键:左移: 右键:右移: 上键:变换造型 下键:加速下掉(没毛病吧,没有继续整) 任意一行的方块满格,这一行就消除,消除一行方块得10分,目前小主我还没有设置关卡,各位喜欢的宝宝们可以自己设置关卡哦: 那么那些方块的造型到底从哪里来的呢,那就是我们自己设计的,常见的

  • Java实现简易俄罗斯方块

    本文实例为大家分享了Java实现简易俄罗斯方块的具体代码,供大家参考,具体内容如下 一.将对象抽象为类 首先考虑俄罗斯方块游戏中含有哪些具体的对象,对象中含有哪些具体属性和方法,然后用代码来实现. 建立如下类: Cell类:代表最小的方格单位,构成7种图形的最基本图形. 含有row(行号),col(列号),image(对应的图片)属性, 含有left(左移),right(右移),drop(下落)方法. Tetromino类:代表由4个最小方格构成的7种图形的合集. 含有cells(四个方块)属性

  • Java实现经典俄罗斯方块游戏

    目录 前言 主要设计 功能截图 代码实现 总结 前言 俄罗斯方块是一个最初由阿列克谢帕吉特诺夫在苏联设计和编程的益智类视频游戏. <俄罗斯方块>的基本规则是移动.旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多行并且消除得分. 用java语言实现,采用了swing技术进行了界面化处理,设计思路用了面向对象思想. 主要需求 由小方块组成的不同形状的板块陆续从屏幕上方落下来,玩家通过调整板块的位置和方向,使它们在屏幕底部拼出完整的一条或几条.这些完整的横条会随即消失,给新落下来的板块腾出

  • 详解Spring Boot 使用Java代码创建Bean并注册到Spring中

    从 Spring3.0 开始,增加了一种新的途经来配置Bean Definition,这就是通过 Java Code 配置 Bean Definition. 与Xml和Annotation两种配置方式不同点在于: 前两种Xml和Annotation的配置方式为预定义方式,即开发人员通过 XML 文件或者 Annotation 预定义配置 bean 的各种属性后,启动 spring 容器,Spring 容器会首先解析这些配置属性,生成对应都?Bean Definition,装入到 DefaultL

  • 让Java代码更高效

    本文简单介绍一下在写代码过程中用到的一些让JAVA代码更高效的技巧. 1,将一些系统资源放在池中,如数据库连接,线程等.在standalone的应用中,数据库连接池可以使用一些开源的连接池实现,如C3P0,proxool和DBCP等,在运行在容器中的应用这可以使用服务器提供的DataSource.线程池可以使用JDK本身就提供的java.util.concurrent.ExecutorService. import java.util.concurrent.Executors; import j

  • java 代码块与静态代码块加载顺序

    java 代码块与静态代码块加载顺序 public abstract class ClassLoadingTest { public static void main(String[] args) { User user3 = new User(); } } public class User { public static User user= new User("wang",18); public static void userSay(){ System.out.println(

  • Spring装配Bean之用Java代码安装配置bean详解

    前言 本文主要给大家介绍了关于Spring之利用Java代码安装配置bean的相关内容,尽管通过组件扫描和自动装配实现Spring的自动化配置很方便也推荐,但是有时候自动配置的方式实现不了,就需要明确显示的配置Spring.比如说,想要将第三方库中的组件装配到自己的应用中,这样的情况下,是没办法在它的类上添加 @Compnent和 @Autowired注解的. 在这种情况下,需要使用显示装配的方式,可以分别通过Java和XML实现,推荐使用Java的方式,因为更加强大,类型安全并且重构友好,因为

  • 新闻列表的分页查询java代码实现

    本文实例为大家分享了新闻列表分页查询的java代码,供大家参考,具体内容如下 package com.ibeifeng.test; //创建新闻测试类 public class newTest { private long id; private String title; private String content; private String author; public newTest() { super(); } public newTest(long id, String titl

  • Java代码统计网站中不同省份用户的访问数

    一.需求 针对log日志中给定的信息,统计网站中不同省份用户的访问数 二.编程代码 package org.apache.hadoop.studyhdfs.mapreduce; import java.io.IOException; import org.apache.commons.lang.StringUtils; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configured; im

  • 浅谈Java代码的 微信长链转短链接口使用 post 请求封装Json(实例)

    废话不多说,直接上代码 String longUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + MpUtil.APPID + "&redirect_uri=" + MpUtil.HOMEPAGE + "/nweixinLoginPc.fo%3Frandomcode=" + randomcode + "&response_type=co

随机推荐