码迷,mamicode.com
首页 > 其他好文 > 详细

打地鼠

时间:2015-06-23 10:18:49      阅读:242      评论:0      收藏:0      [点我收藏+]

标签:游戏   java   

技术分享


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) {// 没用
	}
}
技术分享

技术分享        技术分享   

技术分享      技术分享      技术分享

技术分享      技术分享









打地鼠

标签:游戏   java   

原文地址:http://blog.csdn.net/hncu1306602liuqiang/article/details/46598937

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!