主要实现由一个线程控制30个小球运动,最终效果是每点击一次界面,都会在该位置生成随机大小的小球,小球以随即速度做直线运动(会回弹),生成30个小球后不能再点击。效果如下:
首先创建一个小球类,包括坐标,速度,大小,颜色等属性
public class ball {
int x,y,speed,size;
Graphics g;
Color color;
JFrame jf;
public ball(int x,int y,Graphics g,Color color,int speed,int size){
this.x=x;
this.y=y;
this.g=g;
this.color=color;
this.speed=speed;
this.size=size;
}
}
第二步:建立窗体对象,在窗体上加上监听器
public class ThreadGame extends JFrame{
static Graphics g;
GameListener gl = new GameListener ();
public void showUI(){
JFrame jf=new JFrame("");
jf.setTitle ("线程游戏");
jf.setSize (800,800);
jf.setDefaultCloseOperation (EXIT_ON_CLOSE);
jf.getContentPane().setBackground(Color.WHITE);
jf.setVisible (true);
jf.addMouseListener (gl);
g=jf.getGraphics();
gl.setG(g);
gl.setJf(jf);
}
@Override
public void paint(Graphics g){
super.paint (g);
}
public static void main(String[] args) {
ThreadGame th=new ThreadGame();
th.showUI();
}
}
第三步:创建监听器类,主要监听鼠标动作,按下时获取坐标并创建小球对象,这里是初始化一个动态数组,调用add()方法将创建的小球对象加入数组中,在后面线程类中会从数组中取出小球并绘制。
保证只用一个线程而不再重复创建线程的方法是设置一个布尔变量,初始值为true,当创建并启动线程后,变量赋值为false,之后每次点击鼠标都是将小球add到数组中,而不再创建线程。
public class GameListener extends MouseAdapter{
ArrayList<ball> list=new ArrayList<ball>();
Graphics g;
JFrame jf;
int count=1;
public boolean startThread=true;//判断线程是否启动
public void setG(Graphics g) {
this.g=g;
}
public void setJf(JFrame jf) {
this.jf=jf;
}
@Override
public void mouseReleased(MouseEvent e){
System.out.println("点击了"+count+"次");
count++;
int x ,y=0;
Random r=new Random();
x=r.nextInt(700);
y=r.nextInt(700);
Color color=Color.BLACK;
//实例化小球,输入参数:坐标,画笔,颜色,小球移动速度,小球大小
ball ball=new ball(x,y,g,color,r.nextInt(1,10),r.nextInt(1,50));
//将小球添加到数组
list.add(ball);
//保证只调用一次start方法
if(startThread) {
//启动线程
MainThread mt=new MainThread(list,g,jf);
new Thread(mt).start();
System.out.print("线程启动。。");
startThread=false;
}
}
}
第四步:创建线程类,使用runnable接口实现线程,重写run方法,从数组中取出小球,判断小球是否运动出界面,并且要画一个白球盖住上一个小球,再绘制当前小球。
public class MainThread implements Runnable{
ArrayList<ball> list=new ArrayList<ball>();
Graphics g;
JFrame jf;
public MainThread(ArrayList<ball> list,Graphics g,JFrame jf){
this.list=list;
this.g=g;
this.jf=jf;
}
@Override
public void run() {
//第一个循环控制线程运行时间,要求一个线程控制30个小球
while(list.size()<=30) {
//画出小球
for(int i=0;i<list.size();i++) {
//超出窗体回弹
if(list.get(i).y<0||list.get(i).y>jf.getHeight()+10||list.get(i).x<0||list.get(i).x>jf.getWidth()+10) {
list.get(i).speed=-1*list.get(i).speed;
}
//先画上一个小球,再画当前的小球
g.setColor(Color.WHITE);
g.fillOval(list.get(i).x+list.get(i).speed, list.get(i).y+list.get(i).speed,list.get(i).size, list.get(i).size);
//
list.get(i).x+=list.get(i).speed;
list.get(i).y+=list.get(i).speed;
g.setColor(list.get(i).color);
g.fillOval(list.get(i).x+list.get(i).speed, list.get(i).y+list.get(i).speed,list.get(i).size, list.get(i).size);
}
try {
Thread.sleep (30);
} catch (InterruptedException ie) {
throw new RuntimeException (ie);
}
}
System.out.println("不要再点击了");
}
}