《2022年安卓程序设计报告 .pdf》由会员分享,可在线阅读,更多相关《2022年安卓程序设计报告 .pdf(8页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、弹球游戏物联一班谢鑫 20100740123 一、实验目的1、掌握 Swing 图形用户界面编程以及事件处理等,掌握java 绘图技术。2、掌握多线程编程的基本原理,能使用Runnable、ExecutorService等接口进行线程的创建、启动等工作。二、实验任务设计并编程实现弹球游戏:用户能通过 GUI组件指定生成小球的数量,每个小球将从随机的位置出现,并具有随机颜色, 随机速度以及随机的运动方向,小球沿初始方向匀速运动, 当碰到窗口边缘时, 小球将依据受力原理改变运动方向(可简化考虑, 受力只改变小球的运动方向,小球仍按照初始速度匀速运动,且不考虑小球之间的碰撞)。鼠标在界面中显示为方块
2、状, 玩家需按住鼠标来回移动以避开运动的小球及屏幕四周,如果鼠标碰到任一小球或者窗口四周,则游戏结束。程序需提供计时功能,并最终显示玩家能坚持多少秒。三、设计思路1.界面设计(1)制作一个简单的面板JFrame ,文件保存为 bollFrame.java 其中为一 public 的类 bollFrame,其构造方法为:bollFrame(int n) super(); setTitle( 我的弹球小游戏 );setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Dimension dimension = Toolkit.getDefaultToolki
3、t().getScreenSize();/得到电脑屏幕大小setSize(450,450); setLocation(dimension.width-game.getWidth()/2-250, (dimension.height-game.getHeight()/2-250);/设置面板显示基中;this.n = n; myBollPanel = new bollPanel(n);/构造一个画板;add(myBollPanel);/将画板放入 JFrame createMenu();/创建菜单;setJMenuBar(bar); (2)构造画板类,文件保存为bollPanel.java 名师
4、资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 8 页 - - - - - - - - - 其构造函数如下:bollPanel(int n) this.n = n; / executorThread = Executors.newCachedThreadPool();/ 创建线程池;mouse = new mouseThread(mxNow,myNow,groupThread,this);/ 启动鼠标线程;this.setIsOver(false);/ 游戏开始线程条件的判断
5、;for(int i =0 ;in;+i) myBollThread =new bollThread(this); groupThread.add(myBollThread); /executorThread.execute(myBollThread);/ 小球线程加入线程池; addMouseListener(this); addMouseMotionListener(this); Paint()方法如下构造:public void paint(Graphics g) if(!this.getIsOver() /如果游戏还没结束; super.paint(g);/清除原先的图像g.setCo
6、lor(Color.RED); g.setFont(new Font(宋体,Font.BOLD+Font.ITALIC,15); g.drawString(你已坚持: +getT()+S, 15, 15);/ 计时器的显示;for(int i = 0;i(getWidth()-23)|xNow(getHeight()-23)|yNow0)/ 碰到上下边界;groupThread.get(i).dy = -groupThread.get(i).dy; groupThread.get(i).setxNow(xNow+groupThread.get(i).getdx();/ 设置下一个位置;grou
7、pThread.get(i).setyNow(yNow+groupThread.get(i).getdy(); if(isMouse) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 8 页 - - - - - - - - - g.drawImage(new ImageIcon(boll.gif).getImage(), mxNow, myNow, 40,40, this);/鼠标的图像; /end paint(); 总体界面如下:2.逻辑设计(1).首先,我们考虑到多个
8、小球的运动,实质上是多线程的使用,n 个小球我们就同时启动 n 个线程去控制每个小球的运动。 因此我构造出一个类作为一个小球的线程,保存文件为bollThread.java,顾名思义,小球线程类。相关构造方法如下:public bollThread(bollPanel my) this.myPanel = my; xStart = data.nextInt(200);/随机产生开始位置;yStart = data.nextInt(200); setxNow(xStart);/设置现在的位置;setyNow(yStart); setdx();/设置随机方向使用; 注意:若不设置为随机,则所有小球
9、将相同一个方向运动;setdy(); (2)再次,小球的出现需要有载体,这就是画板,前面界面设置中已提到过,通过让多个小球共享一个画板, 以及通过线程控制小球的重绘, 最后通过画板显示给用户。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 8 页 - - - - - - - - - (3)在第(2)点中提到的画板上我们需要实现鼠标的监听,以下给出几个重要的鼠标事件监听:public void mousePressed(MouseEvent e) / 单击启动鼠标事件;if
10、(e.getButton()=MouseEvent.BUTTON1) copy.schedule(new task(), 0,1000);/ 启动定时器;for(int i =0 ;i(this.getWidth()-30)|mxNow(this.getHeight()-30)|myNow=0)/ 鼠标是否碰到边界;/ executorThread.shutdown(); this.setIsOver(true); copy.cancel(); JOptionPane.showMessageDialog(null, 你撞墙了,下次小心点。 。 。游戏结束 ,提示 ,JOptionPane.OK
11、_OPTION); this.removeMouseListener(this); this.removeMouseMotionListener(this); for(int i =0 ;in;+i) int xNow =groupThread.get(i).getxNow(); int yNow = groupThread.get(i).getyNow(); if(isPeng(xNow,yNow,mxNow,myNow) / executorThread.shutdown(); this.setIsOver(true); copy.cancel(); JOptionPane.showMes
12、sageDialog(null, if(你撞球名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 8 页 - - - - - - - - - 了)+n+ 挑战失败,游戏结束 ., 提示 ,JOptionPane.OK_OPTION); /System.exit(0); this.removeMouseListener(this); this.removeMouseMotionListener(this); / 鼠标的上下左右边和球碰撞的情况, (4) 如果游戏开始后我们突然松
13、开鼠标,让我们控制的小球(或眼睛)停留在最后松开的点上, 那么小球碰到它还会判断是否相撞吗?答案是可以的,我们可以通过编写一个鼠标线程类来实现,保存文件为mouseThread.java ;让此线程在我们按下鼠标开始游戏时同时启动,在我们松开鼠标时启动判断相撞事件。相关的构造方法如下:mouseThread(int mxNow,int myNow,Listgroup,bollPanel bollpane) this.mxNow = mxNow;/ 传入鼠标现在位置;this.myNow = myNow; this.groupThread = group;/ 传入小球线程组;this.bollp
14、ane = bollpane;/传入画板对象; 3.程序测试在程序测试中,先后测试出了,以下几个注意点:A.在判断小球与鼠标控制的小球 ( “眼睛” )相撞时,条件中用到两点之间的距离问题,发现条件不能是两点距离刚好等于两相撞物体半径和,此条件太苛刻, 可能引起判断的失误(概率蛮高的呵呵) ,而应该是小于半径和。B.在小球碰撞或控制的小球(”眼睛“)碰到边界游戏结束时,已经停止了线程,小球竟然还能动, 而且是缓慢移动, 但是判断是否碰撞及边界问题都能正常执行,与我所意料的完全相反,到现在也不知道是怎么回事,只能在paint() 里进行条件判断,只让bollPanel 留下最后一次的个小球及“眼
15、睛”位置。C.这是最后才调试出来的,也是这个游戏中较难注意到的。就是一些 boolean变量的设置: privatebooleanisTime; / 定时器是否启动;privatebooleanisGroupThread; / 所有小球线程组是否启动;privatebooleanisMouseThread; / 鼠标线程是否启动;privatebooleanisMouse; / 鼠标事件是否启动;privatebooleanisOver; / 游戏是否结束;刚开始时并没有注意到这些, 如果我点击鼠标左键开始游戏时,启动了小球线程,这时要设置变量isGroupThread = true标志小球线
16、程组已启动,释放鼠标启动鼠标线程时,isMouseThread = true让鼠标线程来控制与小球相撞的判断,定时器也在这时响应启动isTime =true开始计时,若不设置这些 的话,将发生以下本质上的共同错误::等我释放鼠标后想再次控制小球,就必须在一次启动鼠标事件,这时将重新启动一次计时器, 重新启动一次小球线程组, 重新启动鼠标线程; 这样的结果名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 8 页 - - - - - - - - - 是导致游戏的结果不确定性,
17、没碰到小球 (实际上已碰撞 )它就检测碰撞结束游戏。以及计时器的计时紊乱等。具体调试后的相关代码实现见附录.。五、实验总结通过这次的程序设计,我更加明白了学以致用的道理,对线程的应用使得我更好更快的掌握了线程的本质, 同时,在此次的程序设计中, 经过不断地调试,是我明白了一个程序或项目要做到“精致”,是是需要花多大的精力和耐心,总之,学以致用,会将学到的知识应用到实际中才是学之根本。此次实验也更了解到了线程的知识,比如:一个线程stop后,不能再用 start启动,而应当重新实例化,在start()。也就是说 线程的状态转换过程(新建-就绪-运行-阻塞-死忙)是不可逆的 ,这是个人理解,至少从
18、本实验中可以得到验证。最后,感谢老师的指导和同学们对我的帮助。六、附录以下是调试后的相关算法实现:A: public boolean isPeng(int xNow,int yNow,int mxNow,int myNow)/利用两点之间的距离算法,判断是否撞球int x1 = xNow+15,y1 = yNow+15; int x2 = mxNow+20,y2 = myNow+20; int mulx = x1-x2,muly = y2 -y1; double sum = Math.pow(muly, 2)+Math.pow(mulx, 2); if(sumMath.pow(35, 2) r
19、eturn true; else return false; B: public void paint(Graphics g) if(!this.getIsOver() /在此判断游戏是否结束; super.paint(g);/清除原先的图像g.setColor(Color.RED); g.setFont(new Font(宋体,Font.BOLD+Font.ITALIC,15); g.drawString(你已坚持: +getT()+S, 15, 15); for(int i = 0;i(getWidth()-23)|xNow(getHeight()-23)|yNow0)/ 碰到上下边界;g
20、roupThread.get(i).dy = -groupThread.get(i).dy; groupThread.get(i).setxNow(xNow+groupThread.get(i).getdx(); groupThread.get(i).setyNow(yNow+groupThread.get(i).getdy(); if(isMouse) g.drawImage(new ImageIcon(boll.gif).getImage(), mxNow, myNow, 40,40, this); /end paint(); C : (1)public void mousePressed
21、(MouseEvent e) / 单击启动鼠标事件;if(e.getButton()=MouseEvent.BUTTON1) if(isMouseThread)/鼠标线程是否活着;mouse.stop(); isMouseThread = false; if(!isTime) copy.schedule(new task(), 0,1000);/ 启动定时器;isTime = true; if(!isGroupThread) for(int i =0 ;i(this.getWidth()-30)|mxNow(this.getHeight()-30)|myNow=0)/ 鼠标是否碰到边界; /
22、executorThread.shutdown(); this.setIsOver(true); copy.cancel(); JOptionPane.showMessageDialog(null, 你撞墙了,下次小心点。 。游戏结束 , 提示 ,JOptionPane.OK_OPTION); this.removeMouseListener(this); this.removeMouseMotionListener(this); for(int i =0 ;in;+i) int xNow =groupThread.get(i).getxNow(); int yNow = groupThrea
23、d.get(i).getyNow(); if(isPeng(xNow,yNow,mxNow,myNow) / executorThread.shutdown(); this.setIsOver(true); copy.cancel(); JOptionPane.showMessageDialog(null, if(你 撞 球了)+n+挑战失败,游戏结束 .,提示 ,JOptionPane.OK_OPTION); /System.exit(0); this.removeMouseListener(this); this.removeMouseMotionListener(this); /鼠标的上下左右边和球碰撞的情况, 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 8 页,共 8 页 - - - - - - - - -