Java 多线程的利用(弹球小游戏)



      最近在搞一个弹球游戏,其中,用到了Java多线程的应用,首先,先说一下,什么叫做线程。或许大家都知道进程是什么,打开电脑的任务管理器,可以看到,里面有进程这个选项,非常明显,进程就是一个程序,而每个程序,有由多个线程组成。好了,这样说的不清不楚的,那么好,我用一个弹球小游戏来解释一下,那样可能大家会更容易理解些。

 

import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
 * 游戏界面类
 * 
 * @author Administrator
 * 
 */
public class GameUI extends javax.swing.JFrame {
	private static GameUI UI;
	private java.awt.Graphics g;
	private MyListener ml;
	public javax.swing.JLabel text_field;
	public javax.swing.JProgressBar pBar;
	private String command;
	public java.util.ArrayList list = new java.util.ArrayList();
	private javax.swing.JToggleButton button;

	public static void main(String args[]) {
		UI = new GameUI();
		UI.initUI();
	}

	/**
	 * 初始化窗体的方法
	 */
	public void initUI() {
		// 设置标题
		this.setTitle("是高手就坚持100s");
		// 设置大小
		this.setSize(610, 635);
		// 设置关闭是退出程序
		this.setDefaultCloseOperation(3);
		// 设置打开窗体时在屏幕中间显示
		this.setLocationRelativeTo(null);
		// 设置窗体的流式布局管理器
		this.setLayout(new java.awt.FlowLayout());
		// 设置窗体背景颜色
		this.getContentPane().setBackground(java.awt.Color.black);
		// 创建文本标签对象
		text_field = new javax.swing.JLabel();
		javax.swing.JLabel lable = new javax.swing.JLabel("时  间  :");
		// 设置文本标签前景颜色
		lable.setForeground(java.awt.Color.red);
		text_field.setForeground(java.awt.Color.red);

		

		// 创建进度条对象
		pBar = new javax.swing.JProgressBar(0, 330);
		// 创建按钮对象
		button = new javax.swing.JToggleButton();
		button.setMargin(new Insets(0, 0, 0, 0));
		button.setIcon(new javax.swing.ImageIcon("images/Pause.gif"));
		button.setActionCommand("暂停");
		// 通过匿名内部类来创建动作监听器
		java.awt.event.ActionListener button_listener = new java.awt.event.ActionListener() {

			public void actionPerformed(ActionEvent e) {
				String com = e.getActionCommand();

				if (com.equals("暂停")) {
					button.setMargin(new Insets(0, 0, 0, 0));
					button
							.setIcon(new javax.swing.ImageIcon(
									"images/start.gif"));
					button.setActionCommand("继续");
					for (int i = 0; i < list.size(); i++) {
						list.get(i).PauseThread();

					}

				}
				if (com.equals("继续")) {

					button.setMargin(new Insets(0, 0, 0, 0));
					button
							.setIcon(new javax.swing.ImageIcon(
									"images/Pause.gif"));
					button.setActionCommand("暂停");

					for (int i = 0; i < list.size(); i++) {
						list.get(i).ContinueThread();
					}

				}

			}

		};
		button.addActionListener(button_listener);

		this.add(button);
		this.add(lable);
		this.add(pBar);
		this.add(text_field);
		// 的到菜单条
		javax.swing.JMenuBar bar = creatMenuBar();
		// 为窗体设置菜单条
		this.setJMenuBar(bar);
		// 设置窗体的可见性
		this.setVisible(true);
	}

	/**
	 * 创建菜单条的方法
	 * 
	 * @return
	 */
	public javax.swing.JMenuBar creatMenuBar() {
		// 创建菜单条对象
		javax.swing.JMenuBar bar = new javax.swing.JMenuBar();
		// 创建菜单对象
		javax.swing.JMenu menu_menu = new javax.swing.JMenu("菜单");
		javax.swing.JMenu difficulty_menu = new javax.swing.JMenu("难度");
		javax.swing.JMenu help_menu = new javax.swing.JMenu("帮助");
		// 创建菜单选项对象
		javax.swing.JMenuItem star_item = new javax.swing.JMenuItem("开始");
		javax.swing.JMenuItem exit_item = new javax.swing.JMenuItem("退出");
		javax.swing.JMenuItem help_item = new javax.swing.JMenuItem("游戏说明");
		javax.swing.JMenuItem about_item = new javax.swing.JMenuItem("关于");
		// 创建单选选项
		javax.swing.JRadioButtonMenuItem easy_item = new javax.swing.JRadioButtonMenuItem(
				"简单");
		javax.swing.JRadioButtonMenuItem middle_item = new javax.swing.JRadioButtonMenuItem(
				"中等");
		javax.swing.JRadioButtonMenuItem hard_item = new javax.swing.JRadioButtonMenuItem(
				"困难");
		// 创建一个按钮组
		javax.swing.ButtonGroup group = new javax.swing.ButtonGroup();
		// 将单选按钮添加到按钮组中
		group.add(easy_item);
		group.add(middle_item);
		group.add(hard_item);
		// 将单选按钮添加到菜单中
		difficulty_menu.add(easy_item);
		difficulty_menu.add(middle_item);
		difficulty_menu.add(hard_item);
		// 通过匿名内部类来创建动作监听器
		ActionListener listener = new java.awt.event.ActionListener() {
			public void actionPerformed(ActionEvent e) {
				command = e.getActionCommand();
				// 如果选择开始,则创建线程对象
				if (command.equals("开始") && list.size() == 0) {
					creatBall(20, 1);

				}
				// 如果选择退出按钮,则退出程序
				if (command.equals("退出")) {
					System.exit(0);
				}

				// 如果选择简单按钮
				if (command.equals("简单") && list.size() == 0) {

					creatBall(20, 1);
				}

				// 如果选择中等按钮
				if (command.equals("中等") && list.size() == 0) {
					creatBall(50, 2);

				}
				if (command.equals("困难") && list.size() == 0) {
					creatBall(40, 2);
				}
				if (command.equals("游戏说明")) {
					javax.swing.JOptionPane.showMessageDialog(null,
							"移动鼠标,用挡板接球,如果接不住,就算输了……\n游戏可以选择难度,包括简单、中等、困难");
				}
				if (command.equals("关于")) {
					javax.swing.JOptionPane
							.showMessageDialog(null,
									"这是一个用Java编写的小游戏……\n制作人:沈冠军\n时间:2010年8月\n版权所有,翻版必究!");
				}
			}
		};
		// 添加动作监听器
		star_item.addActionListener(listener);
		exit_item.addActionListener(listener);
		easy_item.addActionListener(listener);
		middle_item.addActionListener(listener);
		hard_item.addActionListener(listener);
		help_item.addActionListener(listener);
		about_item.addActionListener(listener);

		// 将菜单选项对象添加到菜单对象上
		menu_menu.add(star_item);
		menu_menu.add(exit_item);
		help_menu.add(help_item);
		help_menu.add(about_item);
		// 将菜单对象添加到菜单条上
		bar.add(menu_menu);
		bar.add(difficulty_menu);
		bar.add(help_menu);
		// 返回菜单条对象
		return bar;
	}

	/**
	 * 创建线程对象的方法
	 * 
	 * @param speed
	 *            :速度
	 * 
	 */
	public void creatBall(int speed, int num) {
		java.util.Random ran = new java.util.Random();

		if (ml == null) {
			g = UI.getGraphics();
			ml = new MyListener(g);
			UI.addMouseListener(ml);
			UI.addMouseMotionListener(ml);

		}
		for (int i = 0; i < num; i++) {
			int x = ran.nextInt(600) + 10;
			int y = ran.nextInt(300) + 100;
			MyThread th = new MyThread(g, ml, UI, x, y, speed);
			list.add(th);
			th.start();
		}

	}

	/**
	 * 得到命令的方法
	 */
	public String getCommand() {
		return command;
	}

}import java.awt.Color;

import javax.swing.JOptionPane;
/**
 * 线程类
 * 
 * @author Administrator
 * 
 */
public class MyThread extends Thread {
	private int width = 20, height = 20;
	private int x, y;
	private  java.awt.Graphics g;
	private GameUI UI;
	private boolean isexist = true;
	private MyListener listener;
	private int speed;
	private int x1 = 12, y1 = 12;
	private long start, end;
	private long last_time;
	private int response;
	private boolean isFinish = true;
	private boolean isPause = true;
	private java.util.ArrayList list;
	private float value = 320;
	private java.awt.Color color = java.awt.Color.blue;

	/*
	 * 重写构造器
	 */
	public MyThread(java.awt.Graphics g, MyListener listener, GameUI UI, int x,
			int y, int speed) {
		this.g = g;
		this.UI = UI;
		this.x = x;
		this.y = y;
		this.speed = speed;
		this.listener = listener;
	}

	/*
	 * (non-Javadoc)重写run的方法
	 * 
	 * @see java.lang.Thread#run()
	 */
	public void run() {
		drawOval();
	}

	/**
	 * 创建线程的方法
	 */
	public void drawOval() {
		
		
		start = System.currentTimeMillis();
		while (isFinish) {
			while (isPause) {
				synchronized(this.g){
				// 画一个圆
				g.setColor(java.awt.Color.black);
				g.fillOval(x, y, width, height);
				x += x1;
				y += y1;

				getColors();
				g.setColor(color);
				g.fillOval(x, y, width, height);
				}
				int x2 = listener.getX();
				if (x > 580) {
					x1 = -12;
				}
				if (x < 10) {
					x1 = 12;
				}
				if (y < 90) {
					y1 = 12;
				}
				if (y > 595 && x > x2 && x < x2 + 100) {
					y1 = -12;
				}
				if (y > 630) {
					if (isexist) {
						isAgain();
					}
					stopThread();
				}
				try {
					Thread.sleep(speed);
					value -= 0.1;
				} catch (Exception ef) {
					ef.printStackTrace();
				}
				// 将前一次画的清除掉
				end = System.currentTimeMillis();
				last_time = 100 - (end - start) / 1000;
				UI.text_field.setText(last_time + "s");
				UI.pBar.setValue((int) value);
				if (last_time == 0) {
					list = UI.list;
					for (int j = 0; j < list.size(); j++) {
						// 停在线程,并且去掉最后一个圆
						list.get(j).stopThread();
						list.get(j).fadeOval();

					}
					stopThread();
					showDialog();
				}
			}

		}

	}

	/**
	 * 线程结束时消去最后一个圆的方法
	 */
	public void fadeOval() {
		g.setColor(java.awt.Color.black);
		g.fillOval(x, y, width, height);
	}

	/**
	 * 重来对话框的处理方法
	 */
	public void isAgain() {
		isexist = false;
		list = UI.list;
		System.out.println(list.size());

		for (int j = 0; j < list.size(); j++) {
			// 停在线程,并且去掉最后一个圆
			list.get(j).stopThread();
			list.get(j).fadeOval();

		}
		Object[] options = { "是", "否" };
		String command = UI.getCommand();
		response = JOptionPane.showOptionDialog(null,
				"哈哈,你输了!不要灰心\n坚持就是胜利,是否再来一次?", null, JOptionPane.YES_OPTION,
				JOptionPane.NO_OPTION, null, options, null);

		System.out.println(response);
		if (response == 0) {
			if (command.equals("简单") || command.equals("开始")) {
				AgainThread();
				if (list.size() != 0) {
					// 现将原来的对象从队列中移除
					list.removeAll(list);
					UI.creatBall(20, 1);
				}

			}
			if (command.equals("中等")) {
				AgainThread();
				if (list.size() != 0) {
					list.removeAll(list);
					UI.creatBall(50, 2);
				}

			}

			if (command.equals("困难")) {
				AgainThread();
				if (list.size() != 0) {
					list.removeAll(list);
					UI.creatBall(40, 2);
				}
			}
		}

		// 如果点击关闭,则将线程对象从队列中移除
		if (response == -1 || response == 1) {
			list.removeAll(list);
		}

	}

	/**
	 * 停止线程的方法
	 */
	public void stopThread() {
		isFinish = false;
		isPause = false;

	}

	/**
	 * 暂停线程的方法
	 */
	public void PauseThread() {
		isPause = false;

	}

	/**
	 * 继续线程的方法
	 */
	public void ContinueThread() {

		isPause = true;

	}

	/**
	 * 是否重来的方法
	 */
	public void AgainThread() {
		isFinish = true;
		isPause = true;

	}

	public void getColors() {

		if (x % 2 == 0 && y % 2 == 0) {
			color = java.awt.Color.green;
		}
		if (x % 2 == 0 && y % 2 != 0) {
			color = java.awt.Color.red;
		}
		if (x % 2 != 0 && y % 2 != 0) {

			color = java.awt.Color.orange;

		}
		if (x % 2 != 0 && y % 2 != 0) {
			color = java.awt.Color.yellow;
		}
	}

	public void showDialog() {

		javax.swing.JOptionPane
				.showInputDialog("好样的,你是真的高手,\n恭喜你坚持了100s\n请输入您的大名");
	}

}
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;

/**
 * 鼠标监听器的类
 * 
 * @author Administrator
 * 
 */
public class MyListener extends java.awt.event.MouseAdapter {
	private java.awt.Graphics g;
	private int x = 5, y = 620;
	private int width = 100, height = 10;

	public MyListener(java.awt.Graphics g) {
		this.g = g;
	}

	public void mouseMoved(MouseEvent e) {
		// 设置画布对象颜色
		synchronized (this.g) {
			g.setColor(java.awt.Color.black);
			g.fillRect(x, y, width, height);
			x = e.getX();
			g.setColor(java.awt.Color.green);
			g.fillRect(x, y, width, height);
		}
	}

	/**
	 * 得到x的方法
	 * 
	 * @return:x
	 */
	public int getX() {
		return x;
	}

}

界面效果图:

 

Java 多线程的利用(弹球小游戏)_第1张图片
 
好了,大家看到了,线程的作用就是在一个程序中可以同时做不、同的事,就像上面的 弹球游戏,它可以在画矩形的同时画圆,两个可以同时发生,当选择难度时可以看都,可以同时画多个球。 

你可能感兴趣的:(Swing)