感觉写的挺好的,所以分享到最代码上来,如果有版权问题我会尽快删除,看截图
原创整理不易,请注明出处:同样分享一个网友的俄罗斯方块
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://blog.csdn.net/yaerfeng/article/details/20036125