打地鼠
import java.awt.Cursor; import java.awt.Dimension; import java.awt.Font; import java.awt.GridLayout; import java.awt.Image; import java.awt.Point; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.Random; import javax.swing.BorderFactory; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.SwingConstants; import javax.swing.Timer; import javax.swing.border.BevelBorder; public class HitMouses extends JFrame implements ActionListener, MouseListener { private static final long serialVersionUID = 1L;// 唯一的可串行化版本号的标识 private String dir = "./images/";// 找到当前目录下的images文件 private Timer timer;// 用来显示地鼠 private Random uRandom;// 与Math.random()的方法同样 private JLabel jLabelMouse, timesShowLabel, timesHitLabel, gradeLabel; private int timesShow = 0, timesHit = 0, grade = 1, delay = 1000; private Font font = new Font("幼圆", Font.BOLD, 20); private boolean isHit;// 推断能否够击打地鼠,为true时不能够击打,且不能添加击打次数 private JMenu menuGame, menuHelp; private JMenuItem menuItemSatrt, menuItemEnd, menuItemHelp; public HitMouses() { // 设置框架 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setBounds(200, 100, 438, 375);// 这个大小会变。要注意最后一次调整.这个大小要依据背景图片定。图片大小为(433,346). // this.setResizable(false); // 设置背景 this.mySetBackground(); // 设置地鼠图片 this.mySetJLabelMouse(); // 设置光标图片 this.mySetCursorImage(1);// 图片应该显示成捶打的状态 this.addMouseListener(this);// 使整个图片都能够点击 // 设置标题 this.setTitle("打地鼠"); // new 对象 timer = new Timer(1000, new myActionListener()); uRandom = new Random(); // this.getContentPane().setLayout(null);// // 不加这句。地鼠的位置就会乱;不去掉,就无法显示面板,当然这是老鼠又能够正常显示了 // 加块面板 addJPanel(); // 加菜单栏 addMenu(); // 显示地鼠 timer.start(); // 设置显示 this.setVisible(true); } private void addMenu() { // new 对象 JMenuBar menuBar = new JMenuBar(); menuGame = new JMenu("Game"); menuHelp = new JMenu("Help"); menuItemSatrt = new JMenuItem("Start"); menuItemEnd = new JMenuItem("End"); menuItemHelp = new JMenuItem("About"); // 给菜单项加监听 menuItemSatrt.addActionListener(this); menuItemEnd.addActionListener(this); menuItemHelp.addActionListener(this); // menuGame加菜单项 menuGame.add(menuItemSatrt); menuGame.addSeparator(); menuGame.add(menuItemEnd); // menuHelp加菜单项 menuHelp.add(menuItemHelp); // 工具条加菜单 menuBar.add(menuGame); menuBar.add(menuHelp); // 加菜单栏 this.setJMenuBar(menuBar); } private void addJPanel() { JPanel panel = new JPanel(); panel.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));// 面板加图片最好设置边框。API提示 panel.setPreferredSize(new Dimension(438, 375));// 设置首选大小 panel.setOpaque(false);// 设置是否不透明。这里设置为透明 // 出现次数 timesShowLabel = new JLabel("0", new ImageIcon(dir + "chuxiancishu.png"), SwingConstants.CENTER); timesShowLabel.setFont(font); timesShowLabel.setSize(146, 40); // 当前等级 gradeLabel = new JLabel("1", new ImageIcon(dir + "dangqiandengji.png"), SwingConstants.CENTER); gradeLabel.setFont(font); gradeLabel.setSize(146, 40); // 打中次数 timesHitLabel = new JLabel("0", new ImageIcon(dir + "dazhongcishu.png"), SwingConstants.CENTER); timesHitLabel.setFont(font); timesHitLabel.setSize(146, 40); // 面板上加标签 panel.add(timesShowLabel); panel.add(timesHitLabel); panel.add(gradeLabel); // 加面板 this.getContentPane().add(panel); } private void mySetCursorImage(int i) { // 传进一个i各自是1或2 Toolkit tool = Toolkit.getDefaultToolkit();// 利用工厂方法。获得一个ToolKit对象 Image image = tool.createImage(dir + "chui" + i + ".png");// 能够用子类BufferedImage Cursor cursor = tool.createCustomCursor(image, new Point(10, 10), "lq"); // 名字能够随便给一个 // hotSpot 热点范围 this.setCursor(cursor); } private void mySetJLabelMouse() { // 与mySetMouseImage(1)不同的是,这个有监听,最好不要反复写 ImageIcon image = new ImageIcon(dir + "dishu1.png"); jLabelMouse = new JLabel(image); // 设置位置,可使图片显示在不同的位置 jLabelMouse.setBounds(56, 63, 80, 80);// 图片大小(59,69); this.getContentPane().add(jLabelMouse); jLabelMouse.setVisible(false); jLabelMouse.addMouseListener(this); } private void mySetMouseImage(int i) { // 与mySetJLabelMouse()不同的是,这个仅仅用来转换图片 ImageIcon image = new ImageIcon(dir + "dishu" + i + ".png"); jLabelMouse.setIcon(image); jLabelMouse.setVisible(true); } private void mySetBackground() { ((JPanel) this.getContentPane()).setOpaque(false);// 转换成子类。调用setOpaque(不透明的)//同意其底层像素透视出来 Icon image = new ImageIcon(dir + "beijing.jpg"); JLabel backLabel = new JLabel(image); backLabel.setBounds(0, 0, image.getIconWidth(), image.getIconHeight());// 必需要设置大小,不然无法显示 // this.getLayeredPane().add(backLabel);// 无法显示图片 this.getLayeredPane().add(backLabel, new Integer(Integer.MIN_VALUE)); } public static void main(String[] args) { new HitMouses(); } private class myActionListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { // 产生一个随机数使地鼠不断出现,这个技术实际上就是图片的分层显示,仅仅要把这个解决。图片类游戏基本学会 // 方法:把图片放到JLabel中,然后设置位置显示,就这么简单 int ran = uRandom.nextInt(9);// 这种方法比Math.random()的方法好用一些//属于[0,9)范围内 // 设置老鼠位置 switch (ran) { case 0: jLabelMouse.setLocation(56, 38);// 63-25= 38 break; case 1: jLabelMouse.setLocation(322, 179);// 204 -25 = 179 break; case 2: jLabelMouse.setLocation(185, 179); break; case 3: jLabelMouse.setLocation(48, 178); break; case 4: jLabelMouse.setLocation(298, 108);// 133 -25 = 108 break; case 5: jLabelMouse.setLocation(162, 108); break; case 6: jLabelMouse.setLocation(22, 108); break; case 7: jLabelMouse.setLocation(311, 38); break; case 8: jLabelMouse.setLocation(186, 38); break; } // 每次老鼠出来都是没有打中的样子 mySetMouseImage(1); // 游戏规则: // 每击中7次就升一次级; // 假设满四级就代表游戏胜利; // 老鼠出现15次就表示游戏失败。 if (mouseShowTimes() >= 15) {// 游戏失败处理. end(); int yes = JOptionPane.showConfirmDialog(HitMouses.this, "非常遗憾,你输了。\n是否要又一次開始?", "失败", JOptionPane.YES_NO_OPTION); if (yes == JOptionPane.YES_NO_OPTION) { start(); } } } } @Override public void actionPerformed(ActionEvent e) { if (e.getSource() == menuItemSatrt) { start(); return; } if (e.getSource() == menuItemEnd) { if (JOptionPane.showConfirmDialog(this, "你确定要退出吗?") == 0) { System.exit(0); } return; } if (e.getSource() == menuItemHelp) { JDialog dialog = new JDialog(this, "游戏规则:"); dialog.setBounds(this.getX()+20, this.getY()+20, 250, 160); dialog.setLayout(new GridLayout(4, 1)); dialog.add(new JLabel("游戏规则")); dialog.add(new JLabel("1)每击中7次就升一次级;")); dialog.add(new JLabel("2)假设满四级就代表游戏胜利;")); dialog.add(new JLabel("3)老鼠出现15次就表示游戏失败。")); dialog.setVisible(true); } } public void end() { timer.stop(); } public void start() { mySetMouseImage(1); timesShow = 0; timesHit = 0; grade = 1; delay = 1000; timesShowLabel.setText("" + timesShow); timesHitLabel.setText("" + timesHit); gradeLabel.setText("" + grade); timer.start(); setDelay(0); } public int mouseShowTimes() { timesShow++; timesShowLabel.setText("" + timesShow); // 老鼠每次出现都定义为未击打状态 isHit = false; return timesShow; } public int mouseHitTimes() { timesHit++; timesHitLabel.setText("" + timesHit); return timesHit; } public int mouseGrade() { grade++; gradeLabel.setText("" + grade); return grade; } public void setDelay(int d) { if (timer != null) { delay += d; if (delay < 290) {// 4*180 = 720 delay = 1000; } timer.setDelay(delay); } } // 鼠标监听能够写成内部类,可是这里有特殊需要,比方:点击图片的任何位置都能够是光标变化 @Override public void mouseClicked(MouseEvent e) {// 没用 } @Override public void mousePressed(MouseEvent e) {// 目标 mySetCursorImage(2); if (e.getSource() == jLabelMouse && !isHit) { // 老鼠被打中,那么再下次老鼠没有出来之前,不可再次击打老鼠。且不可添加击打次数 isHit = true; // 光标显示击打状态 mySetMouseImage(2); // 升级 if (mouseHitTimes() >= 7) {// 击中7次时 setDelay(-180); // 游戏胜利推断 if (mouseGrade() >= 5) { end(); // 游戏结束,老鼠不可显示 jLabelMouse.setVisible(false); int a = JOptionPane.showConfirmDialog(this, "您打通关了。要又一次来吗?", "恭喜!!!", JOptionPane.YES_NO_OPTION); if (a == JOptionPane.YES_OPTION) { start(); } } // 初始化老鼠出现次数和击打次数 timesShow = -1; timesHit = -1; mouseShowTimes(); mouseHitTimes(); } } } @Override public void mouseReleased(MouseEvent e) {// 目标 mySetCursorImage(1); } @Override public void mouseEntered(MouseEvent e) {// 没用 } @Override public void mouseExited(MouseEvent e) {// 没用 } }