1、 中南大学 Java课程设计汇报 题 目 打字游戏 学生姓名 窦立阳 指导老师 陈丽萍 学 院 信息科学和工程学院 专业班级 计科1204 完成时间 1月15日 目录 第
2、一章 试验要求 ..................................................3 第二章 总体设计 2.1 界面设计 ..................................................4 2.2 运行步骤 ..................................................4 2.3 逻辑设计 ..................................................4 2.4 积分设计 ..............................
3、4 第三章 具体设计 3.1 主面板 ....................................................5 3.1.1 两个按键 ............................................5 3.1.2 相关全局变量 ........................................5 3.1.3 全局变量说明 ........................................5 3.1.4 相关全局函数 .........
4、7 3.2 字符下落模块 ..............................................7 3.2.1 WordLabel ............................................7 3.2.2 WordFallControl ......................................8 3.2.3 WordFallLabel ........................................8 3.3 速度控制模块 .
5、8 3.4 按键模块设计 ..............................................8 3.5 键盘监听事件 ..............................................9 3.6 积分模块设计 ..............................................9 3.7 事件模块设计 .............................................10 第四章 调试分析
6、 4.1 第一次调试 ...............................................11 4.2 第二次调试 ...............................................11 4.3 第三次调试 ...............................................12 第五章 运行结果 .................................................13 第六章 课程设计总结 .....................................
7、17 第七章 参考文件 .................................................19 第八章 附录:带注释源代码 8.1 Wordfall ................................................20 8.1.1 WordFallControl类 .....................................20 8.1.2 WordLabel类 ...........................................22 8.1.3 WordFall
8、Label类 .......................................23 8.2 ScoreLabel类 ............................................24 8.3 StartButton类 ...........................................25 8.4 TimeLabel类 .............................................26 8.5 AAAAA类:程序主函数入口 ...............................28
9、 8.6 Maintain类 .................................................30 第一章 试验要求 【问题描述】设计实现一个打字游戏,界面参见图2-2,含有以下功效: l 点击“开始”按钮,产生随机字符从屏幕上方下落; l 点击键盘上按钮,假如正确,目前字符消失,产生新按钮从上方继续落下。 l 提供速度调整和积分功效。 图2-2 打字游戏界面 第二章 总体设计 2.1 界面设计 依据试验要求中图2-2,在主面板中, 1.1
10、1 有一个模块控制各个字符生成而且控制她们自动下落,并在正确触发时,字符不可见; 1.1.2有一个模块用于设置下落速度; 1.1.3有两个按键,分别为“开始”和“结束”,用于字符下落开始和结束; 1.1.4整个面板处于键盘事件监听中,所以还有一个模块负责监听键盘事件; 1.1.5对应,依据要求,会有一个模块用于将键盘事件和下落字符进行操作,而且计算出积分。 2.2 运行步骤 1.2.1 程序开启,程序等候按键“开始”事件触发; 1.2.2 当“开始”键触发后,负责字符下落模块,将连续产生字符,并使其下落; 1.2.3 键盘开始被监听,从键盘按键触发,向程序返回值; 1.
11、2.3 积分模块开始工作,将字符下落模块字符和键盘事件返回值进行比较,得出积分,而且将积分值显示在面板上; 1.2.4 假如点击“停止”按键,全部模块停止工作,等候程序关闭,或等候“开始”按键事件再次触发,从1.2.1继续这一步骤。 2.3 逻辑设计 1.3.1 字符不停产生而且下降,需要一个线程控制产生字符,然后还应该有一个线程对面一个字符,控制其下落。 1.3.2 键盘被按下后,立即会有值返回到程序中,积分模块会每隔一段时间将,键盘事件返回值,和目前需要按下值进行比较。 2.4 积分说明 当开始产生字符后,会有很多字符全部是可输入,不过目前可输入字符只有一个,所以
12、能够考虑设计一个链表,没当产生一个字符,便将该字符存入链表中,而且有一个指针永远指向目前需要输入值。 因为界面大小有限,当字符连续下落超出界面大小时,不能够经过玩家来猜测,已经不见目前需要输入字符,所以当界面上字符超出十个时,便认为该玩家反应时间过长,判定其为错误,而且将目前需要输入字符设置为下一个。而且从游戏角度考虑,当这种情况出现3次后,便能够判定本轮游戏结束。 第三章 具体设计 3.1 主面板 public class GameFrame extends JFrame 主面板中关键包含是两个按键,各个组件在面板上部署,和其它全局变量设置。 3.1.1两个按键 JBu
13、tton btnStart = new JButton()
JButton btnStop= new JButton()
ScoreLabel scoreLabel
KeyEventPanel keyEventPanel
WordFallLabel wordFallLabel
JSlider slider
3.1.2相关全局变量
boolean START_FLAG = false;
ArrayList
14、rayList
15、s.clear(); CHAR_VALUE = 0; KEY_VALUE = 0; POINTER = 0; MAXFALSE = 3; SUCCESSTIME = 0; TRYTIME = 3; } 3.1.3全局变量说明: START_FLAG: 因为在程序开启时,各个组件就已经开始工作,用START_FLAG使她们经过if语句,不做任何动作,当START_FLAG == true时,便能够开始进行游戏,避免了反复开启线程可能会造成意外情况麻烦。 CODE_LIST: 在游戏线程开
16、启后,会产生很多字符,这些字符若存放在局部空间内,很有可能会出现其它组件需要调用该值而且需要经过一系列传值过程才能实现,将这些值放在一个公共空间内列表中,即使会出现安全上面问题,不过无疑为程序实现降低了很多工作,宽且这也只是一个游戏,在安全上问题能够忽略。 wordLabels: 这个全局变量设置,关键是为了实现下落字符消失。产生字符会放在label中,经过控制label行为来控制字符行为。将每一个WordLabel实例放在该列表中,能够经过在其它空间控制来实现自己想法。 CHAR_VALUE: 里面存放是产生字符值,每一个字符全部能够经过ASCII码转变为一个整数类型值,经过比较整数
17、值来确定是否匹配。 KEY_VALUE: 存放了最近一次从键盘内取得值,因为可能出现连续出现相同字符情况,KEY_VALUE里值必需定时清空,考虑以后,和每次在每次比较完以后进行清空操作比较适宜。 POINTER: 在CODE_LIST中会有很多数,不过目前正确值,只有一个,那就是POINTER指向位置,经过判定KEY_VALUE和CHAR_VALUE值,对POINTER进行操作,具体操作会在ScoreLabel中说明。 MAXFALSE,TRYTIME: 最大失误次数,当超出这个次数时,当局游戏就会结束。 SUCCESSTIME: 本轮目前成功次数,统计成功次数用来积分。
18、SPEED: 控制字符下落速度,这个值会和难度条上值含有映射关系。 3.1.4全局方法说明: public static void init(); 在新一轮游戏开始前,全局变量中值任然是上一轮数据,需要对其中数据进行初始化,设置为公共方法便于调用,其中操作全部是必需操作,无多出也无漏缺。 3.2 字符下落模块 3.2.1 public class WordLabel extends JLabel{}: 这个类关键负责创建一个下落字符。因为共有26个字母和10个数字会在游戏中被记为字符,经过随机函数(int)(Math.random()*35) 产生36个随机数,依据ASCII
19、码规则,字符0-9对应职位48-57,依据产生值加上48,便能够得到字符0-9,同理字符A-Z对应值为65-90,依据产生值,因为是从10开始,所以加上55,就能够得到对应字母字符,每产生一个字符,便将该字符添加到CODE_LIST中,以作她用。 3.2.2 public class WordFallControl extends Thread{}: 在WordLabel被实例化后,需要有个方法控制其下落,因为会产生喝多字符,对众多字符进行统一管理,而且还要考虑到字符在其它情况下动作,太过复杂,所以在这个组件中,只考虑字符下落,每个字符交由一个控制对象控制。每过SD.SLEEP 毫秒时
20、间,WordLabel位置便会下移一个单位,这个单位设置为50 。交由线程使其实现连续下降。 3.2.3 public class WordFallLabel extends JLabel implements unnable{}: 将前两个组件进行组合便是这个类作用,只要这个实例运行正常,那么出现问题就不会是该模块问题,除非是出现对字符艺术化或是下落幅度改变这一类需求。 3.3 下落速度模块 JSlider slider = new JSlider(); JSlider自带方法个头getValue()能够取得滑块值,向滑块添加监听事件——addChangeListener()
21、在滑块移动时,能够将改变以后值映射到SD.SPEED上,以控制速度改变。滑块只能在一轮游戏开始前滑动,从程序实现角度考虑理由是,当移动滑块时,整个面板焦点便会由按键转移到滑块上来,这是键盘事件监听对象也会转移到这个滑块部件上来,这时候有两种方法:一是在游戏中不许可移动滑块,二是在滑块中添加键盘监听事件。相比较之下第一个简单而且符合大多数人操作习惯,完全能够施行。 3.4 按键模块设计 同上一小节所说焦点转移问题,将“开始”和“结束”设计为一个键,使整个面板焦点能够在游戏开始到游戏结束全部一直在同一个部件上,而且实现也很简单,只要连续监听START_FLAG值,分辨目前游戏状态,就能
22、确定是该显示“开始”或是”结束“了。 3.5 键盘监听设计 键盘事件不是要向text area 之类部件中输入字符,而是向KEY_VALUE赋值,重写KeyListener类,使键盘按下事件响应设置为KEY_VALUE = event.getKeyCode()。 3.6 积分模块设计 public class ScoreLabel extends JLabel implements Runnable 该模块包含到变量有KEY_VALUE,CHAR_VALUE,CODE_LIST,POINTER,SUCCESSTIME,TRYTIME。 此时键盘事件监听中,只要有按键被按下
23、就会给KEY_VALUE赋一个值,POINTER指向一个位置,将CODE_LIST.get(POINTER)值和KEY_VALUE比较假如相等,则POINTER值加一,指向列表中下一个值(假如列表中还有话),SUCCESSTIME加一;假如不相等,考虑这个值存在时间是否太长了,每个值全部只有10个单位周期生命这个能够经过列表长度判定出来,每个单位周期,全部会向列表中添加一个新字符,当CODE_LIST.size()-POINTER > 9时,POINTER自加一,指向下一个,TRYTIME减一,不然不进行任何操作。 3.7 时间模块设计 这部分关键是为了熟悉一边线程使用方法 publi
24、c class TimeLabel extends JLabel implements Runnable { /** * */ private static final long serialVersionUID = 1L; private Date date = new Date(); private SimpleDateFormat sdFormat = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss"); public TimeLabel(){ new Thread(this).start();
25、 } @Override public void run() { // TODO Auto-generated method stub int i = 0; while(i < 10){ try { date = new Date(); this.setText(sdFormat.format(date)); new Thread(); Thread.sleep(1000); } catch (Exception e) { // TODO: handle exception e.p
26、rintStackTrace(); } } } } 第四章 调试分析 几乎每写一个类就会调试一次,类里面修改也是很多,下面只是找了三次比较大改动进行说明。 4.1 第一次调试: 第一次调试没有,加入按钮和难度条,关键是为了确定程序主体 部分能够正确实施。 发觉问题有。一超出范围异常:在全部线程开启后,记分板会不 断调用CODE_LIST.get(POINTER)方法,在第一次成功输入后因为记 分板线程sleep时间短于,WordLabel产生线程sleep时间,所以, 列表内还没有第二个值时候便会要取
27、第二个,所以出现这个问题。二 START_FLAG在线程实施过程中何时判定问题,开始时是放在第一 位进行测试,不过线程会在进行到START_FLAG为false就结束,除 非重新实例化各个线程,不过,重新实例化又会在面板上添加新部件, 造成新建一个游戏面板,所以让游戏进程一直实施,碰到START_FLAG 为false是不做任何操作,线程并不中止。 4.2 第二次调试: 第二次调试也能够说是第二次大修改专题内容就是全局变量设 计。 伴随整个程序添加不见越来越多,将各部分产生值保留在局部, 而且调用get和set方法去取得值显得越来越麻烦,而且很多地方包含 到部件之间相互取值,如s
28、core label和word fall control 两块, score 需要里面字符值,而word fall 需要score里面对值判定 情况,方便字符在被按下后立即消失。需要在两个类中添加太多static 数据和方法,同时,静态变量和方法调用又出现了很多限制问题。 最终决定如3.1.1中列出一系列全局变量,大大简化了调用复杂度, 也使整个程序显得简练明了。 4.3 第三次调试: 第三次调试是这次试验中最简单问题,也是最复杂问题,经验问题。在一步一步添加完全部部件,而且对全部部件单独测试后,我发觉只关键点击开始按钮后,不能够正常监听键盘事件了。开始时,键盘监听事件是放在Wo
29、rdLabel中实施,在单独测试时不会有任何问题。 多方面查找资料也没有发觉类似问题。于是从书本上实例翻起,不经意想到,假如两个文本框同时显示却只能向取得焦点那个文本框内输入字符这个情况,瞬间清楚了问题所在。 在进行调整后,重新实施程序,已经能够完成预期目标。 第五章 运行结果 主在程序调试完成后,可使用稳定版本使用情况以下: 图6-1 打字游戏开始界面 图 6-1显示。程序开始时,左上角为记分板,没有任何数据显示;右上角为显示目前时间;中间部分使游戏关键界面,用来显示下落字符,因为游戏还未开始,没有任何显示;左下角是游戏开始按钮,目
30、前显示为“开始,”在点击后,变为“结束”,而且记分板开始积分,游戏住界面开始下落字符,参考图6-2;右下角为难度调整框能够设置难度,左低右高。 图6-2 打字游戏进行中 图 6-2显示。游戏正常开始后,记分板开始积分,会统计正确个数,假如超出时间为按下正确字符,剩下机会就会降低一次,在记分板最终面,会有提醒目前应该输入正确字符;游戏主界面会有字符连续落下,当按下正确字符后,该字符消失,正确字符更新;左下角按钮在点击使游戏开始后,变为“结束”按钮;右下角难度条,能够在游戏前移动,游戏中不能够移动,具体原因参考在第三章——具体设计中,设计键盘监听事件时候已经说明。 图6-3 打字游戏
31、正常退出 图 6-3 显示。当点击结束按钮后,左下角按钮将会变为“开始”按钮;记分板保持显示,用于玩家查看此次游戏成绩,游戏主界面上不会在产生下落字符,直到下轮游戏开始;该轮游戏产生字符继续下落完成,不过此时已经能够开始进行下轮游戏了。这点是设计上缺憾,在以后会进行修改使其愈加完善。 图6-4 打字游戏错误过多退出 图 6-4 显示。此次本轮游戏结束原因是错误过多,没有剩下机会了。玩家仍然能够在记分板上查看到自己成绩。左下角按钮也适时变为了”开始“按钮。 第六章 课程设计总结 此次试验内容选择是打字游戏,最终完成了试验要求内全部内容。 试验过程中,没
32、有借助外力,参考内容也只是Java API文档,在这一点上自己还是比较满意。 试验完成后,和其它同学比较情况是,美工不足,界面只是根据试验要求上例图设计,没有添加更有意思东西。 这次试验有两个小收获。一是加深对线程了解。在设计之初,出现一个最大问题就是在一个线程内添加了另外一个线程,而且副线程不是自开启,在根本程中止时,副线程也是出于终端状态,没有被实施到,经过数次断点测试发觉了这个问题,这个结论可能是错误,不过确实适适用于我碰到情况。二是发觉编程这个东西,跟技术有60%关系,跟知识贮备有30%关系,剩下10%就要看个人经验。30%看看书,查查资料就行。60%重视是对代码量考验。10%是对
33、代码复杂度考验,相同代码敲一万遍,也还是那样,时间长了不做,就忘了,各个组件全部能正常运行,组合在一起后却会出现焦点改变问题,假如不是这次碰到,而且发觉了,以后碰到类似问题,我还是不知道。这个问题即使简单,我也一直迟迟没有请教老师或同学,一是认为放不下脸,二也是锻炼一下自己思维能力,可能第一次处理没有碰到过问题会花费一天两天,第二次可能就是半天,而且自己发觉问题所在,在自己闹钟印象愈加深刻,自己也愈加有成就感。 大收获是,自己这次尝试着从结构层次角度考虑程序设。将整个程序分为各个组件,最终经过组件结合形成整个程序。程序简单,并没有很多层次,而且层次对程序关键性也不是那么显著,不过尝试着这么做
34、而且在以后每一次全部向这方面努力,我想对我程序员生活提升是会有很大帮助。 试验只需要选择一个试验完成,不过其它试验也是老师花费心思,想出来题目,比如说图形编辑系统,仿佛极少有些人选,不过看上去也是挺有意思,决定在寒假时候,着手实现以下,即使java优势并不在于此,不过从以上所说各个方面也很有必需。 第七章 参考文件 JDK1.5API_CN(全).chm:C:\Users\admin\Desktop\API\JDK1.5API_CN(全).chm 第
35、八章 附录:带注释源代码 本章附上整个课程设计游戏源代码,和相关测试代码。 相关组件: Component包: 8.1 Wordfall子包: 8.1.1 wordFallControl类:字符下落规律 package release.conponent.wordfall; import javax.swing.JLabel; import release.SD; public class WordFallControl extends Thread { private JLabel jLabel; private WordLabel wor
36、dLabel; private int x = 0; private int y = (int)(Math.random()*10); //control word label fall,where,who and how public WordFallControl(JLabel jLabel,WordLabel wordLabel){ this.jLabel = jLabel; this.wordLabel = wordLabel; this.jLabel.add(this.wordLabel); this.wordLabel.setBounds
37、 y*SD.WORD_LABEL_WIDTH,x*SD.WORD_LABEL_HEIGHT+50, SD.WORD_LABEL_WIDTH, SD.WORD_LABEL_HEIGHT ); new Thread(this).start(); } @Override public void run() { // TODO Auto-generated method stub while(x<10){ try { // in every SD.SPEED_ms,word label will fall one 50, x++;
38、 this.wordLabel.setBounds(y*SD.WORD_LABEL_WIDTH/5, x*SD.WORD_LABEL_HEIGHT, SD.WORD_LABEL_WIDTH, SD.WORD_LABEL_HEIGHT ); if(x == 9){ //when word label is beyond the frame,no one can see it,it contains nothing this.wordLabel.setText(null); } sleep(SD.SPEED); } ca
39、tch (Exception e) { e.printStackTrace(); } } super.run(); } package release.conponent.wordfall; import javax.swing.JLabel; import release.SD; public class WordFallLabel extends JLabel implements Runnable { /** * */ private static final long serialV
40、ersionUID = 1L; public WordFallLabel(){ setSize(500,500); new Thread(this).start(); System.out.println("world fall start"); } @Override public void run() { // TODO Auto-generated method stub int repeat = 0; //thread goes on constantly,if thread runs 100 times,it
41、will stop while(0<1&&repeat<100){ //if SD.START_FLAG is false,the thread will do nothing,just skip it if(SD.START_FLAG){ //characters and fall new WordFallControl(this, new WordLabel()); repeat++; try { new Thread(); Thread.sleep(SD.SPEED); } ca
42、tch (Exception e) { // TODO: handle exception e.printStackTrace(); } }else { try { new Thread(); Thread.sleep(SD.SPEED); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } } } } 8.1.2 w
43、ordFall类:产生可控制下落字符 package release.conponent.wordfall; import javax.swing.ImageIcon; import release.SD; public class WordLabel extends JLabel { /** * version 1.0 */ private static final long serialVersionUID = 1L; //初始化word label对象,里面值为用随机数产生字符 public WordLabel(){ setTex
44、t(getChar().toString()); setVisible(true); SD.wordLabels.add(this); } private Character getChar(){ //以相同概率取得一个数字 int random_integer = (int)(Math.random()*35); //将该数字经过ASCII码转为对应字符 char int_to_char = random_integer>9?(char)(random_integer+55):(char)(random_integer+48); //向SD.
45、CODE_LIST里面添加一个新生成word label SD.CODE_LIST.add(random_integer>9?random_integer+55:random_integer+48); return int_to_char; } } 8.1.3 WordFallLabel类:整合字符下落这个过程 package release.conponent.wordfall; import javax.swing.JLabel; import release.SD; public class WordFallLabel extends
46、 JLabel implements Runnable { /** * */ private static final long serialVersionUID = 1L; public WordFallLabel(){ setSize(500,500); new Thread(this).start(); System.out.println("world fall start"); } @Override public void run() { // TODO Auto-generated method
47、 stub int repeat = 0; //thread goes on constantly,if thread runs 100 times,it will stop while(0<1&&repeat<100){ //if SD.START_FLAG is false,the thread will do nothing,just skip it if(SD.START_FLAG){ //characters and fall new WordFallControl(this, new WordLabel());
48、 repeat++; try { new Thread(); Thread.sleep(SD.SPEED); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } }else { try { new Thread(); Thread.sleep(SD.SPEED); } catch (Exception e) { // TODO: handle
49、exception e.printStackTrace(); } } } } } 8.2 ScoreLabel类:用于统计得分 package release.conponent; import javax.swing.JLabel; import release.SD; public class ScoreLabel extends JLabel implements Runnable { /** * */ private static final long
50、serialVersionUID = 1L; // initialize the label public ScoreLabel(){ setText("天下武功,唯快不破"); new Thread(this).start(); System.out.println("scroe start"); } @Override public void run() { // TODO Auto-generated method stub //使线程连续实施 while(0<1){ try { new Thre






