感觉写的挺好的,所以分享到最代码上来,如果有版权问题我会尽快删除,看截图
原创整理不易,请注明出处:同样分享一个网友的俄罗斯方块
swing的main类如下:
package com.zuidaima.swing.game import sun.audio.*; import java.awt.*; import java.awt.event.*; import java.io.IOException; import java.net.URL; import javax.imageio.ImageIO; import javax.swing.*; /** * Description:a simple tetric game * <br/>Program Name:Tetric Game * <br/>Date:2012.08.24 * @author Garth http://xiaojia.me * @version 1.0 */ @SuppressWarnings("serial") public class TetricGame extends JFrame{ public static void main(String[] args){ final TetricBlock tetricBlock = new TetricBlock(); final TetricGame tetricGame = new TetricGame(); //工具栏按钮动作 Action startAction = new AbstractAction("start" , new ImageIcon(TetricGame.class.getClassLoader().getResource("res/start.png"))) { public void actionPerformed(ActionEvent e) { tetricBlock.setIsGaming(true); tetricGame.requestFocus(); } }; Action pauseAction = new AbstractAction("pause" , new ImageIcon(TetricGame.class.getClassLoader().getResource("res/pause.png"))) { public void actionPerformed(ActionEvent a) { tetricBlock.setIsGaming(false); tetricGame.requestFocus(); } }; Action aboutAction = new AbstractAction("about" , new ImageIcon(TetricGame.class.getClassLoader().getResource("res/about.png"))) { public void actionPerformed(ActionEvent e) { tetricBlock.setIsGaming(false); JOptionPane.showMessageDialog(null , "Java新手练习项目:俄罗斯方块\n" + "作者:Garth\n" + "博客:http://xiaojia.me"); tetricBlock.setIsGaming(true); tetricGame.requestFocus(); } }; Action closeAction = new AbstractAction("close" , new ImageIcon(TetricGame.class.getClassLoader().getResource("res/close.png"))) { public void actionPerformed(ActionEvent e) { System.exit(0); } }; JToolBar jtb = new JToolBar(); //工具栏垂直并不可拖动 jtb.setOrientation(JToolBar.VERTICAL); jtb.setFloatable(false); jtb.add(startAction); jtb.add(pauseAction); jtb.add(aboutAction); jtb.add(closeAction); tetricGame.add(jtb , BorderLayout.EAST); tetricGame.add(tetricBlock); tetricGame.addKeyListener(tetricBlock); tetricGame.setSize( 323 , 474); tetricGame.setLocationRelativeTo(null); tetricGame.setTitle("俄罗斯方块"); tetricGame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); tetricGame.setVisible(true); //必不可少的一句,让主窗口获得焦点以监听键盘 tetricGame.requestFocus(); } } //方块类,继承JPanel类,实现KeyListener接口 @SuppressWarnings("serial") class TetricBlock extends JPanel implements KeyListener{ //游戏得分 private int score = 0; //方块下落的时间触发器 private Timer timer; //方块下落速度值,值越小,速度越快 private int speed = 1000; //游戏状态 private boolean isGaming = true; //背景音乐 private MusicPlayer bkMusic; //正在移动的方块坐标 private int x , y; //方块类型与状态 private int blockType , blockState; private int i = 0 , j = 0; //已经下落固定的方块map,0-11 ,0-21 private int[][] map = new int[13][23]; //方块,一维代表类型,二维代表状态,三维代表组成方块矩阵 private final int[][][] block = new int[][][] { { //一横一竖 { 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,0,1,1 , 0,1,1,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,0,1,1 , 0,1,1,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 } }, { //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 } }, { //T型 { 1,1,1,0 , 0,1,0,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 }, { 0,1,0,0 , 1,1,1,0 , 0,0,0,0 , 0,0,0,0 }, { 1,0,0,0 , 1,1,0,0 , 1,0,0,0 , 0,0,0,0 } } }; public TetricBlock() { newBlock(); newMap(); drawWall(); timer = new Timer( speed , new TimerListener() ); timer.start(); } //设置游戏状态 public void setIsGaming(boolean is) { isGaming = is; } //画围墙 public void drawWall(){ //底部围墙 for(i = 0 ; i < 12 ; i ++) { map[i][21] = 2; } //两边的围墙 for(i = 0 ; i < 22 ; i++) { map[0][i] = 2; map[11][i] = 2; } } //初始化数组 public void newMap(){ for(i = 0 ; i < 12 ; i++) { for(j = 0 ; j < 22 ; j++) { map[i][j] = 0; } } //循环播放背景音乐 try { bkMusic = new MusicPlayer(TetricGame.class.getClassLoader().getResource("res/background.wav")); bkMusic.loop(); } catch(Exception e) { } } //产生新的方块 public void newBlock(){ blockType = (int) (( Math.random() * 1000 ) % 7 ); blockState = (int) (( Math.random() * 1000) % 4 ); x = 4; y = 0; if(gameOver(x , y)){ JOptionPane.showMessageDialog(null, "Game Over! Score: " + score); newMap(); drawWall(); score = 0; speed = 1000; timer.setDelay(speed); isGaming = true; } } //判断移动方块是否合法 public boolean canMove( int x , int y , int blockType , int blockState ) { for( i = 0 ; i < 4 ; i++) for( j = 0 ; j < 4 ; j++) if(( block[blockType][blockState][ i * 4 + j ] == 1 && map[ j + x + 1][ i + y ] == 1 ) || ( block[blockType][blockState][ i * 4 + j ] == 1 && map[ j + x + 1][ i + y ] == 2 )) return false; return true; } //判断游戏是否结束 public boolean gameOver( int x , int y ) { if( !canMove( x , y , blockType , blockState ) ) { isGaming = false; //播放音乐 try { bkMusic.stopLoop(); new MusicPlayer(TetricGame.class.getClassLoader().getResource("res/gameover.wav")).start(); } catch(Exception e) { } return true; } return false; } //方块左移 public void moveLeft() { if( isGaming && canMove( x - 1 , y , blockType , blockState )) x--; repaint(); } //方块向右移 public void moveRight() { if( isGaming && canMove( x + 1 , y , blockType , blockState )) x++; repaint(); } //方块向下移 public void moveDown() { if( isGaming ) { if( canMove( x , y + 1 , blockType , blockState) ) { y++; dellLine(); } else { addBlock( x , y , blockType , blockState ); dellLine(); newBlock(); } repaint(); } } //改变方块状态 public void turnState() { if( isGaming ) { int tempState = blockState; blockState = ( blockState + 1 ) % 4; if( !canMove( x , y , blockType , blockState ) ) blockState = tempState; repaint(); } } //把不能再继续下落的方块加到固定方块里 public void addBlock( int x , int y , int blockType , int blockState ) { try { new MusicPlayer(TetricGame.class.getClassLoader().getResource("res/addblock.wav")).start(); } catch(Exception e){ } int k = 0; for( i = 0 ; i < 4 ; i++){ for( j = 0 ; j < 4 ; j++) { if(map[ j + x + 1 ][ i + y ] == 0) { map[ j + x + 1 ][ i + y ] = block[blockType][blockState][k]; } k++; } } } //消行 public void dellLine() { int k = 0; for( i = 0 ; i < 22 ; i++ ) { for( j = 0 ; j < 12 ; j++ ) { if( map[j][i] == 1) { k++; if( k >= 10 ) { //播放声音 try { new MusicPlayer(TetricGame.class.getClassLoader().getResource("res/delline.wav")).start(); } catch(Exception e) { } //游戏分数添加分数 score += 10; //速度越来越快 speed -= 15; timer.setDelay( speed ); //消行后,把上面固定的方块下移 for( int a = i ; a > 0 ; a--) for( int b = 0 ; b < 11 ; b++ ) { map[b][a] = map[b][a - 1]; } } } } k = 0; } repaint(); } public void paintComponent(Graphics g) { super.paintComponent(g); //方块图像 Image blockImage = null; try{ blockImage = ImageIO.read(TetricGame.class.getClassLoader().getResource("res/block.png")); } catch (IOException e){ e.printStackTrace(); } //正在下落的方块 for(i = 0 ; i < 16 ; i++) { if( block[blockType][blockState][i] == 1 ) { g.drawImage(blockImage, ((i % 4) + x + 1) * 20 , ((i / 4) + y) * 20,20,20 ,null); } } //已经下落的固定的方块以及围墙 for(i = 0 ; i < 22 ; i++) for(j = 0 ; j < 12 ; j++) { if(map[j][i] == 1) g.drawImage(blockImage , j * 20 , i * 20 , 20 , 20 , null); if(map[j][i] == 2) { g.setColor(new Color(9 , 106 , 187)); g.fillRect(j * 20 , i * 20 , 20 , 20); } } } //监听键盘上下左右方向键 public void keyPressed(KeyEvent e){ switch( e.getKeyCode() ) { case KeyEvent.VK_UP: turnState(); break; case KeyEvent.VK_DOWN: moveDown(); break; case KeyEvent.VK_LEFT: moveLeft(); break; case KeyEvent.VK_RIGHT: moveRight(); break; } } public void keyReleased(KeyEvent arg0){ } public void keyTyped(KeyEvent arg0){ } //内部类,时间监听器 class TimerListener implements ActionListener{ public void actionPerformed(ActionEvent e){ repaint(); moveDown(); } } //内部类,音乐播放器 class MusicPlayer{ //单次播放的声音 private AudioStream as = null; //循环播放的声音 private ContinuousAudioDataStream cas = null; public MusicPlayer(URL url) { try { as = new AudioStream(url.openStream()); } catch(Exception e) { } } //播放单次声音 public void start() { if(as != null) { AudioPlayer.player.start(as); } } //停止单次播放的声音 public void stop() { if(as != null) { AudioPlayer.player.stop(as); } } //循环播放声音 public void loop() { AudioData data = null; try { data = as.getData(); } catch(Exception e) { } if(data != null) { cas = new ContinuousAudioDataStream(data); AudioPlayer.player.start(cas); } } //停止循环播放的声音 public void stopLoop() { if(cas != null) { AudioPlayer.player.stop(cas); } } } }
完整代码下载:http://www.zuidaima.com/share/1550463376362496.htm
相关推荐
setting.xml文件,修改Maven仓库指向至阿里仓
基于java的玉安农副产品销售系统的开题报告
dev-c++ 6.3版本
基于java的项目监管系统开题报告
基于springboot多彩吉安红色旅游网站源码数据库文档.zip
毕业设计&课设_基于 AFLFast 改进能量分配策略的毕业设计项目,含 Mix Schedule策略设计及测试结果分析.zip
基于springboot办公用品管理系统源码数据库文档.zip
C++调用qml对象Demo
非常漂亮的类Web界面的Delphi设计54ed7-main.zip
VB SQL车辆管理系统是一款基于Visual Basic(VB)编程语言和SQL数据库开发的综合车辆管理工具。该系统集成了车辆信息管理、驾驶员信息管理、车辆调度、维修记录、数据存储与检索、报告生成以及安全权限管理等多个核心功能模块。 源代码部分提供了详细的开发流程和实现方法,涵盖了从数据库设计、界面设计到事件驱动编程、数据访问技术和错误处理等关键技术点。通过该系统,用户可以方便地录入、查询、修改和删除车辆及驾驶员信息,实现车辆信息的实时更新和跟踪。同时,系统还支持生成各类车辆管理相关的报告,帮助用户更好地掌握车辆运营情况。 系统部分则采用了直观易用的用户界面设计,使得用户能够轻松上手并快速完成车辆管理工作。系统还具备强大的数据处理能力和安全性,通过数据备份和系统升级优化等功能,确保数据的完整性和系统的稳定运行。 总体而言,VB SQL车辆管理系统是一款功能全面、易于操作且安全可靠的车辆管理工具,适用于企业和个人进行日常车辆运营和管理。无论是车辆信息的录入、查询还是报告生成,该系统都能够提供高效、便捷的服务,是车辆管理工作的理想选择。
AutoSAR基础学习资源
基于springboot英语学习平台源码数据库文档.zip
数据集,深度学习,密封数据集,马体态数据集
基于java的数字家庭网站开题报告
podman使用国内源镜像加速器
基于springboot+web的留守儿童网站源码数据库文档.zip
基于springboot的智能宾馆预定系统源码数据库文档.zip
GetQzonehistory-main.zip
环境说明:开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7 数据库工具:Navicat 开发软件:eclipse/myeclipse/idea Maven包:Maven 浏览器:谷歌浏览器。 项目经过测试均可完美运行
内容概要:本文档详细介绍了QST公司生产的QMI8A01型号的6轴惯性测量单元的数据表及性能参数。主要内容包括设备特性、操作模式、接口标准(SPI、I2C与I3C),以及各种运动检测原理和技术规格。文中还提到了设备的工作温度范围宽广,内置的大容量FIFO可用于缓冲传感器数据,减少系统功耗。此外,对于器件的安装焊接指导亦有详细介绍。 适合人群:电子工程技术人员、嵌入式开发人员、硬件设计师等。 使用场景及目标:适用于需要精准测量物体空间位置变化的应用场合,如消费电子产品、智能穿戴设备、工业自动化等领域。帮助工程师快速掌握该款IMU的技术要点和应用场景。 其他说明:文档提供了详细的电气连接图表、封装尺寸图解等资料,方便用户进行电路板的设计制作。同时针对特定应用提出了一些优化建议。