⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 billiardball.java~

📁 java桌球游戏java桌球游戏java桌球游戏java桌球游戏
💻 JAVA~
📖 第 1 页 / 共 2 页
字号:
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.net.*;
import java.awt.image.*;
import javax.imageio.*;
import java.io.*;
import java.applet.*;
import java.util.Timer;


public class BilliardBall extends JFrame {

	public static final int GAME_WIDTH  = 800;
	public static final int GAME_HEIGHT = 600;

	public Image offScreenImage = null;
	public Graphics bg = null;
	public TablePanel pTable = null;
	public ProcessPanel pInfo = null;

	public BilliardBall() {
		pInfo = new ProcessPanel();
		pTable = new TablePanel(this);  // 暂时, 就这么设为.
	}
	
	public void launchFrame() {
		setTitle("台球游戏");
		setSize(GAME_WIDTH, GAME_HEIGHT);
		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		setLayout(null);
		pTable.setBounds(100, 50, pTable.TABLE_WIDTH, pTable.TABLE_HEIGHT);
		add(pTable);
		pInfo.setBounds(100, 400, pInfo.PROCESS_WIDTH, pInfo.PROCESS_HEIGHT);
		add(pInfo);
		pInfo.addStartActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				pTable.gameStart();
			}
		});
		setResizable(false);
		setVisible(true);
		new PaintThread().start();
	}

	public void update(Graphics g) {
		if ( offScreenImage == null ) {
			offScreenImage = createImage(GAME_WIDTH, GAME_HEIGHT);
		}
		bg = offScreenImage.getGraphics();
		Color c = bg.getColor();
		bg.setColor(Color.WHITE);
		bg.fillRect(0, 0, GAME_WIDTH - 1, GAME_HEIGHT - 1);
		paint(bg);
		bg.setColor(c);	
		g.drawImage(offScreenImage, 0, 0, null);
	}

	public void paint(Graphics g) {
		super.paint(g);
		Color c = g.getColor();
		// add code here: to draw many ball with movement;
		g.setColor(c);
	}

	public int getPower() {
		return pInfo.getPower();
	}

	//change
	public void initialPower() {
		pInfo.initialPower();
	}

	public void updatePower() {
		pInfo.updatePower();	
	}

	public void addScore() {
		pInfo.addScore();
	}

	public void initScore() {
		pInfo.initScore();
	}

	public static void main(String[] args) {
		new BilliardBall().launchFrame();	
	}
	
	private class PaintThread extends Thread {
		public static final int INTERVAL = 80;
		public void run() {
			while ( true ) {
				try {
					Thread.sleep(INTERVAL); //
					pTable.move();
					update(getGraphics());  // 当然 repaint() 这个函数也是行的.
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}	

}

// 就一个球而言, 其应该储存什么信息?
class Ball {  // 封装信息: ball之间.

	public static final double EPS = 0.01;
	public static final int    SLICE = 45;
	public static final int    OFFSET = 16;
	public static final double PROBABILITY = 2.0;

	public Color color = null;
	public double x, y, radian;
	public double vx, vy; // 这里的vx, vy 表示运动矢量.
	public BufferedImage picture = null;
	public boolean live = false;

	public Ball() {
	//	x = y = 50;	
	//	vx = vy = 0;
		live = true;
		setData(150, 150, 0, 0);
		radian = 10;
		color = Color.WHITE;
		picture = ImageLoader.getIndexOf(0);
	}	

	public Ball(double x, double y, Color color) {
		live = true;
		setData(x, y, 0, 0);
		radian = 10;
		this.color = color;
		if ( color != Color.WHITE ) {
			picture = ImageLoader.getIndexOf(1);
		}
	}
	
	public void draw(Graphics g) {
		if ( isLive() == true ) {
			Color c = g.getColor();
			g.setColor(color);
		//g.fillOval((int)(x - radian + 0.5), (int)(y - radian + 0.5), (int)(radian * 2 + 0.5), (int)(radian * 2 + 0.5));		
			g.drawImage(picture, (int)(x - radian + 0.5), (int)(y - radian + 0.5), null);
			g.setColor(c);
		}
	}

	public boolean isHited(Point p) {  // 这个是正方形包含, 
	//	if ( p.x == x && p.y == y ) return false;
		return (p.x >= x - radian && p.x <= x + radian && p.y >= y - radian && p.y <= y + radian); 
	}

	public void setData(double x, double y, double vx, double vy) {
		this.x = x;
		this.y = y;
		this.vx = vx;
		this.vy = vy;
	}	

	public void setData(int value, Point p) {
		
		double spring = Math.sqrt((p.x - x) * (p.x - x) + (p.y - y) * (p.y - y));
	//	System.out.println("Spring:" + spring);
		vx = (p.x - x) / spring * value * 25;
		vy = (p.y - y) / spring * value * 25;
	//	System.out.println("vx:" + vx + " vy: " + vy);

	}

	public void setProperty(double x, double y, Color c) {
		this.x = x;
		this.y = y;
		this.color = c;
		vx = vy = 0;
		if  ( color != Color.WHITE )
			picture = ImageLoader.getIndexOf(1);
		else
			picture = ImageLoader.getIndexOf(0);
	}
	// 恐怕 这里的速度需要测试出来.
	public void forward() {

	}

	public boolean isStayed() {
		if ( Math.abs(vx) <= EPS && Math.abs(vy) <= EPS ) {
			vx = vy = 0;
			return true;
		}
		return false;
	}

	public boolean isTouched(double x1, double y1, double x2, double y2) {
		double dist = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
		return dist < 2 * radian;
	}
	
	public boolean isLive() {
		return live;
	}

	public void setLive(boolean live) {
		this.live = live;
	}
 
	public int collides(Ball s) {
		int step = 1;
		double px, py, nx, ny;
		double tx1, ty1, cx1, cy1;
		double tx2, ty2, cx2, cy2;

		if ( isStayed() == true && s.isStayed() == true ) 
			return SLICE;
		if ( isStayed() == true ) {
			px = py = 0;
		} else  {
			px = vx / Math.sqrt(vx * vx + vy * vy);
			py = vy / Math.sqrt(vx * vx + vy * vy);
		}
		if ( s.isStayed() == true ) {
			nx = 0; ny = 0;
		} else {
		       	nx = s.vx / Math.sqrt(s.vx * s.vx + s.vy * s.vy);
		       	ny = s.vy / Math.sqrt(s.vx * s.vx + s.vy * s.vy);
		}
//tx = mBall.vx - (mBall.vx * (mstep - step) / spring);
		while ( step < SLICE ) { 	
			tx1 = vx - step * px;
			ty1 = vy - step * py;
			if ( (tx1 > 0 && vx < 0) || (tx1 < 0 && vx > 0) ) tx1 = 0.0;
			if ( (ty1 > 0 && vy < 0) || (ty1 < 0 && vy > 0) ) ty1 = 0.0;
			cx1 = x + step * (vx + tx1) / 2000.0;
			cy1 = y + step * (vy + ty1) / 2000.0;
			
			tx2 = s.vx - step * nx;
			ty2 = s.vy - step * ny;
			if ( (tx2 > 0 && vx < 0) || (tx2 < 0 && vx > 0) ) tx2 = 0.0;
			if ( (ty2 > 0 && vy < 0) || (ty2 < 0 && vy > 0) ) ty2 = 0.0;
			cx2 = s.x + step * (s.vx + tx2) / 2000.0;
			cy2 = s.y + step * (s.vy + ty2) / 2000.0;
			if ( isTouched(cx1, cy1, cx2, cy2) == true ) break; // 表接触
			step++;
		}
		return step;
	}
	
	public int collidesWall(int width, int height) {
		int step = 1;
		double px = 0, py = 0, tx = 0, ty = 0, cx = 0, cy = 0;
		if ( isStayed() == true ) return SLICE;
		px = vx / Math.sqrt(vx * vx + vy * vy);
		py = vy / Math.sqrt(vx * vx + vy * vy);
		while ( step < SLICE ) {
			tx = vx - step * px;
			ty = vy - step * py;
			if ( (tx > 0 && vx < 0) || (tx < 0 && vx > 0) ) tx = 0.0;
			if ( (ty > 0 && vy < 0) || (ty < 0 && vy > 0) ) ty = 0.0;
			cx = x + step * (vx + tx) / 2000.0;
			cy = y + step * (vy + ty) / 2000.0;
			if ( cx - radian <= 0 + OFFSET || cx + radian >= width - OFFSET 
					|| cy - radian <= 0 + OFFSET || cy + radian >= height - OFFSET ) {
			       
				if ( isSpecial(cx, cy, width, height) == false ) break; 
			}
			step++;
		}	
		return step;
	}

	public boolean isSpecial(double cx, double cy, int width, int height) {  // 增强真实感,(1) 进洞.
		
		double r1 = OFFSET, r2 = (width - 2 * OFFSET) / 2;
		for ( int i = 0; i < 3; i++ ) {
			if ( Math.sqrt((cx - r2 * i - OFFSET) * (cx - r2 * i - OFFSET) + (cy - r1) * (cy - r1)) < radian * PROBABILITY )
				return true;
		}
		r1 = height - OFFSET;
		for ( int i = 0; i < 3; i++ ) {
			if ( Math.sqrt((cx - r2 * i - OFFSET) * (cx - r2 * i - OFFSET) + (cy - r1) * (cy - r1)) < radian * PROBABILITY )
				return true;
		}
		return false;

	}

	public int collidesHole(int width, int height) {
		int step = 1;
		double px = 0, py = 0;
	       	double tx = 0, ty = 0;
		double cx = 0, cy = 0;
		double r1 = 0, r2 = 0;
		if ( isStayed() == true ) return SLICE;
		px = vx / Math.sqrt(vx * vx + vy * vy);
		py = vy / Math.sqrt(vx * vx + vy * vy);	
		while ( step < SLICE ) {
			tx = vx - step * px;
			ty = vy - step * py;
			if ( (tx > 0 && vx < 0) || (tx < 0 && vx > 0) ) tx = 0.0;
			if ( (ty > 0 && vy < 0) || (ty < 0 && vy > 0) ) ty = 0.0;
			cx = x + step * (vx + tx) / 2000.0;
			cy = y + step * (vy + ty) / 2000.0;
			r1 = OFFSET; r2 = (width - 2 * OFFSET) / 2;
			for ( int i = 0; i < 3; i++ ) {
			   //    	double tvalue = Math.sqrt((cx - r2 * i) * (cx - r2 * i) + (cy - r1) * (cy - r1));	
			//	System.out.println("tvalue :" + tvalue + ":radian2" + (radian * 2));
				if ( Math.sqrt((cx - r2 * i - OFFSET) * (cx - r2 * i - OFFSET) + (cy - r1) * (cy - r1)) < radian * PROBABILITY )
					return step;
			}
			r1 = height - OFFSET;
			for ( int i = 0; i < 3; i++ ) {
			 //      	double tvalue = Math.sqrt((cx - r2 * i) * (cx - r2 * i) + (cy - r1) * (cy - r1));	
			//	System.out.println("tvalue :" + tvalue + ":radian2" + (radian * 2));
				if ( Math.sqrt((cx - r2 * i - OFFSET) * (cx - r2 * i - OFFSET) + (cy - r1) * (cy - r1)) < radian * PROBABILITY )
					return step;
			}
			step++;
		}
		return step;	

	}

	public void update(int step) {
		double px = 0, py = 0;
		double tx, ty, cx, cy;
		if ( isStayed() == true ) {
			px = py = 0;
		} else  {
			px = vx / Math.sqrt(vx * vx + vy * vy);
			py = vy / Math.sqrt(vx * vx + vy * vy);
		}
		tx = vx - step * px;
		ty = vy - step * py;
		if ( (tx > 0 && vx < 0) || (tx < 0 && vx > 0) ) tx = 0.0;
		if ( (ty > 0 && vy < 0) || (ty < 0 && vy > 0) ) ty = 0.0;
		cx = x + step * (vx + tx) / 2000.0;
		cy = y + step * (vy + ty) / 2000.0;
		setData(cx, cy, tx, ty);
	}

	public void changes(Ball s) {  // 这个函数, 则是碰撞反应的核心, 最重要的要防止粘滞住...
		
		double px, py;
		double ux1, uy1, ux2, uy2;
		double ux3, uy3, ux4, uy4;
		px = (s.x - x) / Math.sqrt((s.x - x) * (s.x - x) + (s.y - y) * (s.y - y));  // 这边是单位化
		py = (s.y - y) / Math.sqrt((s.x - x) * (s.x - x) + (s.y - y) * (s.y - y));

		ux1 = (px * vx + py * vy) * px;
		uy1 = (px * vx + py * vy) * py;
		ux2 = vx - ux1;
		uy2 = vy - uy1;
	
		ux3 = px * (px * s.vx + py * s.vy);
		uy3 = py * (py * s.vx + py * s.vy);
		ux4 = s.vx - ux3;
		uy4 = s.vy - uy3;

		vx = ux2 + ux3;
		vy = uy2 + uy3;

		s.vx = ux1 + ux4;
		s.vy = uy1 + uy4;
		
		// 还要恰当改变两球之间的距离.
		int step = 1;
		while ( true ) {
			x = x + step * vx / 1000.0;
			y = y + step * vy / 1000.0;
			s.x = s.x + step * s.vx / 1000.0;
			s.y = s.y + step * s.vy / 1000.0;
			if ( isTouched(x, y, s.x, s.y) == false ) break;
			if ( isStayed() == true && s.isStayed() == true && isTouched(x, y, s.x, s.y) == true ) { // 潜在的一个死循环.
				double p1 = (x - s.x) / Math.sqrt((s.x - x) * (s.x - x) + (s.y - y) * (s.y - y));
				double p2 = (y - s.y) / Math.sqrt((s.x - x) * (s.x - x) + (s.y - y) * (s.y - y));
				double p3 = (s.x - x) / Math.sqrt((s.x - x) * (s.x - x) + (s.y - y) * (s.y - y));
				double p4 = (s.y - y) / Math.sqrt((s.x - x) * (s.x - x) + (s.y - y) * (s.y - y));
				step = 1;
			//	System.out.println("I frame myself");
				while ( true ) {
					x = x + step * p1 / 200;
					y = y + step * p2 / 200;
					s.x = s.x + step * p3 / 200;
					s.y = s.y + step * p4 / 200;
					if ( isTouched(x, y, s.x, s.y) == false ) return;
					step++;
				}
			} 
			step++;
		}	


	}

	public void changesWall(int width, int height) {
		
		if ( x - radian <= 0 + OFFSET ) {
			x = radian + OFFSET;
			vx = -vx;
		} else if ( x + radian >= width - OFFSET ) {
			x = width - radian - OFFSET;
			vx = -vx;
		} 
		if ( y - radian <= 0 + OFFSET ) {
			y = radian + OFFSET;
			vy = -vy;
		} else if ( y + radian >= height - radian - OFFSET ) {
			y = height - radian - OFFSET;
			vy = -vy;
		}	

	}

	public Point changesHole(int width, int height) {  // 制作消失效果.
		
		double r1, r2;	
		setLive(false);	
		r1 = OFFSET; r2 = (width - 2 * OFFSET) / 2;
		for ( int i = 0; i < 3; i++ ) {
			if ( Math.sqrt((x - r2 * i - OFFSET) * (x - r2 * i - OFFSET) + (y - r1) * (y - r1)) < radian * PROBABILITY )
				return new Point((int)(r2 * i + OFFSET), (int)(r1));
		}
		r1 = height - OFFSET;
		for ( int i = 0; i < 3; i++ ) {
			if ( Math.sqrt((x - r2 * i - OFFSET) * (x - r2 * i - OFFSET) + (y - r1) * (y - r1)) < radian * PROBABILITY )
				return new Point((int)(r2 * i + OFFSET), (int)(r1));
		}
		return new Point(-100, -100);  // 若程序执行到这里,表明程序执行错误.

	}

	public String toString() {  // 这个toString() 用于调试用的.
		return "x: " + x + " y: " + y + " vx " + vx +  " vy " + vy;
	}

//	public boolean is
	//public synchronized ()
	// 当然也可以重载.
	// return .    Math.sqrt((p.x - x) * (p.x - x) + (p.y - y) * (p.y - y)) <= radian ;
	// return    (p.x - x) * (p.x - x) + (p.y - y) * (p.y - y) <= radian *radian;


}


class TablePanel extends JPanel {

	public static final int TABLE_WIDTH  = 600;
	public static final int TABLE_HEIGHT = 300;
	public static final int SLICE = 45;
	
	public static final int CWNULL = 0;   // 表没有碰撞的情况
	public static final int CWBALL = 1;   // 与球相碰
	public static final int CWWALL = 2;   // 与wall相碰
	public static final int CWHOLE = 3;   // 落入hole中 	 

//	public MouseMonitor mouseManager = null;
	public Point pTarget;
	public Ball  mBall;
	public boolean state = false;
	public boolean canFire = false;
	public boolean canPlace = true;
	public ArrayList<Ball> balls = null;
	public ArrayList<Tnode> flashs = null;
	public BufferedImage table = null;
	public BilliardBall parent = null;

	public TablePanel(BilliardBall parent) {
		this.parent = parent;
		table = ImageLoader.getBackground();
		balls = new ArrayList<Ball>();
		flashs = new ArrayList<Tnode>();
		initial();
		gameStart();
	//	balls.add(new Ball());  // 对Ball的构造函数进行修改.
		setSize(TABLE_WIDTH, TABLE_HEIGHT);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -