动态弹球(Java多线程实现+swing)

1 篇文章 0 订阅
1 篇文章 0 订阅

根据老师上课讲的内容,完成了一个小作业,发到这里,希望可以帮助到需要的人,也希望大家来指点。
效果图:
在这里插入图片描述
点击"创建小球",在窗体底部任意位置弹出颜色随机小球,小球碰到四边或与其他小球相撞就会反弹,随着时间增加,小球运动速度加快并变大:在这里插入图片描述
首先我们创建两个按钮对象以及一个画布对象(绘制小球),设置窗体参数:

    private Button startButton;
	private Button exitButton;
	private Canvas canvas;
	public static int WIDTH = 300;
	public static int HEIGHT = 480;

类的构造方法中将按钮和画布添加进窗体中,设置布局和画布参数以及按钮的监听事件:

	setTitle("弹球小游戏");
	
	canvas = new Canvas();
	canvas.setBackground(Color.white);
	
	add("Center", canvas);
	
	startButton = new Button("创建小球");
	exitButton = new Button("退出");
		
	Panel p = new Panel();
	p.add(startButton);
	p.add(exitButton);
		
	add("South", p);

	addWindowListener(new WindowAdapter() {
		public void windowClosing(WindowEvent e) {
			setVisible(false);
			System.exit(0);
		}
	});	

当点击窗体中的两个不同的按钮时分别进行的操作:

	//当点击创建小球的按钮时
	startButton.addMouseListener(new MouseAdapter() { 
			
		public void mousePressed(MouseEvent e) {
            //生成新的对象
			new Ball(canvas, new Color(
					(int) ((255) * Math.random()),
					(int) ((255) * Math.random()), 
					(int) ((255) * Math.random()))
				).start();
				
		}
	});
	exitButton.addMouseListener(new MouseAdapter() {
		public void mousePressed(MouseEvent e) {
			setVisible(false);
			System.exit(0);
		}
	});

上面的创建小球按钮生成小球对象时,需要用到下面的Ball类:
本类中需要设置一些必要的参数来判断小球是否停止以及初始小球运动的速度等:

	private int xSize = 12;
	private int ySize = 12;
	
	private int x;
	private int y;
	
	private int dx = 5;
	private int dy = 5;
	
	private Color color;
	
	private int movecount = 0;
	
	public final static int MOVE_COUNT = 500;
	
	private boolean isMoving = true;
	
	private boolean isOver = false;

本类的构造方法中,要给生成小球的颜色和出现位置一个随机的值:

	box = c;
	color = co;
		
	Dimension d= box.getSize();
	x = (int)((d.width) * Math.random());
	y = d.height;

对小球在画布canvas c的对象上进行绘制:

	Graphics g = box.getGraphics();
	g.setColor(color);
	g.fillOval(x, y, xSize, ySize);
	g.dispose();

小球的运动方法,运动中需要调用速度改变和碰撞时的方法:

	if (!box.isVisible()) return;
		
	Graphics g = box.getGraphics();
	g.setColor(color);
	g.setXORMode(box.getBackground());
		
	g.fillOval(x, y, xSize, ySize);
	x += dx;
	y += dy;
	bounce();
		
	if(movecount++ > MOVE_COUNT) {
		changeSpeedAndSize();
	}
		
	g.fillOval(x, y, xSize, ySize);
	g.dispose();

当小球遭遇到碰撞时(与四边或其他小球相撞),参数改变;

	Dimension d = box.getSize();
	if(x < 0) {x = 0; dx = -dx;}
	if(x + xSize >= d.width) {x = d.width - xSize; dx = -dx;}
	if(y < 0) {y = 0; dy = -dy;}
	if(y + ySize >= d.height) {y = d.height - ySize; dy = -dy;}

小球的速度的大小会随着时间的增加而加快和增大,不想让小球变化的话,可以删除此方法:

	dx = dx / 2 * 3;
	dy = dy / 2 * 3;
	xSize = xSize / 2 * 3;
	ySize = ySize / 2 * 3;
	movecount = 0;

这个小实验是用了多线程来实现小球的创建和运动,创建的小球很多时,会占用很大的CPU空间,运行时需要注意。不想使用多线程实现的朋友可以自行进行修改。
下方附上所有代码:

//******Ball.java*******//
import java.awt.*;

public class Ball extends Thread{
	private Canvas box;
	
	private int xSize = 12;
	private int ySize = 12;
	
	private int x;
	private int y;
	
	private int dx = 5;
	private int dy = 5;
	
	private Color color;
	
	private int movecount = 0;
	
	public final static int MOVE_COUNT = 500;
	
	private boolean isMoving = true;
	
	private boolean isOver = false;
	
	public Ball(Canvas c, Color co) {
		box = c;
		color = co;
		
		Dimension d= box.getSize();
		x = (int)((d.width) * Math.random());
		y = d.height;
		
	}
	
	private void draw() {
		
		Graphics g = box.getGraphics();
		g.setColor(color);
		g.fillOval(x, y, xSize, ySize);
		g.dispose();
	}
	
	public void move() {
		if (!box.isVisible()) return;
		
		Graphics g = box.getGraphics();
		g.setColor(color);
		g.setXORMode(box.getBackground());
		
		g.fillOval(x, y, xSize, ySize);
		x += dx;
		y += dy;
		bounce();
		
		if(movecount++ > MOVE_COUNT) {
			changeSpeedAndSize();
		}
		
		g.fillOval(x, y, xSize, ySize);
		g.dispose();
		
	}
	
	private void bounce() {
		Dimension d = box.getSize();
		if(x < 0) {x = 0; dx = -dx;}
		if(x + xSize >= d.width) {x = d.width - xSize; dx = -dx;}
		if(y < 0) {y = 0; dy = -dy;}
		if(y + ySize >= d.height) {y = d.height - ySize; dy = -dy;}
		
	}
	
	private void changeSpeedAndSize() {
		
		dx = dx / 2 * 3;
		dy = dy / 2 * 3;
		
		xSize = xSize / 2 * 3;
		ySize = ySize / 2 * 3;
		
		movecount = 0;
	}
	
	public void run() {
		
		while(!isOver) {
			if(isMoving) move();
			try {
				Thread.sleep(30);	
			}catch(InterruptedException e) {
				
			}
		}
	}
	
	public int getXpos() {
		return x;
	}
	
	public int getYpos() {
		return y;
	}
	
	public void pause() {
		isMoving = false;
	}
	
	public void resumeMove() {
		isMoving = true;
	}
	
	public boolean isThisOver() {
		return isOver;
	}

}

//****BouncingBall.java****//
import java.awt.*;
import java.awt.ActiveEvent.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;

public class BouncingBall extends Frame{
	
	private Button startButton;
	private Button exitButton;
	private Canvas canvas;
	public static int WIDTH = 300;
	public static int HEIGHT = 480;
	
	public BouncingBall() {
		setTitle("弹球小游戏");
		
		canvas = new Canvas();
		canvas.setBackground(Color.white);
		
		add("Center", canvas);
		
		startButton = new Button("创建小球");
		exitButton = new Button("退出");
		
		Panel p = new Panel();
		p.add(startButton);
		p.add(exitButton);
		
		add("South", p);
		
		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				setVisible(false);
				System.exit(0);
			}
		});
	}
	public void init() {
		
		canvas.setVisible(true);
		
		startButton.addMouseListener(new MouseAdapter() {
			
			public void mousePressed(MouseEvent e) {

				new Ball(canvas, new Color(
						(int) ((255) * Math.random()),
						(int) ((255) * Math.random()), 
						(int) ((255) * Math.random()))
					).start();
			}
		});
		exitButton.addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent e) {
				setVisible(false);
				System.exit(0);
			}
		});
	}
	
	public static void main(String args[]) {
		
		BouncingBall a = new BouncingBall();
		a.setSize(HEIGHT, WIDTH);
		a.init();
		a.setVisible(true);
	}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值