📄 ball.java
字号:
package day03.table_ball;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
/**
* 小球类,代表在画布上移动的小球
* @author Administrator
*
*/
public class Ball{
private double speetX=0.0;
private double speetY=0.0;
private double MOCHAX=0.02;
private double MOCHAY=0.02;
private Component canvas;//画布
private Color color;//小球的颜色
private int XSIZE = 25;//小球的X直径
private int YSIZE = 25;//小球的Y直径
private double bx=0; //小球所处的座标
private double by=0;
private double xx; //圆心点坐标
private double yy;
private double dx; //小球每次移动的步长
private double dy;
private String txt=null;
private double Dsize=10;
public Ball(Component c) { canvas = c; }
public Ball(double bx,double by,Component c, Color color,String txt) {
canvas = c;
this.txt=txt;
this.bx=bx;
this.by=by;
xx=bx+(XSIZE/2);
yy=by+(YSIZE/2);
this.color = color;
}
/**
* 根据x,y座标绘制当前小球
* @param g2
*/
public void draw(Graphics2D g2) {
if(color != null) g2.setColor(color);
g2.fill(new Ellipse2D.Double(bx, by, XSIZE, YSIZE));
g2.setColor(Color.white);
g2.drawString(txt, (int)xx-4, (int)yy+4);
}
/**
* 该方法控制小球的移动动作。移动小球其实就是把小球的座标位置改变一下,再调用画布的repaint方法。
*
*/
public synchronized void move(){
// if(dx!=0||dy!=0){
// System.out.println(Thread.currentThread().getName()+" dx "+dx);
// System.out.println(Thread.currentThread().getName()+" dy "+dy);
// }
if((xx-XSIZE/2-15<Dsize&&yy-YSIZE/2-25<Dsize) //左上角
||(xx-XSIZE/2-15<Dsize&&Math.abs(yy-(canvas.getHeight()-YSIZE/2)+25)<Dsize) //左下角
||(Math.abs(xx-canvas.getWidth()+XSIZE/2+20)<Dsize&&yy-YSIZE/2-20<Dsize) //右上角
||(Math.abs(xx-canvas.getWidth()+XSIZE/2+20)<Dsize&&Math.abs(yy-canvas.getHeight()+YSIZE/2+20)<Dsize) //右下角
||(Math.abs(xx-canvas.getWidth()/2)<Dsize&&yy-YSIZE/2-20<Dsize) //上中
||(Math.abs(xx-canvas.getWidth()/2)<Dsize&&Math.abs(yy-canvas.getHeight()+YSIZE/2)-20<Dsize)){ //下中
if(txt.equals("0")){
xx=650;
yy=185;
bx=xx-XSIZE/2;
by=yy-YSIZE/2;
dx=0;
dy=0;
}else{
BallFrame.labQiu.setText(BallFrame.labQiu.getText()+txt+" || ");
YSIZE=0;
XSIZE=0;
Thread.currentThread().stop();
((BallPanel)canvas).getBalls().remove(this);
}
}
bx += dx; by += dy;
xx=bx+(XSIZE/2);
yy=by+(YSIZE/2);
if(!((xx-XSIZE/2-15<Dsize&&yy-YSIZE/2-25<Dsize) //左上角
||(xx-XSIZE/2-15<Dsize&&Math.abs(yy-(canvas.getHeight()-YSIZE/2)+25)<Dsize) //左下角
||(Math.abs(xx-canvas.getWidth()+XSIZE/2+20)<10&&yy-YSIZE/2-25<Dsize) //右上角
||(Math.abs(xx-canvas.getWidth()+XSIZE/2+20)<10&&Math.abs(yy-canvas.getHeight()+YSIZE/2+20)<Dsize) //右下角
||(Math.abs(xx-canvas.getWidth()/2)<Dsize&&yy-YSIZE/2-20<Dsize) //上中
||(Math.abs(xx-canvas.getWidth()/2)<Dsize&&Math.abs(yy-canvas.getHeight()+YSIZE/2)-20<Dsize))){
if (bx -20< 0){ bx = 20; dx = -dx; }
if ((bx + XSIZE-canvas.getWidth()+20)>0){ bx = canvas.getWidth()-20 - XSIZE; dx = -dx; }
if (by -30< 0){ by = 30; dy = -dy; }
if (by + YSIZE >= canvas.getHeight()-30) { by = canvas.getHeight()-30 - YSIZE; dy = -dy; }
// canvas.repaint();
for(int i=0;i<((BallPanel)canvas).getBalls().size();i++){
Ball penBall=((Ball)((BallPanel)canvas).getBalls().get(i));
double xx2=penBall.getXx();
double yy2=penBall.getYy();
double juLiX = (xx)-(xx2);
double juLiY = (yy)-(yy2);
double juLi=Math.sqrt(juLiX*juLiX+juLiY*juLiY);
//System.out.println("JILI "+juLi);
if(this!=penBall&&juLi<XSIZE){
double fx = juLiX/juLi; // 法线单位向量
double fy = juLiY/juLi;
double faktorback = (2*XSIZE)/juLi;
double skalarp = (dx*fx+dy*fy)-((penBall.getDx())*fx+(penBall.getDy())*fy); // 求法线上的合速度值
double Kraftx = fx * skalarp; // 再分解为合速度向量
double Krafty = fy * skalarp;
(xx2)=(xx)-juLiX*faktorback; // 把一个球回退到接触点,另一个却不退
(yy2)=(yy)-juLiY*faktorback;
(dx) = (dx - Kraftx); // 减掉法线上的速度,剩下切线上的速度!
(dy) = (dy - Krafty);
penBall.setDx(penBall.getDx() + Kraftx);
penBall.setDy(penBall.getDy() + Krafty);
}
}
canvas.repaint();
}
canvas.repaint();
new MoChaRun().start();
}
public double getXx() {
return xx;
}
public double getYy() {
return yy;
}
public void setXSIZE(int xsize) {
XSIZE = xsize;
}
public void setYSIZE(int ysize) {
YSIZE = ysize;
}
public void setDx(double dx) {
this.dx = dx;
speetX=dx;
}
public double getDx() {
return dx;
}
public double getDy() {
return dy;
}
public void setDy(double dy) {
this.dy = dy;
speetY=dy;
}
public void setSpeetX(double speetX) {
this.speetX = speetX;
}
public void setSpeetY(double speetY) {
this.speetY = speetY;
}
class MoChaRun extends Thread{
@Override
public void run() {
//System.out.println(Thread.currentThread().getName());
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(dx>0){
dx-=Math.abs(MOCHAX*speetX);
if(dx<1){
dx=0;
}
}else if(dx<0){
dx+=Math.abs(MOCHAX*speetX);
if(dx>-1){
dx=0;
}
}
if(dy>0){
dy-=Math.abs(MOCHAY*speetY);
if(dy<1){
dy=0;
}
}else if(dy<0){
dy+=Math.abs(MOCHAY*speetY);
if(dy>-1){
dy=0;
}
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -