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

📄 bouncingballs.java

📁 面向对象技术
💻 JAVA
字号:
import java.awt.*;
import java.applet.*;
//定义Obstacle类
class Obstacle
{
	public Rectangle r; 
	Graphics g;
	//构造函数
	public Obstacle(int x,int y,int w,int h)
	{
		r=new Rectangle(x,y,w,h);
	}
	//调用paint()方法,画出Obstacle
	public void paint(Graphics gr)
	{	
		g=gr;
		g.setColor(Color.lightGray);//设置颜色
		//画3D矩形
		g.draw3DRect(r.x,r.y,r.width,r.height,true);
	}		
}
//定义CollideBall类
class CollideBall
{
	int width, height;
	public static final int diameter=20;
	//坐标值以及增量值(运动方向和速度)
	double x, y, xinc, yinc, coll_x, coll_y;
	boolean collide;
	Color color;
	Graphics g;
	Rectangle r;	
	//构造函数
	public CollideBall(int w, int h, int x, int y, double xinc, double yinc, Color c)
	{
		width=w;
		height=h;
		this.x=x;
		this.y=y;
		this.xinc=xinc;
		this.yinc=yinc;		
		color=c;		
		r=new Rectangle(150,80,130,90);
	}
	//获取中心位置坐标
	public double getCenterX() {return x+diameter/2;}
	public double getCenterY() {return y+diameter/2;}
        //改变矩形的大小以及位置
	public void alterRect(int x, int y, int w, int h)
	{
		r.move(x,y);
		r.resize(w,h);
	}
	//定义move()方法,负责球体的运动路线
	public void move()
	{
		//当两个球体发生碰撞时的运动属性
		if (collide)
		{			
			double xvect=coll_x-getCenterX();
			double yvect=coll_y-getCenterY();

			if((xinc>0 && xvect>0) || (xinc<0 && xvect<0))
				xinc=-xinc;

			if((yinc>0 && yvect>0) || (yinc<0 && yvect<0))
				yinc=-yinc;
	
			collide=false;
		}
	
		x+=xinc;
    	y+=yinc;
	//当球碰到边框时,它会被弹回来
    	if(x<6 || x>width-diameter)
    	{
    		xinc=-xinc;
	  		x+=xinc;
    	}
	    
		if(y<6 || y>height-diameter)
    	{
    		yinc=-yinc;
	  		y+=yinc;
    	}
		
		//将球体的坐标转换为整数
		int x=(int)this.x;
		int y=(int)this.y;
		//当碰到障碍物就弹回来
		//左边框
		if(x>r.x-diameter&&x<r.x-diameter+7&&xinc>0&&y>r.y-diameter&&y<r.y+r.height)
    	{
    		xinc=-xinc;
	  		x+=xinc;
    	}
		//右边框
		if(x<r.x+r.width&&x>r.x+r.width-7&&xinc<0&&y>r.y-diameter&&y<r.y+r.height)
    	{
    		xinc=-xinc;
	  		x+=xinc;
    	}
		//上边框
		if(y>r.y-diameter&&y<r.y-diameter+7&&yinc>0&&x>r.x-diameter&&x<r.x+r.width)
		{
			yinc=-yinc;
	  		y+=yinc;
		}
		//下边框
		if(y<r.y+r.height&&y>r.y+r.height-7&&yinc<0&&x>r.x-diameter&&x<r.x+r.width)
		{
			yinc=-yinc;
	  		y+=yinc;
		}

	}
	//定义hit()方法,判断是发生否碰撞
	public void hit(CollideBall b)
	{
		if(!collide)
		{
			coll_x=b.getCenterX();
			coll_y=b.getCenterY();
			collide=true;
		}
	}
	//paint()方法
	public void paint(Graphics gr)
	{	
		g=gr;
		g.setColor(color);
		//由于fillOval()函数的坐标值必须为整数,
		//所以这里将准确的坐标值转换为整数
		g.fillOval((int)x,(int)y,diameter,diameter);
	
		g.setColor(Color.white);
		g.drawArc((int)x,(int)y,diameter,diameter,45,180);

		g.setColor(Color.darkGray);
		g.drawArc((int)x,(int)y,diameter,diameter,225,180);
	}	
}
//定义BouncingBalls类
public class BouncingBalls extends Applet implements Runnable 
{
	Thread runner;//定义runner线程	
	Image Buffer;
    Graphics gBuffer;		
    CollideBall ball[];//定义ball数组,用来存放球体参数
	Obstacle o;    
    //设置球体数量
    static final int MAX=10;
	boolean intro=true,drag,shiftW,shiftN,shiftE,shiftS;
	boolean shiftNW,shiftSW,shiftNE,shiftSE;
	int xtemp,ytemp,startx,starty;
	int west, north, east, south;
	//初始化
	public void init() 
	{			
		Buffer=createImage(size().width,size().height);
		gBuffer=Buffer.getGraphics();					
      		//创建10个球体
		ball=new CollideBall[MAX];
            	int w=size().width-5;
		int h=size().height-5;		
		//这些球体各自拥有不同的起始坐标值,增量值
		//(运动的速度和方向)以及不同的颜色
		ball[0]=new CollideBall(w,h,50,20,1.5,2.0,Color.orange);
                ball[1]=new CollideBall(w,h,60,210,2.0,-3.0,Color.red);
                ball[2]=new CollideBall(w,h,15,70,-2.0,-2.5,Color.pink);
       		ball[3]=new CollideBall(w,h,150,30,-2.7,-2.0,Color.cyan);
        	ball[4]=new CollideBall(w,h,210,30,2.2,-3.5,Color.magenta);
		ball[5]=new CollideBall(w,h,360,170,2.2,-1.5,Color.yellow);
		ball[6]=new CollideBall(w,h,210,180,-1.2,-2.5,Color.blue);
		ball[7]=new CollideBall(w,h,330,30,-2.2,-1.8,Color.green);
		ball[8]=new CollideBall(w,h,180,220,-2.2,-1.8,Color.black);
		ball[9]=new CollideBall(w,h,330,130,-2.2,-1.8,Color.gray);
 		//创建一个障碍物
		o=new Obstacle(150,80,130,90);
		//定义东南西北
		west=o.r.x;
		north=o.r.y;
		east=o.r.x+o.r.width;
		south=o.r.y+o.r.height;
	}	
	//启动线程
	public void start()
	{
		if (runner == null) 
		{
			runner = new Thread (this);
			runner.start();
		}
   }
   //停止线程
   public void stop()
	{
		if (runner != null) 
		{
         	runner.stop();
           	runner = null;
     	}
   }
        //开始运行程序
	public void run()
	{
		while(true) 
		{
			Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
			try {runner.sleep(15);}
            	catch (Exception e) { }						
			//使球体到处运动
			for(int i=0;i<MAX;i++)
				ball[i].move();	
			handleCollision();
			repaint();	                        
		}	
	}
	//判断是否碰撞
	boolean collide(CollideBall b1, CollideBall b2)
	{
		double wx=b1.getCenterX()-b2.getCenterX();
		double wy=b1.getCenterY()-b2.getCenterY();
		//计算两个球体的球心距离
		//从而判断球体是否相撞
		double distance=Math.sqrt(wx*wx+wy*wy);
		if(distance<b1.diameter)					
			return true;		

			return false;	
	}
        //changeCursor()方法,负责设置鼠标
	void changeCursor(int x, int y)
	{
		Rectangle r=new Rectangle(o.r.x+1,o.r.y+1,o.r.width-1,o.r.height-1);
		Frame BrowserFrame;
		Component ParentComponent;
		ParentComponent = getParent();
		while ( ParentComponent != null && 
		!(ParentComponent instanceof Frame)) 		      
		ParentComponent = ParentComponent.getParent();		
		BrowserFrame = (Frame) ParentComponent;
		if(shiftNW||shiftSE)
			BrowserFrame.setCursor(Frame.SE_RESIZE_CURSOR);
		else if(shiftNE||shiftSW)
			BrowserFrame.setCursor(Frame.SW_RESIZE_CURSOR);
		else if(shiftW)
			BrowserFrame.setCursor(Frame.W_RESIZE_CURSOR);
		else if(shiftN)
			BrowserFrame.setCursor(Frame.N_RESIZE_CURSOR);
		else if(shiftE)
			BrowserFrame.setCursor(Frame.W_RESIZE_CURSOR);
		else if(shiftS)
			BrowserFrame.setCursor(Frame.N_RESIZE_CURSOR);
		else if(r.inside(x,y))
			BrowserFrame.setCursor(Frame.MOVE_CURSOR);
		else 
			BrowserFrame.setCursor(Frame.DEFAULT_CURSOR);
	}
	//mouseMove()方法,判断鼠标的移动
	public boolean mouseMove(Event evt,int x,int y)
	{
		//障碍物的边角区域
		Rectangle nw,sw,ne,se;
		
		nw=new Rectangle(o.r.x-2,o.r.y-2,4,4);
		if(nw.inside(x,y))
			shiftNW=true;
		else shiftNW=false;
                
		sw=new Rectangle(o.r.x-2,o.r.y+o.r.height-2,4,4);
		if(sw.inside(x,y))
			shiftSW=true;
		else shiftSW=false;
                
		ne=new Rectangle(o.r.x+o.r.width-2,o.r.y-2,4,4);
		if(ne.inside(x,y))
			shiftNE=true;
		else shiftNE=false;
                
		se=new Rectangle(o.r.x+o.r.width-2,o.r.y+o.r.height-2,4,4);

		if(se.inside(x,y))
			shiftSE=true;
		else shiftSE=false;		
                
		if(x>o.r.x-2&&x<o.r.x+2&&y>o.r.y&&y<o.r.y+o.r.height)
			shiftW=true;
		else shiftW=false;
		if(x>o.r.x+o.r.width-2&&x<o.r.x+o.r.width+2
			&&y>o.r.y&&y<o.r.y+o.r.height)
			shiftE=true;
		else shiftE=false;
		if(y<o.r.y+2&&y>o.r.y-2&&x>o.r.x&&x<o.r.x+o.r.width)
			shiftN=true;
		else shiftN=false;
		if(y>o.r.y+o.r.height-2&&y<o.r.y+o.r.height+2
			&&x<o.r.x+o.r.width)
			shiftS=true;
		else shiftS=false;
		changeCursor(x,y);
		return true;
	}
	//mouseDown()方法,负责判断鼠标是否被按下
	public boolean mouseDown(Event evt,int x,int y)
	{
		Rectangle r=new Rectangle(o.r.x+2,o.r.y+2,o.r.width-4,o.r.height-4);
		if(r.inside(x,y))
		{
			drag=true;
			startx=x;
			starty=y;
			xtemp=o.r.x;
			ytemp=o.r.y;
		}
		else drag=false;
		changeCursor(x,y);
		return true;
	}
        //mouseDrag()方法,判断鼠标是否作出拖拽动作
	public boolean mouseDrag(Event evt,int x,int y)
	{
		intro=false;
		Rectangle bounds=new Rectangle(5,5,size().width-5,size().height-5);
		int endx, endy;		
		endx=x-startx;
		endy=y-starty;	
		//在边框外,禁止鼠标活动
		if(x<5)x=5;
		if(y<5)y=5;
		if(x>bounds.width)x=bounds.width;
		if(y>bounds.height)y=bounds.height;
                //是否发生拖拽动作
		if(drag)
		{	
			//使鼠标拖拽动作只能在边框那进行
			int ox=endx+xtemp;
			int oy=endy+ytemp;
			
			if(ox<5)ox=5;
			if(oy<5)oy=5;

			if(ox>bounds.width-o.r.width)
				ox=bounds.width-o.r.width;

			if(oy>bounds.height-o.r.height)
				oy=bounds.height-o.r.height;	
			
			o.r.move(ox,oy);				

			west=o.r.x;
			north=o.r.y;
			east=o.r.x+o.r.width;
			south=o.r.y+o.r.height;						
		}		
		//否则
		else
		{
			if(shiftNW){west=x;north=y;}
			else if(shiftNE){east=x;north=y;}
			else if(shiftSW){west=x;south=y;}
			else if(shiftSE){east=x;south=y;}
			else if(shiftW)west=x;
			else if(shiftE)east=x;
			else if(shiftN)north=y;
			else if(shiftS)south=y;											
			//设置矩形的最小边长,该矩形不能小于40*40
			int MIN=40;
			//判断左右方向的最小边距
			if(east-west<MIN)
			{				
				if(shiftW||shiftNW||shiftSW)
					west=east-MIN;
				if(shiftE||shiftNE||shiftSE)
					east=west+MIN;
			}
                        //判断上下方向的最小边距
			if(south-north<MIN)
			{
				if(shiftN||shiftNW||shiftNE)
					north=south-MIN;
				if(shiftS||shiftSE||shiftSW)
					south=north+MIN;
			}
		}
		//将障碍物的改变向球体和边框发送消息
		for(int i=0;i<MAX;i++)
			ball[i].alterRect(o.r.x,o.r.y,o.r.width,o.r.height);		
		o.r.move(west,north);
		o.r.resize(east-west, south-north);
		changeCursor(x,y);		
		return true;
	}	
	//处理碰撞
	private void handleCollision()
	{	
		//遍历所有的球体,检查是否发生碰撞
		for(int i=0;i<MAX;i++)
			for(int j=0;j<MAX;j++)
				{
					if(i!=j)
					{										
						if(collide(ball[i], ball[j]))
						{			
							ball[i].hit(ball[j]);
							ball[j].hit(ball[i]);
						}
					}
				}	
	}
	//update()方法
	public void update(Graphics g)
	{
		paint(g);
  	}
        //
  	public void paint(Graphics g) 
	{		
		gBuffer.setColor(Color.lightGray);
		gBuffer.fillRect(0,0,size().width,size().height);
		gBuffer.draw3DRect(5,5,size().width-10,size().height-10,false);			
		//画障碍物矩形
		o.paint(gBuffer);
		//画球体
		for(int i=0;i<MAX;i++)
				ball[i].paint(gBuffer);	
		if(intro)
		{			
			gBuffer.setColor(Color.red);
			gBuffer.setFont(new Font("Helvetica", Font.PLAIN,  12));			
			gBuffer.drawString("您可以移动中心矩形的位置并且可以改变它的大小!",20,30);
			gBuffer.setFont(new Font("Helvetica", Font.PLAIN,  10));
			gBuffer.drawString("2003 by Ali",155,240);
		}		
		g.drawImage (Buffer,0,0, this);				
  	}	
}

⌨️ 快捷键说明

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