用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字
云代码 - java代码库

Java桌球游戏——模拟桌球打击处理及绘制

2013-01-01 作者: 小蜜锋举报

[java]代码库

import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Panel;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;

/** */
/**
 * <p>
 * Title: LoonFramework
 * </p>
 * <p>
 * Description:Java桌球演示
 * </p>
 * <p>
 * Copyright: Copyright (c) 2007
 * </p>
 * <p>
 * Company: LoonFramework
 * </p>
 * http://cping1982.blog.51cto.com/601635/130098
 * @author chenpeng
 * @email:ceponline@yahoo.com.cn
 * @version 0.1
 */

public class JavaBilliards extends Panel implements Runnable, MouseListener,
		MouseMotionListener {

	/** */
	/**
     * 
     */
	private static final long serialVersionUID = -5019885590391523441L;

	// 球
	private double _ball;

	// 缓存用背景
	private Image _screen;

	// 画布
	private Graphics _graphics;

	// 台桌
	private Image _table;

	private double c[];

	private double d[];

	private double e[];

	private double f[];

	private int countBall;

	private int h;

	private double i[];

	private double j[];

	private double k[];

	private double l[];

	private double m[];

	private double n[];

	private double o[];

	private double p[];

	private boolean q[];

	private double r;

	private int a;

	private int u;

	private int v;

	private int w;

	private int x;

	private boolean y;

	private int z;

	private int A;

	/** */
	/**
	 * 初始化
	 * 
	 */
	public JavaBilliards() {
		a = 0;
		r = 10D;
		z = 300;
		A = 0;
		setBounds(50, 50, 700, 350);
		Frame frame = new Frame("Java桌球演示");
		frame.add(this);
		frame.setBounds(0, 0, 700, 380);
		frame.setResizable(false);
		frame.setVisible(true);
		frame.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		requestFocus();
		initialize();
	}

	public void initialize() {
		// 基础数据
		base();
		// 注入实例
		immit();
		// 缓存背景
		_screen = new BufferedImage(this.getWidth(), this.getHeight(), 1);
		// 背景图形
		_graphics = _screen.getGraphics();
		// 绘制台桌
		makeTable();
		// 设置监听
		addMouseListener(this);
		addMouseMotionListener(this);
		// 启动
		new Thread(this).start();
	}

	/** */
	/**
	 * 初始化数据
	 * 
	 */
	public void base() {

		// 球体
		_ball = 16D;
		c = (new double[] { 40D, (double) (getWidth() - 40) });
		d = (new double[] { c[0], (double) getHeight() - c[0] });
		e = (new double[] { c[0] + 20D, (double) (getWidth() / 2), c[1] - 20D });
		f = (new double[] { d[0] + 20D, d[1] - 20D });
	}

	/** */
	/**
	 * 注入实例
	 * 
	 */
	public void immit() {
		countBall = 16;
		i = new double[countBall];
		j = new double[countBall];
		k = new double[countBall];
		l = new double[countBall];
		m = new double[countBall];
		n = new double[countBall];
		o = new double[countBall];
		p = new double[countBall];
		q = new boolean[countBall];
		// 打击对象
		hitObject();
		// 打击用球
		hitBall();
	}

	/** */
	/**
	 * 打击用球数值
	 * 
	 */
	public void hitBall() {
		i[0] = (1.0D * (e[2] - e[0])) / 3D;
		j[0] = this.getHeight() / 2;
		k[0] = 0.0D;
		l[0] = 0.0D;
		q[0] = true;
	}

	/** */
	/**
	 * 打击对象
	 * 
	 */
	public void hitObject() {
		int il = 1;
		h = countBall - 1;
		// 求平方根
		double dl = Math.sqrt(3.5D);
		for (int j1 = 0; j1 < 5; j1++) {
			double d2 = ((double) getWidth() * 2D) / 3D + (double) j1 * dl * r;
			double d3 = (double) (getHeight() / 2) - (double) j1 * r;
			for (int k1 = 0; k1 <= j1; k1++) {
				i[il] = d2;
				j[il] = d3;
				k[il] = 0.0D;
				l[il] = 0.0D;
				q[il] = true;
				d3 += 2D * r;
				il++;
			}

		}

	}

	/** */
	/**
	 * 绘制台球桌
	 * 
	 */
	public void makeTable() {
		_table = new BufferedImage(this.getWidth(), this.getHeight(), 1);
		Graphics g = _table.getGraphics();
		g.setColor(Color.GRAY);
		g.fillRect(0, 0, getWidth(), getHeight());
		g.setColor((new Color(200, 100, 50)).darker());
		g.fill3DRect((int) c[0], (int) d[0], (int) (c[1] - c[0]),
				(int) (d[1] - d[0]), true);
		g.setColor(Color.BLACK);
		g.fill3DRect((int) e[0], (int) f[0], (int) (e[2] - e[0]),
				(int) (f[1] - f[0]), false);
		g.setColor(Color.GREEN.darker());
		g.drawLine((int) ((1.0D * (e[2] - e[0])) / 3D), (int) f[0],
				(int) ((1.0D * (e[2] - e[0])) / 3D), (int) f[1]);
		g.fillOval((int) ((1.0D * (e[2] - e[0])) / 3D) - 2,
				(int) ((f[1] + f[0]) / 2D) - 2, 4, 4);
		g.drawArc((int) ((1.0D * (e[2] - e[0])) / 3D) - 20,
				(int) ((f[1] + f[0]) / 2D) - 20, 40, 40, 90, 180);
		g.setColor(Color.BLACK);
		double d1 = _ball - 2D;
		for (int i1 = 0; i1 < 3; i1++) {
			for (int j1 = 0; j1 < 2; j1++) {
				g.fillOval((int) (e[i1] - d1), (int) (f[j1] - d1),
						(int) (2D * d1), (int) (2D * d1));
			}
		}
	}

	/** */
	/**
	 * 线程处理
	 */
	public void run() {
		long timeStart;
		timeStart = System.currentTimeMillis();
		// 死循环反复处理
		for (;;) {
			long timeEnd = System.currentTimeMillis();
			switch (a) {
			default:
				break;

			case 1:
				// 根据时间换算运动轨迹
				conversion(timeEnd - timeStart);
				// 过程处理
				course();
				break;

			case 2:
				conversion(timeEnd - timeStart);
				// 过程处理
				course();
				boolean flag = true;
				for (int i1 = 0; flag && i1 < countBall; i1++)
					flag = k[i1] == 0.0D && l[i1] == 0.0D;

				if (flag) {
					a = 1;
					// 击球
					if (!q[0]) {
						hitBall();
					}
				}
				if (h == 0)
					a = 3;
				break;

			case 3:
				hitObject();
				hitBall();
				a = 0;
				break;
			}

			repaint();
			timeStart = timeEnd;
			try {
				Thread.sleep(10L);
			} catch (InterruptedException e1) {
				e1.printStackTrace();
			}
		}

	}

	public void course() {
		// 限制区域
		limit();
		// 入袋处理
		pocket();
		// 运动演算
		play();
		for (int i1 = 0; i1 < countBall; i1++)
			if (q[i1]) {
				i[i1] = m[i1];
				j[i1] = n[i1];
			}
	}

	/** */
	/**
	 * 变换时间为动作数据
	 * 
	 * @param value
	 */
	public void conversion(long value) {
		double d1 = (double) value / 1000D;
		for (int i1 = 0; i1 < countBall; i1++)
			if (q[i1]) {
				m[i1] = i[i1] + k[i1] * d1;
				n[i1] = j[i1] + l[i1] * d1;
				k[i1] *= 0.98999999999999999D;
				l[i1] *= 0.98999999999999999D;
				if (Math.abs(Math.hypot(k[i1], l[i1])) < 2D) {
					k[i1] = 0.0D;
					l[i1] = 0.0D;
				}
			}

	}

	public void pocket() {
		for (int i1 = 0; i1 < countBall; i1++)
			if (q[i1]) {
				for (int j1 = 0; j1 < 3; j1++) {
					for (int k1 = 0; k1 < 2; k1++)
						if (Math.hypot(e[j1] - i[i1], f[k1] - j[i1]) < _ball) {
							q[i1] = false;
							if (i1 != 0) {
								h--;
							}
							k[i1] = 0.0D;
							l[i1] = 0.0D;
						}

				}

			}

	}

	public void play() {
		for (int i1 = 0; i1 < countBall; i1++)
			if (q[i1]) {
				for (int j1 = i1 + 1; j1 < countBall; j1++) {
					boolean flag;
					if (q[j1] && (flag = randball(i1, j1))) {
						for (int k1 = 0; k1 < 10 && flag; k1++) {
							m[i1] = (m[i1] + i[i1]) / 2D;
							n[i1] = (n[i1] + j[i1]) / 2D;
							m[j1] = (m[j1] + i[j1]) / 2D;
							n[j1] = (n[j1] + j[j1]) / 2D;
							flag = randball(i1, j1);
						}

						if (flag) {
							m[i1] = i[i1];
							n[i1] = j[i1];
							m[j1] = i[j1];
							n[j1] = j[j1];
						}
						double d1 = m[j1] - m[i1];
						double d2 = n[j1] - n[i1];
						double d3 = Math.hypot(m[i1] - m[j1], n[i1] - n[j1]);
						double d4 = d1 / d3;
						double d5 = d2 / d3;
						o[j1] = k[j1] - k[j1] * d4 * d4;
						o[j1] -= l[j1] * d4 * d5;
						o[j1] += k[i1] * d4 * d4;
						o[j1] += l[i1] * d4 * d5;
						p[j1] = l[j1] - l[j1] * d5 * d5;
						p[j1] -= k[j1] * d4 * d5;
						p[j1] += k[i1] * d4 * d5;
						p[j1] += l[i1] * d5 * d5;
						o[i1] = k[i1] - k[i1] * d4 * d4;
						o[i1] -= l[i1] * d4 * d5;
						o[i1] += k[j1] * d4 * d4;
						o[i1] += l[j1] * d4 * d5;
						p[i1] = l[i1] - l[i1] * d5 * d5;
						p[i1] -= k[i1] * d4 * d5;
						p[i1] += k[j1] * d4 * d5;
						p[i1] += l[j1] * d5 * d5;
						k[i1] = o[i1];
						l[i1] = p[i1];
						k[j1] = o[j1];
						l[j1] = p[j1];
					}
				}

			}

	}

	public boolean randball(int i1, int j1) {
		// hypot随机决定两值之一
		return Math.hypot(m[i1] - m[j1], n[i1] - n[j1]) < 2D * r;
	}

	/** */
	/**
	 * 限制区域
	 * 
	 */
	public void limit() {
		for (int i = 0; i < countBall; i++)
			if (q[i]) {
				if (m[i] - r < e[0]) {
					m[i] = e[0] + r;
					k[i] *= -1D;
				} else if (m[i] + r > e[2]) {
					m[i] = e[2] - r;
					k[i] *= -1D;
				}
				if (n[i] - r < f[0]) {
					n[i] = f[0] + r;
					l[i] *= -1D;
				} else if (n[i] + r > f[1]) {
					n[i] = f[1] - r;
					l[i] *= -1D;
				}
			}

	}

	public void makeScreen(Graphics screenGraphics) {

		screenGraphics.drawImage(_table, 0, 0, null);
		if (q[0]) {
			_graphics.setColor(Color.WHITE);
			_graphics.fillOval((int) (i[0] - r), (int) (j[0] - r),
					(int) (r * 2D), (int) (r * 2D));
		}
		screenGraphics.setColor(Color.RED);
		for (int i1 = 1; i1 < countBall; i1++)
			if (q[i1])
				screenGraphics.fillOval((int) (i[i1] - r), (int) (j[i1] - r),
						(int) (r * 2D), (int) (r * 2D));

		screenGraphics.setColor(Color.BLACK);
		for (int j1 = 0; j1 < countBall; j1++)
			if (q[j1]) {
				screenGraphics.drawOval((int) (i[j1] - r), (int) (j[j1] - r),
						(int) (r * 2D), (int) (r * 2D));
			}

		if (a == 1) {
			makeHelper(screenGraphics);
		}
		if (a == 0) {
			int k1 = getWidth() / 2 - 85;
			int l1 = getHeight() / 2;
			screenGraphics.setColor(Color.BLACK);
			screenGraphics.drawString("点击画面开始", k1 + 2, l1 + 2);
			if ((System.currentTimeMillis() / 1000L & 1L) == 0L) {
				screenGraphics.setColor(Color.YELLOW);
			} else {
				screenGraphics.setColor(Color.CYAN);
			}
			screenGraphics.drawString("点击画面开始", k1, l1);
		}
	}

	/** */
	/**
	 * 绘制球杆及辅助线
	 * 
	 * @param screenGraphics
	 */
	public void makeHelper(Graphics screenGraphics) {
		double d1 = Math.hypot(i[0] - (double) u, j[0] - (double) v);
		double d2 = ((double) u - i[0]) / d1;
		double d3 = ((double) v - j[0]) / d1;
		double d4 = y ? n() / 10D : 1.0D;
		double d5 = i[0] + d2 * (r + d4);
		double d6 = i[0] + d2 * (r + (double) z + d4);
		double d7 = j[0] + d3 * (r + d4);
		double d8 = j[0] + d3 * (r + (double) z + d4);
		screenGraphics.setColor(Color.ORANGE);
		screenGraphics.drawLine((int) d5, (int) d7, (int) d6, (int) d8);
		int i1 = 0;
		int j1 = y ? (int) (150D * (d4 / 1000D)) : 15;
		double d9;
		double d10 = (d9 = 30D) * d2;
		double d11 = d9 * d3;
		double d12 = i[0] + (double) A * d2;
		double d13 = j[0] + (double) A * d3;
		A--;
		A %= d9;
		screenGraphics.setColor(Color.WHITE);
		for (; i1 < j1; i1++) {
			if (d12 < e[0]) {
				d12 = e[0] - d12;
				d12 = e[0] + d12;
				d10 *= -1D;
			} else if (d12 > e[2]) {
				d12 -= e[2];
				d12 = e[2] - d12;
				d10 *= -1D;
			}
			if (d13 < f[0]) {
				d13 = f[0] - d13;
				d13 = f[0] + d13;
				d11 *= -1D;
			} else if (d13 > f[1]) {
				d13 -= f[1];
				d13 = f[1] - d13;
				d11 *= -1D;
			}
			screenGraphics.fillOval((int) d12 - 2, (int) d13 - 2, 4, 4);
			d12 -= d10;
			d13 -= d11;
		}

	}

	public double n() {
		if (y) {
			return Math.min(1000D,
					10D * Math.hypot(i[0] - (double) w, j[0] - (double) x));
		} else {
			return Math.min(1000D, 10D * Math.hypot(u - w, v - x));
		}
	}

	public void update(Graphics g) {
		paint(g);
	}

	public void paint(Graphics g) {
		makeScreen(_graphics);
		g.drawImage(_screen, 0, 0, null);
	}

	public void mousePressed(MouseEvent mouseevent) {
		y = true;
	}

	public void mouseReleased(MouseEvent mouseevent) {
		if (a == 1) {
			double d1 = Math.hypot(i[0] - (double) u, j[0] - (double) v);
			double d2 = (i[0] - (double) u) / d1;
			double d3 = (j[0] - (double) v) / d1;
			double d4;
			if ((d4 = n()) > 0.0D) {
				a = 2;
				k[0] = d4 * d2;
				l[0] = d4 * d3;
			}
		}
		y = false;
	}

	public void mouseClicked(MouseEvent mouseevent) {
		if (a == 0)
			a = 1;
	}

	public void mouseEntered(MouseEvent mouseevent) {
	}

	public void mouseExited(MouseEvent mouseevent) {
	}

	public void mouseMoved(MouseEvent mouseevent) {
		w = mouseevent.getX();
		x = mouseevent.getY();
		u = w;
		v = x;
	}

	public void mouseDragged(MouseEvent mouseevent) {
		w = mouseevent.getX();
		x = mouseevent.getY();
	}

	public static void main(String args[]) {
		new JavaBilliards();
	}

}

[代码运行效果截图]


Java桌球游戏——模拟桌球打击处理及绘制


网友评论    (发表评论)

共2 条评论 1/1页

发表评论:

评论须知:

  • 1、评论每次加2分,每天上限为30;
  • 2、请文明用语,共同创建干净的技术交流环境;
  • 3、若被发现提交非法信息,评论将会被删除,并且给予扣分处理,严重者给予封号处理;
  • 4、请勿发布广告信息或其他无关评论,否则将会删除评论并扣分,严重者给予封号处理。


扫码下载

加载中,请稍后...

输入口令后可复制整站源码

加载中,请稍后...