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;