?? 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 + -