去年就已经学了这个技术了,一直没去写,现在抽个时间写了个俄罗斯方块游戏。

只有简单的新游戏,暂停,继续,积分功能。简单的实现了俄罗斯的经典功能。

不介绍了,有兴趣的自己运行一下,后面贴出了图片。

代码:

  1. package cn.hncu;
  2. import java.awt.Color;
  3. import java.awt.Font;
  4. import java.awt.Graphics;
  5. import java.awt.event.ActionEvent;
  6. import java.awt.event.ActionListener;
  7. import java.awt.event.KeyAdapter;
  8. import java.awt.event.KeyEvent;
  9. import javax.swing.JFrame;
  10. import javax.swing.JMenu;
  11. import javax.swing.JMenuBar;
  12. import javax.swing.JMenuItem;
  13. import javax.swing.JOptionPane;
  14. import javax.swing.JPanel;
  15. import javax.swing.Timer;
  16. public class Tetris extends JFrame{
  17. public static void main(String[] args) {
  18. Tetris te = new Tetris();
  19. te.setVisible(true);
  20. //如果在界面中添加了编辑框等会抢占焦点的控件,则需要用下面的代码
  21. //te.requestFocus(true);//让游戏面板获得焦点--抢到键盘的监听
  22. }
  23. private TetrisPanel tp;
  24. JMenuItem itemPause;
  25. JMenuItem itemContinue;
  26. public Tetris() {
  27. this.setDefaultCloseOperation(EXIT_ON_CLOSE);
  28. this.setLocation(700, 200);
  29. this.setSize(220, 275);
  30. this.setResizable(false);
  31. tp = new TetrisPanel();
  32. this.getContentPane().add(tp);
  33. //添加菜单
  34. JMenuBar menubar = new JMenuBar();
  35. this.setJMenuBar(menubar);
  36. JMenu menuGame = new JMenu("游戏");
  37. menubar.add(menuGame);
  38. JMenuItem itemNew = new JMenuItem("新游戏");
  39. itemNew.setActionCommand("new");
  40. itemPause = new JMenuItem("暂停");
  41. itemPause.setActionCommand("pause");
  42. itemContinue = new JMenuItem("继续");
  43. itemContinue.setActionCommand("continue");
  44. itemContinue.setEnabled(false);
  45. menuGame.add(itemNew);
  46. menuGame.add(itemPause);
  47. menuGame.add(itemContinue);
  48. MenuListener menuListener = new MenuListener();
  49. itemNew.addActionListener(menuListener);
  50. itemPause.addActionListener(menuListener);
  51. itemContinue.addActionListener(menuListener);
  52. //让整个JFrame添加键盘监听
  53. this.addKeyListener( tp.listener );
  54. }
  55. class MenuListener implements ActionListener{
  56. @Override
  57. public void actionPerformed(ActionEvent e) {
  58. //玩新游戏
  59. if(e.getActionCommand().equals("new")){
  60. tp.newGame();
  61. }
  62. if(e.getActionCommand().equals("pause")){
  63. timer.stop();
  64. itemContinue.setEnabled(true);
  65. itemPause.setEnabled(false);
  66. }
  67. if(e.getActionCommand().equals("continue")){
  68. timer.restart();
  69. itemContinue.setEnabled(false);
  70. itemPause.setEnabled(true);
  71. }
  72. }
  73. }
  74. private Timer timer;
  75. class TetrisPanel extends JPanel{
  76. // 方块的形状:
  77. // 第一维代表方块类型(包括7种:S、Z、L、J、I、O、T)
  78. // 第二维代表旋转次数
  79. // 第三四维代表方块矩阵
  80. // shapes[type][turnState][i] i--> block[i/4][i%4]
  81. int shapes[][][] = new int[][][] {
  82. /*
  83. * 模板 { {0,0,0,0,0,0,0,0, 0,0,0,0, 0,0,0,0}, {0,0,0,0,0,0,0,0, 0,0,0,0,
  84. * 0,0,0,0}, {0,0,0,0,0,0,0,0, 0,0,0,0, 0,0,0,0}, {0,0,0,0,0,0,0,0,
  85. * 0,0,0,0, 0,0,0,0} }
  86. */
  87. // I (※把版本1中的横条从第1行换到第2行)
  88. { { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
  89. { 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 },
  90. { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
  91. { 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 } },
  92. // S
  93. { { 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  94. { 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
  95. { 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  96. { 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 } },
  97. // Z
  98. { { 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  99. { 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
  100. { 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  101. { 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 } },
  102. // J
  103. { { 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0 },
  104. { 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  105. { 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
  106. { 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
  107. // O
  108. { { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  109. { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  110. { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  111. { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
  112. // L
  113. { { 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0 },
  114. { 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  115. { 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
  116. { 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
  117. // T
  118. { { 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  119. { 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
  120. { 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  121. { 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 } }
  122. };
  123. private int blockType;//方块类型
  124. private int turnState;//旋转状态
  125. private int x;//方块的位置x--列的位置--列号
  126. private int y;//方块的位置y--行的位置--行号
  127. private int map[][]=new int[13][23];//地图:12列22行。为防止越界,数组开成:13列23行
  128. private int delay=1000;
  129. public TimerKeyLister listener=new TimerKeyLister();
  130. private int score=0;//分数
  131. public TetrisPanel(){
  132. newGame();
  133. nextBlock();
  134. //timer = new Timer(delay,listener);
  135. //timer.start();
  136. }
  137. public void newGame() {
  138. blockType = (int)(Math.random()*1000)%7;
  139. turnState = (int)(Math.random()*1000)%4;
  140. x=4;
  141. y=0;
  142. for( int i=0;i<12;i++){//走列
  143. for(int j=0;j<21;j++){//走行
  144. if(i==0 || i==11){//3为界面边框的格
  145. map[i][j]=3;//按理只要用0和1以外的整数就可以,但这里用3有特殊作用--后面用
  146. }else{
  147. map[i][j]=0;
  148. }
  149. }
  150. map[i][21]=3;//3为界面边框的格
  151. }
  152. if(timer!=null){
  153. timer.stop();
  154. }
  155. delay=1000;
  156. timer = new Timer(delay,listener);
  157. timer.start();
  158. }
  159. private void nextBlock() {
  160. blockType = (int)(Math.random()*1000)%7;
  161. turnState = (int)(Math.random()*1000)%4;
  162. x=4;
  163. y=0;
  164. //game Over
  165. if(crash(x,y,blockType,turnState)==0){
  166. timer.stop();
  167. int option = JOptionPane.showConfirmDialog(this,
  168. "Game Over!!,还敢来吗...");
  169. if (option == JOptionPane.OK_OPTION) {
  170. newGame();
  171. } else if (option == JOptionPane.NO_OPTION) {
  172. System.exit(0);
  173. }
  174. }
  175. }
  176. private void down() {
  177. if( crash(x,y+1,blockType,turnState)==0 ){//注意,这里用y+1,是判断块往下掉一格后,map中对应位置是否为堆积块或框架
  178. add(x,y,blockType,turnState);//把当前方块的信息保存到地图
  179. nextBlock();
  180. }else{
  181. y++;
  182. }
  183. repaint();
  184. }
  185. private void left() {
  186. if(x>=0){
  187. x -= crash(x-1,y,blockType,turnState);
  188. }
  189. repaint();
  190. }
  191. private void right() {
  192. if(x<8){
  193. x += crash(x+1,y,blockType,turnState);
  194. }
  195. repaint();
  196. }
  197. private void turn() {
  198. if(crash(x,y,blockType,(turnState+1)%4)==1 ){
  199. turnState = (turnState+1)%4;
  200. }
  201. repaint();
  202. }
  203. private void add(int x, int y, int blockType, int turnState) {
  204. for( int a=0; a<4; a++){
  205. for(int b=0; b<4; b++){
  206. if( shapes[blockType][turnState][a*4+b] ==1 ){
  207. map[x+b+1][y+a] = 1;
  208. }
  209. }
  210. }
  211. tryDelLine();
  212. }
  213. //消行
  214. private void tryDelLine(){
  215. for(int b=0;b<21;b++){
  216. int c=1;
  217. for(int a=0;a<12;a++){
  218. c &= map[a][b];//全部是1,c的结果才是1
  219. }
  220. if(c==1){//有一行需要消
  221. //依次往下移动一行
  222. for(int d=b; d>0; d--){
  223. for(int e=0;e<11;e++){
  224. map[e][d] = map[e][d-1];
  225. }
  226. }
  227. //加分
  228. score +=100;
  229. delay /=1.05;
  230. timer.setDelay(delay);
  231. }
  232. }
  233. }
  234. //参数例子: 4,3,2,3
  235. //判断有无碰撞
  236. private int crash(int x, int y, int blockType, int turnState){
  237. for( int a=0; a<4; a++){
  238. for(int b=0; b<4; b++){
  239. // if( (shapes[blockType][turnState][a*4+b]==1 && map[x+b+1][y+a] ==1) ||
  240. // (shapes[blockType][turnState][a*4+b]==1 && map[x+b+1][y+a] ==3 ) ){
  241. // }
  242. if( (shapes[blockType][turnState][a*4+b] & map[x+b+1][y+a]) ==1 ){
  243. return 0;//碰撞
  244. }
  245. }
  246. }
  247. return 1;//没有碰撞
  248. }
  249. @Override
  250. public void paint(Graphics g) {
  251. // blockType =6;
  252. // turnState = 3;
  253. // x=4;
  254. // y=6;
  255. super.paint(g);//消除残影
  256. g.setColor(new Color(153,51,205));
  257. //画当前方块
  258. for(int j=0;j<16;j++){
  259. if(shapes[blockType][turnState][j]==1){
  260. g.fillRect((j%4+x+1)*10, (j/4+y)*10, 10, 10);
  261. g.setColor(Color.cyan);
  262. g.drawRect((j%4+x+1)*10, (j/4+y)*10, 10, 10);
  263. g.setColor(new Color(153,51,205));
  264. }
  265. }
  266. //画界面框架 以及 堆积块---整个地图
  267. g.setColor(Color.red);
  268. for( int i=0;i<12;i++){//走列
  269. for(int j=0;j<22;j++){//走行
  270. if(map[i][j]==3){
  271. g.drawRect(i*10, j*10, 10, 10);
  272. }else if(map[i][j]==1){
  273. g.fillRect(i*10, j*10, 10, 10);
  274. g.setColor(Color.GREEN);
  275. g.drawRect(i*10, j*10, 10, 10);
  276. g.setColor(Color.red);
  277. }
  278. }
  279. }
  280. //显示分数,同时为版面美观,在界面上再加点东西
  281. // 画方块区右侧部分
  282. g.setColor(Color.red);
  283. g.setFont(new Font("aa", Font.BOLD, 11));
  284. g.drawString("score=" + score, 130, 20);
  285. g.setFont(new Font("aa", Font.PLAIN, 13));
  286. g.setColor(Color.blue);
  287. g.drawString("拒绝盗版游戏,", 125, 70);
  288. g.drawString("注意自我保护。", 125, 90);
  289. g.drawString("谨防受骗上当。", 125, 110);
  290. g.drawString("适度游戏益脑,", 125, 130);
  291. g.drawString("沉迷游戏伤身。", 125, 150);
  292. g.drawString("合理安排时间,", 125, 170);
  293. g.drawString("享受健康生活。", 125, 190);
  294. }
  295. class TimerKeyLister extends KeyAdapter implements ActionListener{
  296. @Override
  297. public void actionPerformed(ActionEvent e) {
  298. down();
  299. }
  300. @Override
  301. public void keyPressed(KeyEvent e) {
  302. switch(e.getKeyCode()){
  303. case KeyEvent.VK_DOWN:
  304. down(); break;
  305. case KeyEvent.VK_LEFT:
  306. left();break;
  307. case KeyEvent.VK_RIGHT:
  308. right();break;
  309. case KeyEvent.VK_UP:
  310. turn();break;
  311. case KeyEvent.VK_F1:
  312. plug();
  313. case KeyEvent.VK_F2:
  314. time();
  315. }
  316. }
  317. }
  318. public void plug() {
  319. score+=100;
  320. }
  321. public void time() {
  322. delay =1000;
  323. timer.setDelay(delay);
  324. }
  325. }
  326. }

运行界面:

Java---俄罗斯方块小游戏的更多相关文章

  1. C#俄罗斯方块小游戏程序设计与简单实现

    C#俄罗斯方块小游戏程序设计与简单实现 相信90后或者80后都玩过这款小游戏,一直想干一票,琢磨一下,但又不太懂,于是网上搜集修改就有了以下效果!bug较多,多多包涵! 1.效果展示 2.实现方法 参 ...

  2. Java太阳系小游戏分析和源代码

    Java太阳系小游戏分析和源代码 -20150809 近期看了面向对象的一些知识.然后跟着老师的解说做了一个太阳系各行星绕太阳转的小游戏,来练习巩固一下近期学的知识: 用到知识点:类的继承.方法的重载 ...

  3. Java五子棋小游戏(控制台纯Ai算法)

    Java五子棋小游戏(控制台纯Ai算法) 继续之前的那个五子棋程序 修复了一些已知的小Bug 这里是之前的五子棋程序 原文链接 修复了一些算法缺陷 本次增加了AI算法 可以人机对战 也可以Ai对Ai看 ...

  4. js实现简单的俄罗斯方块小游戏

    js实现简单的俄罗斯方块小游戏 开始 1. 创建一个宽为 200px,高为 360px 的背景容器 <!DOCTYPE html> <html lang="en" ...

  5. Java猜拳小游戏(剪刀、石头、布)

    1.第一种实现方法,调用Random数据包,直接根据“1.2.3”输出“剪刀.石头.布”.主要用了9条输出判断语句. import java.util.Random; import java.util ...

  6. 从零开始学java(小游戏 石头剪刀布)

    Game.java package com.java;import java.util.Scanner;public class Game {        private Player player ...

  7. Java石头剪刀布小游戏

    package com.neusoft.test; import java.awt.BorderLayout; import java.awt.Choice; import java.awt.Colo ...

  8. Java开发小游戏 用键盘控制精灵在游戏中上下左右跑动 窗体小游戏可打包下载,解压后双击start运行

    package com.swift; import java.awt.Point; import java.awt.event.KeyEvent; import com.rupeng.game.Gam ...

  9. Java经典小游戏——贪吃蛇简单实现(附源码)

    一.使用知识 Jframe GUI 双向链表 线程 二.使用工具 IntelliJ IDEA jdk 1.8 三.开发过程 3.1素材准备 首先在开发之前应该准备一些素材,已备用,我主要找了一个图片以 ...

  10. Java 坦克小游戏心得

    原本是闲得慌无聊才去尝试做这个项目的,因为小时候玩小霸王的游戏机,那个时候经常玩这个游戏吧,特别是喜欢那种自定义地图的模式,觉得自由度非常不错.总之关于这个游戏,想说的一大堆.鉴于能有个空闲的时间,打 ...

随机推荐

  1. java之泛型潜在错误

    如果使用带泛型声明的类时,没有传入类型参数,那么这个类型参数默认是声明该参数时指定的第一个上限类型,这个类型参数被称为raw type(原始类型 ). eg:     public class Lis ...

  2. 02_Jquery_01_id选择器

    首先建立建立一个JavaWeb项目工程,导入jquery-1.5.1.js. (一)选择器--打印文本内容 [index.jsp] <%@ page language="java&qu ...

  3. Codeforces Round #80 Div.1 D

    思路:考虑离线操作,以y为关键字排序,对于y相同的一起操作,然后考虑y的范围,当y<=sqrt(n)时,直接O(n)预处理出f[x]表示f[x]+f[x+y]+f[x+2*y]+..+f[x+k ...

  4. leetcode169——Majority Element (C++)

    Given an array of size n, find the majority element. The majority element is the element that appear ...

  5. fork();

    僵死进程: 父进程没有等待子进程,wait() 子进程会变成僵死进程. int main(int arg, char *args[]){ pid_t pid = fork();//调用fork产生一个 ...

  6. BFC与hasLayout之间的故事

    刚拒绝了一个很有诱惑的公司,不是不想去,而是对现在的能力还不确定,希望能够进一步提高自己的技能,所有想写博客了,监督自己的学习进度·········现在还没有开放博客,希望成熟一些后再开放吧! 进入正 ...

  7. express的基本配置项

    express自动生成的app.js中有一段代码用app.set和app.use对express进行配置,但这些配置都是什么意思,以及都能做哪些配置并没有展开.这一节就专门来讲express的配置.上 ...

  8. mysql可视化管理工具

    1.navicat for mysql 2.navicat premium 3.HeidiSQL 4.MySQLWorkbench

  9. TDirectory.GetDirectoryRoot获取指定目录的根目录

    使用函数: System.IOUtils.TDirectory.GetDirectoryRoot 函数定义: class function GetDirectoryRoot(const Path: s ...

  10. cursor_sharing

    CURSOR_SHARING Property Description Parameter type String Syntax CURSOR_SHARING = { EXACT | FORCE } ...