java小试牛刀(一):碰撞吧,小球
2017-08-02 10:43
405 查看
我时常想象人生就是一颗颗不同颜色的球,我们在特定的空间里面做自由的运动,偶尔会与另一颗美丽或者平凡的小球碰撞在一起,然后我们仍走向截然不同的道路。
生命如此,每个人都是独立的个体。也许有一天吧,你遇到了比你强大,比你包容的另一个生命,他或者她会告诉你,来我的怀里吧;于是乎你毅然决然的放弃了所有,奋不顾身的投入了他的怀抱,两颗不同的心,不同的生命也能融为一体。
于是我们终于知道,生命可以是坚硬的碰撞,也可以是温柔的拥抱。在碰撞与拥抱之间,整个宇宙中的生命得以延续,文明才能得到继续。
在这里作为java初步学习的小结,下面是我所做的小球碰撞以及包容(吞噬)的多线程程序。
以下:
我们用一个黑色的界面来代表整个宇宙,在其中放入五颜六色的形状不一的小球(代表生命),这些球在遇到界面的边界时会发生反弹,在遇到其他球时则会发生吞噬或者碰撞的随机过程。
将小球定义为Ball类,每次在黑色界面上的鼠标点击都会在点击处生成一个颜色随机,大小随机(有上限),速度随机(大小和方向随机,但x,y方向的速度不会同时为0)。将所有小球存放在Arraylist中,然后利用多线程对Arraylist进行操作。其中主要实现的是小球的碰撞以及吞噬的 功能。此外还引入暂停,继续,停止等功能。
下面是小球类
下面是整个界面的实现以及主线程的实现
需要说明的是paint会在run的重载方法中调用,用多线程的思路实现小球的运动过程。
下面是界面的监听机制类
以上就实现了小球的随机生成,碰撞,吞噬功能。
生命如此,每个人都是独立的个体。也许有一天吧,你遇到了比你强大,比你包容的另一个生命,他或者她会告诉你,来我的怀里吧;于是乎你毅然决然的放弃了所有,奋不顾身的投入了他的怀抱,两颗不同的心,不同的生命也能融为一体。
于是我们终于知道,生命可以是坚硬的碰撞,也可以是温柔的拥抱。在碰撞与拥抱之间,整个宇宙中的生命得以延续,文明才能得到继续。
在这里作为java初步学习的小结,下面是我所做的小球碰撞以及包容(吞噬)的多线程程序。
以下:
我们用一个黑色的界面来代表整个宇宙,在其中放入五颜六色的形状不一的小球(代表生命),这些球在遇到界面的边界时会发生反弹,在遇到其他球时则会发生吞噬或者碰撞的随机过程。
将小球定义为Ball类,每次在黑色界面上的鼠标点击都会在点击处生成一个颜色随机,大小随机(有上限),速度随机(大小和方向随机,但x,y方向的速度不会同时为0)。将所有小球存放在Arraylist中,然后利用多线程对Arraylist进行操作。其中主要实现的是小球的碰撞以及吞噬的 功能。此外还引入暂停,继续,停止等功能。
下面是小球类
import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.util.Random; /* * 这里定义的小球类 * 属性有坐标x,y;大小size;速度xspeed,yspeed;颜色color。全部定义为private型 * 各属性都有他们的setters和getters * 方法有move方法来控制其移动 * */ public class Ball { private int x,y,size; private int xspeed; private int yspeed; private Color color; public int getXspeed() { return xspeed; } public void setXspeed(int xspeed) { this.xspeed = xspeed; } public int getYspeed() { return yspeed; } public void setYspeed(int yspeed) { this.yspeed = yspeed; } 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; } public int getSize() { return size; } public void setSize(int size) { this.size = size; } public Color getColor() { return color; } public void setColor(Color color) { this.color = color; } //move是小球的移动方法。 public void move(BallGame BG,Graphics2D g2d){ //判断是否碰撞到左右边界,如果碰撞到则x方向的速度取反 if(x<=0||(x+this.size)>=BG.getWidth()){ int tempspeed=-this.xspeed; this.xspeed =tempspeed; } //判断是否碰撞到上下边界,如果碰撞到则y方向的速度取反 if(y<=20||((y+this.size)>=BG.getHeight())){ int tempspeed =-this.yspeed; this.yspeed =tempspeed; } /* * 下面是小球的移动过程:将小球之间所在位置用界面背景色填充, * 在新的位置上画出小球 */ //用界面背景色填充小球位置 g2d.setColor(BG.getBackground()); g2d.fillOval(x, y, 4000 this.size+5, this.size+5); //改变小球的x和y方向上的小球都会移动xpeed和yspeed的距离,然后得到新的位置坐标 this.x +=this.xspeed; this.y +=this.yspeed; //再用小球颜色在新的坐标上画出小球 g2d.setColor(this.color); g2d.fillOval(x, y, this.size, this.size); }
下面是整个界面的实现以及主线程的实现
import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.RenderingHints; import java.util.ArrayList; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; public class BallGame extends JFrame { private Image img; private ArrayList list =new ArrayList(); public static void main(String []Args){ BallGame BG= new BallGame(); BG.unitUI(); } //这里是黑色的界面 public void unitUI(){ this.setTitle("老九的小球游戏"); this.setSize(1200,700); this.setLocationRelativeTo(null); this.setBackground(Color.black); this.setDefaultCloseOperation(3); this.setResizable(false); this.setVisible(true); /* * 这里加入的监听机制有两个功能 * 1.MouseLIstener用以实现鼠标点击出现小球的功能。 * 2.KeyListener用以实现暂停继续动画的功能 * */ BallListener BL =new BallListener(this,this.getGraphics(),list); this.addMouseListener(BL); this.addKeyListener(BL); //引入多线程 Thread t =new Thread(BL); t.start(); } public void paint(Graphics g) { //次画布img实现双缓冲,用g2d来绘制图形 img = this.createImage(this.getWidth(), this.getHeight()); Graphics2D g2d = (Graphics2D) img.getGraphics(); //引入画笔抗锯齿 g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); /* * 将小球存放在Arraylist数组队列中 * 在下面的循环中将实现小球的吞噬和撞击功能 */ for (int i = 0; i < list.size(); i++) { /* * 小球已被定义为Ball类 * 将取出的小球放在变量ball中 */ Ball ball = (Ball) list.get(i); //这里取出相遇的小球存放在tempb中 for(int j =0 ;j<list.size() ;j++){ Ball tempb =(Ball)list.get(j); //i=j时说明取出的是ball自己 if(i!=j){ /* 再次判断是否发生吞噬,if中判断两球是否重叠,所用公式是,两球的圆心坐标(x1,y1),(x2,y2)以及两球的大小size1,size2应满足以下条件:x1<x2,y1<y2; 1+size1>x2+size2,y1+size1>y2+size2。 */ if(ball.getX()<tempb.getX()&&ball.getY()<tempb.getY() &&(ball.getX()+ball.getSize())>(tempb.getX()+tempb.getSize()) &&(ball.getY()+ball.getSize())>(tempb.getY()+tempb.getSize())){ //如果相遇则发生吞噬,在Arraylist中取出temp对应的小球 list.remove(j); //吞噬后新的小球体积是相遇小球的中的较大者体积加一 if(ball.getSize()<100){ int tempsize =ball.getSize(); ball.setSize(tempsize+1); } } /* 再次判断是否相遇,if中判断两球是否相遇,所用公式是,两球的圆心坐标(x1,y1),(x2,y2)以及两球的大小size1,size2应满足以下条件:(x1-x2)^2+(y1-y2)^2<(size1-size2)^2 */ if(((ball.getX()-tempb.getX())*(ball.getX()-tempb.getX()) +(ball.getY()-tempb.getY())*(ball.getY()-tempb.getY())) <=(ball.getSize()-tempb.getSize())){ //碰撞后两球都会反弹 ball.setXspeed(-ball.getXspeed()); ball.setYspeed(-ball.getYspeed()); tempb.setXspeed(-tempb.getXspeed()); tempb.setYspeed(-tempb.getYspeed()); } } } //在画布g2d上重新绘制所有小球的运动状态 ball.move(this,g2d); } //用g绘制次画布 g.drawImage(img, 0, 0, this); } }
需要说明的是paint会在run的重载方法中调用,用多线程的思路实现小球的运动过程。
下面是界面的监听机制类
import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.ArrayList; import java.util.Random; //利用鼠标监听实现小球的生成,利用按键监听实现整个程序的暂停和继续 public class BallListener implements MouseListener,KeyListener,Runnable{ private int x,y; private BallGame BG; Graphics g; private ArrayList list; //stopFlag为停止功能键 private boolean stopFlag=true; //pauseFlag为 暂停/继续 功能键 private volatile boolean pauseFlag=true; //BallListener方法实现参数的传递:BallGame类界面BG,BG的画笔g,存放小球的数组队列list public BallListener(BallGame BG,Graphics g,ArrayList list){ this.BG =BG; this.g =g; this.list =list; } //在此方法中生成小球 public void mousePressed(MouseEvent e) { //得到鼠标的x,y坐标 x =e.getX(); y =e.getY(); //将得到的坐标赋给小球对象ball Ball b =new Ball(); b.setX(x); b.setY(y); //为小球生成随机颜色,但和界面的背景色不同 Random rand = new Random(); do{ b.setColor( new Color( (new Double(Math.random()*128)).intValue()+128, (new Double(Math.random()*128)).intValue()+128, (new Double(Math.random()*128)).intValue()+128)); }while(b.getColor()==BG.getBackground()); //为小球生成随机的大小但大小不能小于等于10 do{ b.setSize(rand.nextInt(50)); }while(b.getSize()<=10); //为小球生成随机的速度但x,y的速度不能同时为0 do{ b.setXspeed(rand.nextInt(8)-4); b.setYspeed(rand.nextInt(8)-4); }while(b.getXspeed()==0&&b.getYspeed()==0); //将生成的小球加入数组队列list中 list.add(b); } //在此方法中实现暂停,继续等功能 public void keyPressed(KeyEvent e) { //得到按键的值 int key =e.getKeyCode(); //switch实现不同的功能 switch(key){ //空格键时界面暂停,再次空格则会继续 case 32: pauseFlag =!pauseFlag; break; //Esc键时界面停止,多线程结束 case 27: stopFlag =false; break; case 10: stopFlag =true; pauseFlag=true; list.clear(); BG.repaint(); this.run(); break; } } //在run方法中每隔10ms调用一次BG的重写方法来实现之前所述功能 public void run() { //外层的while循环保证多线程一直执行知道stopFlag变为false while(stopFlag){ /*pauseFlag实现暂停功能,需要说明的是如果为声明pauseFlag为volatile型, 则pauseFlag在计算机中存放在内存,而多线程在寄存器中执行,数据会无法交换*/ if(pauseFlag){ BG.repaint(); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } } public void keyTyped(KeyEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mouseClicked(MouseEvent e) {} public void keyReleased(KeyEvent e) {} }
以上就实现了小球的随机生成,碰撞,吞噬功能。
相关文章推荐
- java线程和进程(运用多线程的小球碰撞游戏)
- Java课程设计---碰撞的小球
- Java版小球碰撞
- CCF2018年3月第2题(碰撞的小球)Java解法
- Java 游戏编程基础 做个碰撞的小球
- 201803CCF第二题(碰撞的小球)Java
- java小球弹性碰撞
- java碰撞小球
- java实现小球碰撞反弹
- 五十道编程小题目 --- 10 反弹的小球 java
- android练习:碰撞的小球
- Java简单游戏开发之碰撞检测
- Java中如何监测两个物体是否碰撞?
- 【java】控制小球的移动,保证小球不出边界
- html5使用canvas实现小球碰撞反弹实例
- 如鹏java学习进程 模拟小球弹跳
- 用Java实现小球碰壁反弹的简单实例(算法十分简单)
- java入门第六天之跟屁虫小球
- 一个与小球碰撞有关的有趣问题
- 案例-多个小球碰撞