课程设计报告题目弹球小游戏姓名方成学号20专业java指导教师陈华恩2013年12 月30目录一、实验目的 (2)二、需求分析 (2)三、实验任务 (2)1、设计 (3)2、程序要求: (3)3、选作题: (3)四、开发工具与平台 (3)五、设计思路 (3)1、界面设计 (3)2、逻辑设计 (3)3、程序测试 (4)六、实验总结 (5)七、程序代码 (5)八、参考文献 (11)1.《疯狂java讲义》 (12)2.《算法导论》 (12)3.《java编程思想》 (12)一、实验目的1、熟练掌握java面向对象编程。
2、掌握Swing图形用户界面编程以及事件处理等,掌握java绘图技术。
3、掌握timer类的灵活使用4、培养独立查找资料,并解决问题的能力。
二、需求分析经典的碰撞球是一个的古老游戏,目的是在训练人的反应能力。
只有通过把所有的砖块消除完,才能顺利的完成任务。
游戏要求如下:1、实现球速度的随机性2、实现球碰撞到边缘或者砖块自动反弹3、实现游戏可以随时暂停4、实现游戏结束后能重新开始游戏三、实验任务1、设计设计并编程实现弹球程序:用户能通过菜单或者按钮新增一小球,该小球将从随机的位置出现,并具有随机颜色,随机速度以及随机的运动方向,小球沿初始方向匀速运动,当碰到窗口边缘时,小球将依据受力原理改变运动方向(可简化考虑,受力只改变小球的运动方向,小球仍按照初始速度匀速运动,且不考虑小球之间的碰撞)。
2、程序要求:(1)具备相应界面,并通过事件编程,实现相应的菜单或者按钮功能。
(2)使用timer,在程序窗口区域绘制小球,并以线程控制小球的移动,实现动画效果。
3、选作题:(1)实现奖励机制及关卡机制四、开发工具与平台JDK1.6+eclipse五、设计思路1、界面设计首先建立窗口类继承自JFrame。
该界面为主界面。
在加上按钮—开始与暂停在加入JPanel面板,用于图形界面.2、逻辑设计程序用过响应timer事件,按钮事件及键盘事件来管理程序的运行。
3、程序测试六、实验总结1、这次实验综合运用了GUI 编程,使我对多线程编程有了一定的了解,对java 的多线程机制有了一点理解,更加熟练的运用swing 组件设计界面,响应消息,接口的实现等等。
2、通过课程设计的编程和对编程过程中遇到的问题的思考,切实的提高了我的编程能力,通过这次课程设计,我巩固所了学过的知识,能用JAVA 熟练地运用其中的一些,进一步掌握了各个指令的功能是转向。
七、程序代码package com.fangcheng.ball.game;import java.awt.Font;import java.awt.event.*;import javax.swing.*;import java.util.ArrayList;import java.util.Random;public class BallGame extends JFrame implementsActionListener,KeyListener{private JPanel p;private JButton start;private JButton stop;private JLabel ball;private JLabel qiupai;private JLabel bg;//用来放置背景图片的JLabelprivate JLabel win;private JLabel over;private int x1=50;private int x2=15;private int y1=325;private int y2=340;//球与球拍的初始位置private Timer time;//周期性触发球的移动事件的timer对象private boolean isRight=false;//球是否向右移动private boolean isDow=false;//球是否为下降private boolean isOver=false;//是否游戏结束private boolean isYi=false;//球拍是否能移动private int xsudu=3;private int ysudu=3;//球的x,y速度,初始值为3private Random ran=new Random();//用于随机产生球的x,y速度private ArrayList<JLabel> removeBrickList;//被移除的砖块的list private ArrayList<JLabel> brickList; //游戏时砖块的listprivate Font font;/*** 构造器,参数为窗口标题* @param s*/public BallGame(String s){s uper(s);g ameShow();}/*** 用于游戏窗口绘制的方法*/public void gameShow(){//初始化组件I mageIcon img1=newImageIcon(BallGame.class.getResource("/images/ball.png"));I mageIcon img2=newImageIcon(this.getClass().getResource("/images/pa.png"));I mageIcon img3=newImageIcon(this.getClass().getResource("/images/kuang.png"));I mageIcon img4=newImageIcon(this.getClass().getResource("/images/win.gif"));I mageIcon img5=newImageIcon(this.getClass().getResource("/images/over.png"));I mageIcon img6=newImageIcon(this.getClass().getResource("/images/brick.gif"));I mageIcon img7=newImageIcon(this.getClass().getResource("/images/brick1.png"));I mageIcon img8=newImageIcon(this.getClass().getResource("/images/brick2.png"));f ont=new Font("微软雅黑", Font.PLAIN, 12);b all=new JLabel(img1);q iupai=new JLabel(img2);b g=new JLabel(img3);w in=new JLabel(img4);o ver=new JLabel(img5);p=new JPanel();s tart=new JButton("开始");s top=new JButton("暂停");s tart.setFont(font);s top.setFont(font);t ime=new Timer(10,this);b rickList=new ArrayList<JLabel>();r emoveBrickList=new ArrayList<JLabel>();//初始化砖块f or(int i=0;i<27;i++){JLabel temp;if(i%6==0)//用来给砖块加载不同的图片temp=new JLabel(img6);else if(i%6==1)temp=new JLabel(img7);else if(i%6==2)temp=new JLabel(img8);else if(i%6==3)temp=new JLabel(img7);else if(i%6==4)temp=new JLabel(img8);elsetemp=new JLabel(img6);brickList.add(temp);}//将砖块添加至面板f or(int i=0;i<brickList.size();i++){if(i<9){brickList.get(i).setBounds(25*i+10, 15, 20, 20);}else if(i<18){brickList.get(i).setBounds(25*(i-9)+10, 40, 20, 20);}else if(i<27){brickList.get(i).setBounds(25*(i-18)+10, 65, 20, 20);}p.add(brickList.get(i));}//置空布局管理器t his.setLayout(null);p.setLayout(null);//绝对位置布局组件p.setBounds(0, 0, 240, 500);s tart.setBounds(50, 400, 60, 30);s top.setBounds(140, 400, 60, 30);t his.setBounds(450, 100,246, 465);b all.setBounds(x1, y1, img1.getIconWidth(), img1.getIconHeight());q iupai.setBounds(x2, y2, img2.getIconWidth(),img2.getIconHeight());b g.setBounds(0, 0,img3.getIconWidth(), img3.getIconHeight());o ver.setBounds(10, 30, img4.getIconWidth(), img4.getIconHeight());w in.setBounds(10, 30, img5.getIconWidth(), img5.getIconHeight());//先将胜利与结束标签设为不可见o ver.setVisible(false);w in.setVisible(false);//添加监视器s tart.addActionListener(this);s top.addActionListener(this);q iupai.addKeyListener(this);//添加键盘监视器(为了防止焦点丢失造成的问题,将所有组件都添加键盘监视器)p.addKeyListener(this);s tart.addKeyListener(this);s top.addKeyListener(this);t his.addKeyListener(this);//加载组件p.add(ball);p.add(qiupai);p.add(over);p.add(win);p.add(bg);t his.add(start);t his.add(stop);t his.add(p);t his.setResizable(false);t his.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e){System.exit(0);}});t his.setVisible(true);}/*** 主程序入口* @param args*/public static void main(String[] args) {new BallGame("碰撞球");}/*** 发生操作的监视器*/public void actionPerformed(ActionEvent e) {if(e.getSource().equals(start)){if(isOver){x1=qiupai.getX()+30;y1=qiupai.getY()-15;//当游戏结束时按开始按钮,即二次开始游戏时将球的位置至于球拍上isOver=false;over.setVisible(false);win.setVisible(false);//遍历remove列表,将上次游戏移除的砖块再次绘制到面板(添加至bricklist)for(int i=0;i<removeBrickList.size();i++){removeBrickList.get(i).setVisible(true);brickList.add(removeBrickList.get(i));}}isYi=true;time.start();}else if(e.getSource().equals(stop)){if(!isOver){time.stop();//只有当游戏没有结束时,才能暂停}}else{//遍历砖块listfor(int i=0;i<brickList.size();i++){//如果小球与砖块发生重叠,将砖块从list里移除if(ball.getX()>=brickList.get(i).getX()&&ball.getX()<=brickList.g et(i).getX()+20&&ball.getY()<=brickList.get(i).getY()+20){//将需要移除的砖块保存到被移除的砖块的removeBrickListremoveBrickList.add(brickList.get(i));brickList.get(i).setVisible(false);brickList.remove(i);isDow=true; //与砖块碰撞后改变y轴方向}}//如果list空,则说明游戏胜利if(brickList.size()==0){win.setVisible(true);time.stop();isOver=true;}if(y1<340){//如果球的y轴超过该数值,则表明球已经掉到球拍下面,即游戏结束if(isDow){if(isRight){x1+=xsudu;y1+=ysudu;}else{x1-=xsudu;y1+=ysudu;}}else{if(isRight){y1-=ysudu;x1+=xsudu;}else{x1-=xsudu;y1-=ysudu; //绘制球的运动轨迹}}if(x1>210) //超出范围改变左右方向i sRight=false;//如果小球与球拍发生重叠,小球反弹。