小球与线程

这篇博客介绍了如何使用Java线程创建一个动态小球游戏,重点在于小球碰撞壁后的反弹逻辑,通过定义方向变量并结合switch或if语句控制运动路径。作者首先定义了面板类,然后实现了小球的主要功能,并添加了监听器。尽管游戏已经完成,但作者认为小球间的碰撞效果有待优化。
摘要由CSDN通过智能技术生成




     通过线程来实现动态的小球是一个比较复杂的过程,首先是能够让小球碰到壁后弹起来,这个方法的实现有一些技巧在里面,就是定义的的哥方方向变量,通过把方向赋予一定的值从而来使用switch语句或是if语句进行判断。以达到转变方向的过程。这是弹球的主要思想

首先是定义了一个面板类.

/**
 * 定义一个画画类,用来生成面板和画画。
 * @author 周建权 20130713
 *
 */

public class Draw extends JFrame {

	private JPanel jpanel;
	private Graphics g;

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Draw draw = new Draw();
		draw.initUI();
	}
	
	public void initUI(){
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setTitle("弹球");
		this.setSize(600, 600);
		this.setLayout(new BorderLayout());
		JPanel jp = new JPanel();
		jpanel = new JPanel();
		this.add(jp,BorderLayout.NORTH);
		this.add(jpanel,BorderLayout.CENTER);
		JButton jbu1=new JButton("增加");
		JButton jbu2=new JButton("继续");
		JButton jbu3=new JButton("暂停");
		JButton jbu4=new JButton ("随机删除");
		JButton jbu5=new JButton("顺序删除");
		JButton jbu6=new JButton("点鼠标删除");
		jp.add(jbu1);
		jp.add(jbu2);
		jp.add(jbu3);
		jp.add(jbu4);
		jp.add(jbu5);
		jp.add(jbu6);
		jbu4.setForeground(Color.blue);
		jbu1.setForeground(Color.blue);
		jbu2.setForeground(Color.blue);
		jbu3.setForeground(Color.blue);
		jbu5.setForeground(Color.blue);
		jbu6.setForeground(Color.blue);
		
		
		this.setVisible(true);
		
	  
	    ThreadListener l=new ThreadListener(jpanel);
	    jbu1.addActionListener(l);
	    jbu2.addActionListener(l);
	    jbu3.addActionListener(l);
	    jbu4.addActionListener(l);
	    jbu5.addActionListener(l);
	    jbu6.addActionListener(l);
	   /**
	    * 打算添加图片,还没实现此功能。
	    */
	    jpanel.setUI(new PanelUI(){
	    ImageIcon image=new ImageIcon();
	    public void paint(Graphics g,JComponent c){
	     g.drawImage(image.getImage(),0,0,null);
	    }
	     });
	   
	}
}

 接着就是实现小球主要功能的方法了。小球的各个功能都以此为基础

/**
 *   线程类
 * @author 周建权 2013.7.18
 *
 */
public class DrawThread extends Thread {
	private Graphics g;
	private JPanel jp;
	private static  ArrayList<DrawThread> ball = new ArrayList<DrawThread>();
	//定义方向
	private static final int UP=1;
	private static final int DOWN=2;
	private static final int LEFT=3;
	private static final int RIGHT=4;
	//定义小球位置
	private int x,lastx;
	private int y,lasty;
	public int getX() {
		return x;
	}
	public void setX(int x) {
		this.x = x;
	}
	public int getY() {
		return y;
	}
	public void setY(int y) {
		this.y = y;
	}
	
	// 定义半径
	private int radius;
	public int getRadius() {
		return radius;
	}
	public void setRadius(int radius) {
		this.radius = radius;
	}
	
	//定义停止暂停
	private boolean pauseFlag=false;
	private boolean stopFlag=false;
	//定义速度
	private int xspeed;
	private int yspeed;
	//球的运动方向
	private int xdirection=RIGHT;
    private int ydirection=DOWN;
	//定义颜色
	private Color co;	
	public DrawThread(JPanel jpanel){
		this.jp=jpanel;
		this.g=jpanel.getGraphics();
	}
	public static ArrayList<DrawThread> getList() {
		return ball;
	}
	
	/**
	 * run函数
	 */
	public void run(){
		init();
		while(true){
		try{
			Thread.sleep(200);
			}catch(Exception ef){}
	  if(pauseFlag==true){
		continue;
		}
		if(stopFlag==true){
		clear();
			return;
		}
		clear();
		move();
		draw();
		}
	}
	/**
	 * 定义变量的初始值
	 */
	public void init(){
		Random random=new Random();
		
		xspeed=30+random.nextInt(20);
	    yspeed=10+random.nextInt(40);
	    radius=15+random.nextInt(30);
	    co=new Color(random.nextInt(256),random.nextInt(256),random.nextInt(256));
	}
	/**
	 * 小球移动的方法
	 */
  public void move(){
	
	    if(x<radius/2){xdirection=RIGHT;}
		else if(x>jp.getWidth()-3*radius/2){xdirection=LEFT;}
		
		if(y<radius/2){ydirection=DOWN;}
		else if(y>jp.getHeight()-3*radius/2){ydirection=UP;}
		lastx=x;
		lasty=y;

		if(this.xdirection==LEFT){
			x-=this.xspeed;
			if(collsion(LEFT)){
				xdirection=RIGHT;
			}
		}
		else if(this.xdirection==RIGHT){
			x+=this.xspeed;
			if(collsion(RIGHT)){
				xdirection=LEFT;
		}
		
		if(this.ydirection==UP){
			y-=this.yspeed;
			if(collsion(UP)){
				ydirection=DOWN;
				}
			}
		
		else if(this.ydirection==DOWN){
			y+=this.yspeed;
			if(collsion(DOWN)){
				ydirection=UP;
				}
			}
		}
		
		
  }
  	public void fillcircle(int x,int y,int radius){
  		g.fillOval(x-radius, y-radius, 2*radius, 2*radius);
  	}
	/**
	 * 绘制小球的方法
	 */
	public void draw(){
		g.setColor(co);
		fillcircle(x, y, radius);
		
		int r=co.getRed();
		int G=co.getGreen();
		int b=co.getBlue();
		int radius=this.radius;//很诡秘的代码。
		while(radius>3){
			radius-=2;
			G+=10;
			r+=10;
			b+=10;
			if(G>255){G=255;}
			if(r>255){r=255;}
			if(b>255){b=255;}
		Color d=new Color(r,G,b);
		g.setColor(d);
		fillcircle(x,y,radius);
		}
	}
	/**
	 * 擦除小球的方法
	 */
	public void clear(){
		g.setColor(this.jp.getBackground());
	    fillcircle(x, y,  2*radius);
	}
	/**
	 * 定义一个设置暂停布尔值的方法
	 * @param flag
	 */
	public void setPause(boolean flag){
		pauseFlag=flag;
	}
	/**
	 * 设置停止方法中的布尔值一直为true,线程不可重复开始,停止后直接退出
	 */
	public void setStop(boolean flag){
		this.stopFlag = flag;
	}
	/**
	 * 定义一个碰撞方法,该方法用于判断两个小球是否碰撞。
	 * @param direction
	 * @return若两球碰撞则返回true,若不碰撞则返回false
	 */
	private boolean collsion(int direction){
		for(int i=0;i<ball.size();i++){System.out.println(ball.size());
			DrawThread Thread=ball.get(i);
			if(this==Thread){
				continue;}
			int m=Math.abs(this.getX()-Thread.getX());
			int n=Math.abs(this.getY()-Thread.getY());
			int o=(int)Math.sqrt(m*m+n*n);
			if(o<=this.radius+Thread.radius);
			if(direction==LEFT||direction==RIGHT)
				Thread.xdirection=direction;
			else {Thread.ydirection=direction;
				
			}
			int xsp=this.xspeed;
			int ysp=this.yspeed;
			this.xspeed=Thread.xspeed;
			this.yspeed=Thread.yspeed;
			Thread.xspeed=xsp;
			Thread.yspeed=ysp;
			
			x=lastx;
			y=lasty;
			
			return true;
		}
		return false;
	}
	

}

下面就是添加监听器了

/**
 * 创建一个按钮监听器,按钮画小球
 * 
 * @author 周建权 2013.7.14
 * 
 */
public class ThreadListener extends Thread implements ActionListener {
	private JPanel jp;
	private Graphics g;

	public ThreadListener(JPanel jp) {
		this.jp = jp;
	}

	// 创建一个队列,用来存放线程
	ArrayList<DrawThread> allBall = new ArrayList<DrawThread>();

	public void actionPerformed(ActionEvent e) {
		String s = e.getActionCommand();

		if (s.equals("增加")) {
			DrawThread Thread = new DrawThread(jp);
			// allBall.add(Thread);
			Thread.start();
			allBall.add(Thread);
		}
		
		if (s.equals("继续")) {
			for (int i = 0; i < allBall.size(); i++) {
				DrawThread Thread = allBall.get(i);
				Thread.setPause(false);
			}
		}
		
		if (s.equals("暂停")) {
			for (int i = 0; i < allBall.size(); i++) {
				DrawThread Thread = allBall.get(i);
				Thread.setPause(true);
			}
		}
		
		if (s.equals("随机删除")) {
			int m = allBall.size();
			System.out.println(allBall.size());
			Random random = new Random();
			int n = random.nextInt(m);
			System.out.println(n);
			DrawThread Thread = allBall.remove(n);
			Thread.setStop(true);
			System.out.println(n);
		}
		
		if (s.equals("顺序删除")) {
			if (!allBall.isEmpty()) {
				DrawThread Thread = allBall.remove(0);
				Thread.setStop(true);
			}
		}
		
		if(s.equals("点鼠标删除")){System.out.println("怎么不可以删除");
		MouseListener mouse=new MouseListener(){
		 	
		 	public void mouseClicked(MouseEvent e){
	 	    System.out.println(allBall.size());
	 	    	for(int i=0;i<allBall.size();i++){
	 	    	DrawThread Thread=allBall.get(i);
	 	    	int x=Math.abs(Thread.getX()-e.getX());
	 	    	int y=Math.abs(Thread.getY()-e.getY());
	 	    	if(x<Thread.getRadius()&&y<Thread.getRadius()){
	 	    		allBall.remove(i);
	 	    		Thread.setStop(true);
	 	    		Thread.clear();
	 	    		}
	 	    	}
	 	    }
	 	    public void mousePressed(MouseEvent e){}
	 	    public void mouseReleased(MouseEvent e){}
	 	    public void mouseEntered(MouseEvent e){}
	 	    public void mouseExited(MouseEvent e){}
	 	};jp.addMouseListener(mouse);
	}
	
	}    
}

 一个弹球就做好了。还有待改进的是两个小球之间的效果,这个弹出来的效果一点也不好。。。  

 



 

 

 

 

  • 大小: 34.7 KB
  • 大小: 26.5 KB
  • 大小: 23 KB
  • 大小: 18.9 KB
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值