package Rush; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.Timer; import javax.swing.event.MenuEvent; import javax.swing.event.MenuListener; public class Teris extends JFrame { private TetrisPanel a; private JMenuItem j1, j2, j3, j4,c1,c2,c3,n1,n2,n3; private JMenu menuGame, menuEdit,menuHelp; public Teris() { // 添加菜单, JMenuBar menubar = new JMenuBar(); setJMenuBar(menubar); // 菜单 menuGame = new JMenu("游戏"); menubar.add(menuGame); menuEdit = new JMenu("编辑"); menubar.add(menuEdit); menuHelp=new JMenu("帮助"); menubar.add(menuHelp); // String chStr[]={"游戏","编辑","帮助"}; // JMenu menuGame[] = new JMenu[chStr.length]; // for(int i=0;i< chStr.length;i++){ // menuGame[i]=new JMenu(chStr[i]); // menuGame[i].setMargin(new Insets(1,2,3,4)); // menubar.add(menuGame[i]); // } // 菜单项 j1 = new JMenuItem("新游戏"); j1.setActionCommand("newGame"); menuGame.add(j1); j2 = new JMenuItem("暂停"); j2.setActionCommand("pause"); menuGame.add(j2); j3 = new JMenuItem("继续"); j3.setActionCommand("restart"); menuGame.add(j3); j4 = new JMenuItem("Open"); menuGame.add(j4); c1=new JMenuItem("剪切"); menuEdit.add(c1); c2=new JMenuItem("复制"); menuEdit.add(c2); c3=new JMenuItem("粘贴"); menuEdit.add(c3); JMenu a1=new JMenu("二级菜单"); menuHelp.add(a1); n1=new JMenuItem("查找"); n1.setActionCommand("search"); a1.add(n1); n2=new JMenuItem("字体"); a1.add(n2); n3=new JMenuItem("超链接"); menuHelp.add(n3); // 菜单监听 Menulistener m1 = new Menulistener(); j1.addActionListener(m1); j2.addActionListener(m1); j3.addActionListener(m1); // 另一种添加方式 j4.addActionListener(m1); n1.addActionListener(m1); // TetrisPanel a = new TetrisPanel(); a = new TetrisPanel(); this.addKeyListener(a.listener); // 正式开发不用this,运行效率跟高 add(a); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(220, 275); setLocation(400, 100); setTitle("俄罗斯方块精简版"); setResizable(false); } // 用面板当画布,界面刷新效果更好 class TetrisPanel extends JPanel { private int blockType;// 0-6 3之间的随机数 private int turnState;// 0-3 2 private int x; private int y; private int delay; private int score; private TimerLister listener = new TimerLister(); private Timer timer; // 定义地图,用来存放整个游戏方块区的状态(显示方格,或不现实) // 存放快的位置;x=0~11,y=0~21 int map[][] = new int[13][23];// 为绝决越界,预留一列 // 方块的形状:第一维代表方块的类型(包括7重:S、Z、L、J、I、O、T) // 第二维代表方块的形状 // 第三四位代表方块的矩阵 private final int[][][] shapes = new int[][][] { // I (※把版本1中的横条从第1行换到第2行) { { 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 }, { 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 } }, // 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 TetrisPanel() { nextBlock(); newGame(); } // 生成一个新的的方块 public void nextBlock() { // blockType和turnState两个变量即决定是什么样的方块 // 每次新生成一个快就是产生为这两个变量产生一个新的值 blockType = (int) (Math.random() * 1000) % 7; turnState = (int) (Math.random() * 1000) % 4; x = 4; y = 0; if (crash(x, y, blockType, turnState) == 0) { timer.stop(); int option = JOptionPane.showConfirmDialog(this, "Game Over~"); if (option == JOptionPane.OK_OPTION) { newGame(); } else if (option == JOptionPane.NO_OPTION) { System.exit(0); } } } // 初始化地图(外框) public void newGame() { for (int i = 0; i < 12; i++) { for (int j = 0; j < 22; j++) { map[i][j] = 0; map[11][j] = map[0][j] = 3; } map[i][21] = 3; } // timer = new Timer(300, listener); delay = 1000; timer = new Timer(delay, listener); timer.start(); score = 0;// 分数 nextBlock(); repaint(); } // 暂停方法 private void pause() { timer.stop(); } // 开始方法 private void restart() { timer.restart(); } // 打开网页方法;随便写,与本程序无关 private void Open() { Runtime timer1 = Runtime.getRuntime(); try { // timer1.exec("notepad d:\\java\\java1.txt");// 打开文本文档 timer1.exec("C:\\Program Files\\Internet Explorer\\IEXPLORE.EXE www.baidu.cn");// 打开网页 } catch (Exception e) { System.out.println(e.getMessage()); } } private void search(){ Runtime timer1 = Runtime.getRuntime(); try { timer1.exec("notepad d:\\java");// 打开文本文档,但是拒绝访问?? //timer1.exec("C:\\Program Files\\Internet Explorer\\IEXPLORE.EXE www.baidu.cn");// 打开网页 } catch (Exception e) { System.out.println(e.getMessage()); } } // 下落方法 private void down() { if (crash(x, y + 1, blockType, turnState) == 0) { add(x, y, blockType, turnState); nextBlock(); } y++; repaint(); } // 判断是否碰撞 private int crash(int x, int y, int blockType, int turnState) { for (int a = 0; a < 4; a++) { for (int b = 0; b < 4; b++) { if ((shapes[blockType][turnState][a * 4 + b] & map[x + b + 1][y + a]) == 1) { return 0; } } } return 1; } private void add(int x, int y, int blockType, int turnState) { for (int a = 0; a < 4; a++) { for (int b = 0; b < 4; b++) { if (shapes[blockType][turnState][a * 4 + b] == 1) map[x + b + 1][y + a] = shapes[blockType][turnState][a * 4 + b]; } } tryDeline(); } private void turn() { turnState = (turnState + crash(x, y, blockType, (turnState + 1) % 4)) % 4; repaint(); } private void left() { x -= crash(x - 1, y, blockType, turnState); repaint(); } private void right() { x += crash(x + 1, y, blockType, turnState); repaint(); } public void tryDeline() { for (int b = 0; b < 21; b++) { int c = 1; for (int a = 0; a < 12; a++) {// 10行10列是真正的方块区 // 方法一 设置标志 用素数方法 // 方法二 用于运算 c &= map[a][b]; } if (c == 1) { // 销行 //从上往下 组行扫描 吧下一行的格子依次往上移 其实就是赋值 for (int d = b; d > 0; d--) { for (int e = 1; e < 11; e++) { map[e][d] = map[e][d - 1]; } } // 游戏加分 score += 10; delay /= 2; timer.setDelay(delay); } } } @Override // 花当前快 protected void paintComponent(Graphics g) { super.paintComponent(g);// 清除残影(清除背景) g.setColor(Color.blue); for (int j = 0; j < 16; j++) { if (shapes[blockType][turnState][j] == 1) { g.fillRect((j % 4 + x + 1) * 10, (j / 4 + y) * 10, 10, 10); } } // 画已经固定的方块 g.setColor(Color.red); for (int j = 0; j < 22; j++) { for (int i = 0; i < 12; i++) { if (map[i][j] == 1) { g.fillRect(i * 10, j * 10, 10, 10); // 让堆积快有分界线 g.setColor(Color.BLACK); g.drawRect(i * 10, j * 10, 10, 10); g.setColor(Color.red); } else if (map[i][j] == 3) { g.drawRect(i * 10, j * 10, 10, 10); } } } // 画放块去右侧部分 g.setColor(Color.black); g.setFont(new Font("aa", Font.BOLD, 18)); g.drawString("score=" + score, 130, 20); g.setFont(new Font("aa", Font.PLAIN, 13)); g.drawString("拒绝盗版游戏", 125, 80); g.drawString("注意自我保护", 125, 100); g.drawString("谨防上当受骗", 125, 120); g.drawString("适度游戏益脑", 125, 140); g.drawString("过度游戏伤身", 125, 160); g.drawString("合理安排时间", 125, 180); g.drawString("享受健康生活", 125, 200); } class TimerLister extends KeyAdapter implements ActionListener { public void actionPerformed(ActionEvent e) { down(); } public void keyPressed(KeyEvent e) { int keyCode = e.getKeyCode(); switch (keyCode) { case KeyEvent.VK_DOWN: down(); break; case KeyEvent.VK_UP: turn(); break; case KeyEvent.VK_LEFT: left(); break; case KeyEvent.VK_RIGHT: right(); break; } } } } class Menulistener implements ActionListener { public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals("newGame")) { a.newGame(); j2.setEnabled(true); j3.setEnabled(false); } else if (e.getActionCommand().equals("pause")) { a.pause(); j2.setEnabled(false); j3.setEnabled(true); } else if (e.getActionCommand().equals("restart")) { a.restart(); j3.setEnabled(false); j2.setEnabled(true); } else if (e.getActionCommand().equals("Open")) { a.Open(); }else if (e.getActionCommand().equals("search")) { a.search(); } } } public static void main(String[] args) { Teris te = new Teris(); te.setVisible(true); } }