@红薯 你好,想跟你请教个问题:
您好,看到这里您威望最高,所以想请教您啦。我用java写了一个类似于windows的屏保的多球运动,碰到弹回。可是当我写两个小球运动的时候可以正常反应,当我把程序继续丰富利用for(i)嵌套for(j)改成多个小球后,界面出来的小球几乎都是静止的了。一下是代码,请求帮我看看吧。
思路:1.先创建Circle类,定义球的属性。2. 创建画布类,CircleCanvas,用来显示出小球和小球运动。3. 创建CanvasPanel,用来将画布在界面上显示出来。
package practice0911s2;
public class Circle {
private int mass;
private double velocity=8;
private int radius=5;
private int posX=0,posY=0;
private double dirX=8.0;
private double dirY=10.0;
public Circle(){
SetCircle();
}
public Circle(int r, int v){
mass=radius=r;
velocity=v;
}
public void SetCircle(){
mass=radius=5;
velocity=8;
}
public double getVelocity(){
return velocity;
}
public int getRadius(){
return radius;
}
public int getPosX(){
return posX;
}
public int getPosY(){
return posY;
}
public double getDirX(){
return dirX;
}
public double getDirY(){
return dirY;
}
public double getVelDirX(){
return velocity*dirX;
}
public double getVelDirY(){
return velocity*dirY;
}
public void setVelocity(double vel){
velocity=vel;
}
public void setRadius(int r){
radius=r;
}
public void setPosX(int x){
posX=x;
}
public void setPosY(int y){
posY=y;
}
public void setPosition(int x,int y){
posX=x;
posY=y;
}
public void setDirX(double dx){
dirX=dx;
}
public void setDirY(double dy){
dirY=dy;
}
}
package practice0911s2;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
public class CircleCanvas extends Canvas implements Runnable {
private int canvasWidth;
private int canvasHeight;
private int CircleNum=10;
private Circle cl[]=new Circle[CircleNum];
private boolean moveStatus=true;
public CircleCanvas(int width, int height){
canvasWidth=width;
canvasHeight=height;
for(int i=0; i!=CircleNum; ++i)
{
cl[i]= new Circle(20,2);
}
cl[0].setPosition(2*cl[0].getRadius(),canvasHeight/2);
for(int i=1;i!=CircleNum;++i)
{
cl[i].setPosition(cl[i-1].getPosX()+cl[i-1].getRadius()+cl[i].getRadius(),
canvasHeight/2);
}
}
public void paint(Graphics g){
for(int i=0;i!=CircleNum;++i)
{
g.setColor(new Color ((int)(Math.random()*16777215)));
g.fillArc(cl[i].getPosX(), cl[i].getPosY(), 2*cl[i].getRadius(),
2*cl[i].getRadius(), 0, 360);
}
}
public void exit(){
moveStatus=false;
}
public void circleMove(){
for(int i=0; i!=CircleNum; ++i){
if(cl[i].getPosX() + cl[i].getVelocity()*cl[i].getDirX()
+ 2*cl[i].getRadius() > canvasWidth ||
cl[i].getPosX() + cl[i].getVelocity()*cl[i].getDirX() < 0){
cl[i].setDirX(-1*cl[i].getDirX());
}else{
cl[i].setPosX((int)(cl[i].getPosX()+cl[i].getVelDirX()));
}
//iy Circle against the wall
if(cl[i].getPosY() + cl[i].getVelocity()*cl[i].getDirY()
+ 2*cl[i].getRadius() > canvasWidth ||
cl[i].getPosY() + cl[i].getVelocity()*cl[i].getDirY() < 0){
cl[i].setDirY(-1*cl[i].getDirY());
}else{
cl[i].setPosY((int)(cl[i].getPosY()+cl[i].getVelDirY()));
}
}
}
public void run(){
while(moveStatus){
circleMove();
}
circlesCollide();
repaint();
try{
Thread.sleep(10);
}catch(InterruptedException e){}
}
public void circlesCollide(){
for(int i=0; i!=CircleNum; ++i){
for(int j=0; j!=CircleNum; ++j){
if(i!=j){
//i Circle against the wall
//ix Circle against the wall
if(Math.sqrt(Math.pow((cl[i].getPosX()-cl[j].getPosX()),2) +
Math.pow((cl[i].getPosY()-cl[j].getPosY()),2))
> (cl[i].getRadius()+cl[j].getRadius())){
return;
}else{
double sx = cl[i].getPosX() - cl[j].getPosX() ;
double sy = cl[i].getPosY() - cl[j].getPosY() ;
double s1x = sx / Math.sqrt(sx*sx + sy*sy) ;
double s1y = sy / Math.sqrt(sx*sx + sy*sy) ;
double tx = -sy ;
double ty = sx ;
double t1x = tx / Math.sqrt(tx*tx + ty*ty) ;
double t1y = ty / Math.sqrt(tx*tx + ty*ty) ;
double v1s = cl[i].getDirX() * s1x + cl[i].getDirY() * s1y ;
double v1t = cl[i].getDirX() * t1x + cl[i].getDirY() * t1y ;
double v2s = cl[j].getDirX() * s1x + cl[j].getDirY() * s1y ;
double v2t = cl[j].getDirX() * t1x + cl[j].getDirY() * t1y ;
//exchange of momentum in Dir s
double v1sf = v2s ;
double v2sf = v1s ;
double nsx = v1sf * s1x ;
double nsy = v1sf * s1y ;
double ntx = v1t * t1x ;
double nty = v1t * t1y ;
cl[i].setDirX(nsx + ntx);
cl[i].setDirY(nsy + nty);
nsx = v2sf * s1x ;
nsy = v2sf * s1y ;
ntx = v2t * t1x ;
nty = v2t * t1y ;
cl[j].setDirX(nsx + ntx);
cl[j].setDirY(nsy + nty);
//if the circles are still in the collide status, we should let them go
while(Math.sqrt(Math.pow((cl[i].getPosX()-cl[j].getPosX()),2) +
Math.pow((cl[i].getPosY()-cl[j].getPosY()),2))
> (cl[i].getRadius()+cl[j].getRadius())){
if(cl[i].getPosX() + cl[i].getVelocity()*cl[i].getDirX()
+ 2*cl[i].getRadius() > canvasWidth ||
cl[i].getPosX() + cl[i].getVelocity()*cl[i].getDirX() < 0){
cl[i].setDirX(-1*cl[i].getDirX());
}else{
cl[i].setPosX((int)(cl[i].getPosX()+cl[i].getVelDirX()));
}
//iy Circle against the wall
if(cl[i].getPosY() + cl[i].getVelocity()*cl[i].getDirY()
+ 2*cl[i].getRadius() > canvasWidth ||
cl[i].getPosY() + cl[i].getVelocity()*cl[i].getDirY() < 0){
cl[i].setDirY(-1*cl[i].getDirY());
}else{
cl[i].setPosY((int)(cl[i].getPosY()+cl[i].getVelDirY()));
}
//j Circle against the wall
//jx Circle against the wall
if(cl[j].getPosX() + cl[j].getVelocity()*cl[j].getDirX()
+ 2*cl[j].getRadius() > canvasWidth ||
cl[j].getPosX() + cl[j].getVelocity()*cl[j].getDirX() < 0){
cl[j].setDirX(-1*cl[j].getDirX());
}else{
cl[j].setPosX((int)(cl[j].getPosX()+cl[j].getVelDirX()));
}
//jy Circle against the wall
if(cl[j].getPosY() + cl[j].getVelocity()*cl[j].getDirY()
+ 2*cl[j].getRadius() > canvasWidth ||
cl[j].getPosY() + cl[j].getVelocity()*cl[j].getDirY() < 0){
cl[j].setDirY(-1*cl[j].getDirY());
}else{
cl[j].setPosY((int)(cl[j].getPosY()+cl[j].getVelDirY()));
}
}
}
}
}
}
}
public void canvasResize(){
canvasWidth=this.getWidth();
canvasHeight=this.getHeight();
}
}
package practice0911s2;
import javax.swing.*;
import java.awt.Container;
import java.awt.event.WindowAdapter;
import java.awt.event.ComponentAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.ComponentEvent;
public class CirclePanel extends JPanel {
private int screenWidth,screenHeight;
JFrame frame=null;
Container panel=null;
CircleCanvas clcanvas=null;
public CirclePanel(){
frame=new JFrame("Bouncing Ball");
frame.setSize(500,500);
this.setSize(500,500);
screenWidth=this.getWidth();
screenHeight=this.getHeight();
Container panel=frame.getContentPane();
//panel.setBackground(Color.black);
clcanvas=new CircleCanvas(screenWidth,screenHeight);
Thread t = new Thread(clcanvas);
t.start();
//Thread??
frame.addWindowListener(new WindowAdapter(){
public void windowClosed(WindowEvent e){
clcanvas.exit();
System.exit(0);
}
});
frame.addComponentListener(new ComponentAdapter(){
public void componentResized(ComponentEvent e){
resize();
}
});
panel.add(clcanvas);
frame.setVisible(true);
}
public static void main(String[] args) {
CirclePanel clpanel =new CirclePanel();
}
public void resize(){
screenWidth = frame.getWidth();
screenHeight = frame.getHeight();
clcanvas.canvasResize();
}
}