打地鼠

来源:互联网 发布:淘宝买东西到加拿大 编辑:程序博客网 时间:2024/05/02 02:07


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或2Toolkit tool = Toolkit.getDefaultToolkit();// 利用工厂方法,获得一个ToolKit对象Image image = tool.createImage(dir + "chui" + i + ".png");// 可以用子类BufferedImageCursor 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 {@Overridepublic void actionPerformed(ActionEvent e) {// 产生一个随机数使地鼠不断出现,这个技术实际上就是图片的分层显示,只要把这个解决,图片类游戏基本学会// 方法:把图片放到JLabel中,然后设置位置显示,就这么简单int ran = uRandom.nextInt(9);// 这个方法比Math.random()的方法好用一些//属于[0,9)范围内// 设置老鼠位置switch (ran) {case 0:jLabelMouse.setLocation(56, 38);// 63-25= 38break;case 1:jLabelMouse.setLocation(322, 179);// 204 -25 = 179break;case 2:jLabelMouse.setLocation(185, 179);break;case 3:jLabelMouse.setLocation(48, 178);break;case 4:jLabelMouse.setLocation(298, 108);// 133 -25 = 108break;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();}}}}@Overridepublic 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 = 720delay = 1000;}timer.setDelay(delay);}}// 鼠标监听可以写成内部类,但是这里有特殊需要,比如:点击图片的任意位置都可以是光标变化@Overridepublic void mouseClicked(MouseEvent e) {// 没用}@Overridepublic 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();}}}@Overridepublic void mouseReleased(MouseEvent e) {// 目标mySetCursorImage(1);}@Overridepublic void mouseEntered(MouseEvent e) {// 没用}@Overridepublic void mouseExited(MouseEvent e) {// 没用}}

           

            

      









1 0