3
回答
多球碰撞运动,java,屏幕刷新问题
利用AWS快速构建适用于生产的无服务器应用程序,免费试用12个月>>>   

@红薯 你好,想跟你请教个问题:

您好,看到这里您威望最高,所以想请教您啦。我用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();           
    }

}

举报
zchning
发帖于4年前 3回/723阅
顶部