📄 bouncingballs.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 + -