【课程设计报告】JAVA实现华容道智力游戏 有源码(word版) .doc
课程设计(论文)任务书 软 件 学 院 学院 软件+电子商务 专业 2 班 一、课程设计(论文)题目 华容道一个传统的智力游戏 二、课程设计(论文)工作自 2010 年 12 月 20 日起至 2010 年 12 月 24 日止。三、课程设计(论文) 地点: 软 件 学 院 实 训 中 心 四、课程设计(论文)内容要求:1本课程设计的目的(1)掌握Java语言的程序设计方法; (2)理论联系实际,进一步提高学生的软件开发技术;(3)培养学生分析、解决问题的能力;(4)提高学生实践论文撰写能力。2课程设计的任务及要求1)课程设计任务:用java语言编写一个华容道小游戏2)创新要求:在基本要求达到后,可进行创新设计3)课程设计论文编写要求(1)课程设计任务及要求(2)设计思路-工作原理、功能规划(3)详细设计-数据分析、算法思路、类设计、功能实现(含程序流程图、主要代码及注释)、界面等。(4)运行调试与分析讨论-给出运行屏幕截图,分析运行结果,有何改进想法等。(5)设计体会与小结-设计遇到的问题及解决办法,通过设计学到了哪些新知识,巩固了哪些知识,有哪些提高。(6)参考文献(必须按标准格式列出,可参考教材后面的参考文献格式)(7)报告按规定排版打印,要求装订平整,否则要求返工;(8)课设报告的装订顺序如下:封面-任务书-中文摘要-目录-正文-附录(代码及相关图片)(9) 严禁抄袭,如有发现,按不及格处理。4)课程设计评分标准: (1)学习态度:10分;(2)系统设计:20分;(3)编程调试:20分;(4)回答问题:20分;(5)论文撰写:30分。5)参考文献:(1)丁振凡. Java语言实用教程(第2版)M. 北京邮电大学出版社. 2008.1 (2)丁振凡. Java语言实用教程实验指导(第2版)M. 北京邮电大学出版社. 2008.1(3)杨树林等. Java语言最新实用案例教程(第2版)M. 清华大学出版社. 2010.76)课程设计进度安排1准备阶段(4学时):选择设计题目、了解设计目的要求、查阅相关资料2程序模块设计分析阶段(4学时):程序总体设计、详细设计3代码编写调试阶段(8学时):程序模块代码编写、调试、测试4撰写论文阶段(4学时):总结课程设计任务和设计内容,撰写课程设计论文学生签名: 2010 年 12 月 20 日课程设计(论文)评审意见(1)学习态度(10分):优()、良()、中()、一般()、差(); (2)系统设计(20分):优( )、良()、中()、一般()、差(); (3)编程调试(20分):优()、良()、中()、一般()、差();(4)回答问题(20分):优()、良()、中()、一般()、差();(5)论文撰写(30分):优()、良()、中()、一般()、差(); 评阅人: 职称: 讲师 2010 年 12 月 25 日中文摘要华容道,古老的中国游戏,以其变化多端、百玩不厌的特点与魔方、独立钻石棋一起被国外智力专家并称为“智力游戏界的三个不可思议”。游戏就是依照“曹瞒兵败走华容,正与关公狭路逢,只为当初恩义重,放开金锁走蛟龙”这一故事情节设计,受到很多玩家的喜爱。该程序用Java语言编写 ,棋盘上有10个不一样大小的按钮,分别代表曹操、张飞、赵云、马超、黄忠和关羽,还有四个兵。棋盘最下方有两个空着的小方格,代表曹操逃出的位置,可以实现通过鼠标或者键盘移动界面上的按钮,最终使曹操移动到棋盘最下方,代表曹操逃出华容道。 目录一、课程设计任务及要求1二、需求分析2三、设计思路3四、详细设计4五、运行调试与分析讨论14六、设计体会与小结16七、参考文献17一、课程设计任务及要求 1、 本程序主要练习使用布局管理器设计一个华容道游戏界面,并练习使用事件监听器(鼠标事件、键盘事件和焦点事件)实现按钮的移动。 2、编写一个按钮的子类,使用该子类创建的对象代表华容道中的人物。通过焦点事件控制人物颜色,当人物获得焦点时颜色为红色,当失去焦点时颜色为黄色。 3、通过键盘事件和鼠标事件来实现曹操、关羽等人物的移动。当人物上发生鼠标事件或键盘事件时,如果鼠标指针的位置是在人物的下方(也就是组件的下半部分)或按下键盘的“键,该人物向下移动。向左、向右和向上的移动原理类似。 4、点击“重新开始”可以使各个按钮复位,重新开始游戏。二、需求分析要满足的容道游戏的基本操作:1 各人物按钮按相应的顺序和大小排列,按钮上标注人物名字,界面美观。2 通过焦点事件控制人物按钮的颜色,得到焦点呈红色,失去焦点为淡黄色。3 可以通过键盘控制各个按钮的移动:按“”键,人物按钮向下移动其它方向类似。4 可以通过鼠标点击来控制各个人物按钮的移动:如果点击的位置在按钮的上半部分则向上移动,如果点击按钮的下半部分则向下,左右原理类似。5 有“重新开始按钮” 点击重新开始按钮各个人物按钮复位,能重新开始游戏。6 小程序能够自由的缩小,放大,关闭。三、设计思路 1.首先是界面设计,该界面主要包括十个人物按钮(马、曹操、关羽等)以及旁边的四个边框按钮和重新开始按钮。对于人物按钮,创建Button按钮的子类,在该类中定义按钮的一些新的属性和焦点事件监听器,如:按钮的标签名、按钮的颜色、按钮的排号(如这里有十个人物按钮,从1排到十,在程序中可以依靠这个属性区分人物按钮)、按钮颜色、按钮获得或失去焦点事件。同时在设计该界面时要考虑到各个按钮的位置、大小等情况。 2.对界面上的各人物按钮添加相应的相应事件焦点事件:通过焦点事件各个按钮的是焦点。鼠标事件、键盘事件:通过这两种事件去完成界面上各人物按钮的移动。对重新开始按钮定义动作事件(ActionEvent)完成界面初始化功能也 就是各人物按钮重新归位。四、详细设计1.类的设计本程序总共有3个类(1)MoveExample 类public class MoveExample public static void main(String args)/定义主方法 new Hua_Rong_Road();/创建一个Hua_Rong_Road对象 (2)Person 类 增加焦点事件监视器:addFocusListener(事件监听器)当组件具有焦点监视器后,如果组件从无输入焦点变成有输入焦点或从有输入焦点到无输入焦点都会触发FocusEvent事件。创建监视器的类必须要实现FocusListener接口,该接口有两个方法:public void focusGained(final FocusEvent e) /获得焦点触发public void focusLost(final FocusEvent e) /失去焦点触发当组件从无输入焦点变成有输入焦点并触发FocusEvent事件时,监视器调用类实现的接口方法focusGained(FocusEvent e);当组件从有输入焦点变成无输入焦点并触发FocusEvent事件时,监视器调用类实现方法focusLost(FocusEvent e)。 class Person extends Button implements FocusListener int number; Color c=new Color(255,245,170);/设置颜色/preson 方法 public Person(final int number,final String s) super(s); setBackground(c);/背景色 this.number=number; c=getBackground(); addFocusListener(this);/事件焦点监听 public void focusGained(final FocusEvent e) /获得焦点触发 setBackground(Color.red);/获得焦点的颜色 public void focusLost(final FocusEvent e) /失去焦点触发 setBackground(c); (3)Hua_Rong_Road 类 游戏界面主要包括十个人物按钮马、曹操、关羽等。对于人物按钮,在该类中定义按钮的一些新的属性和焦点事件监听器,如:按钮的标签名、按钮的颜色、按钮的排号(如这里有十个人物按钮,从1排到十,在程序中可以依靠这个属性区分人物按钮)、按钮颜色、按钮获得或失去焦点事件。同时在设计该界面时要考虑到各个按钮的位置、大小等情况。class Hua_Rong_Road extends Frame implements MouseListener,KeyListener,ActionListener Person person=new Person10; Button left,right,above,below; Button restart=new Button("重新开始");/添加重新开始按钮 Hua_Rong_Road()方法设置容器 public Hua_Rong_Road() init();/设置按钮 setBounds(100,100,320,360);/组件在容器上的起点和长宽 setVisible(true);/ 像控件中添加元素 validate();/刷新 addWindowListener(new WindowAdapter()/注册窗口事件监听 public void windowClosing(WindowEvent e)/关闭 System.exit(0); ); init()方法 设置10个按钮 public void init() setLayout(null);/设置布局默认 add(restart);/添加重新开始 restart.setBounds(100,320,120,25);/按钮大小 restart.addActionListener(this);/注册监听 String name="曹操","关羽","张飞","刘备","赵云","黄忠","兵 ","兵","兵","兵" for(int k=0;k<name.length;k+) personk=new Person(k,namek);/为每个按钮加上名字 personk.addMouseListener(this);/每个按钮都注册鼠标事件监听 /*鼠标事件的类型是MouseEvent,即组件触发鼠标时,MouseEvent类自动创建一个事件对象。Java分别使用MouseListener接口来处理鼠标事件。MouseListener接口可以处理5种鼠标事件:单击、按下、释放、进入和退出。*/personk.addKeyListener(this);/注册键盘事件监听/*当按下、释放或敲击键盘上一个键时就发生了键盘事件,如:当一个组件处于激活状态时(获得焦点),敲击键盘上一个键就导致了这个组件发生了键盘事件。事件源使用addKeyListener方法获得监视器。*/*KeyEvent类的public int getKeycode()方法和public char getKeychar()判断哪个键被按下、敲击或释放。*/ add(personk);/加上人物按钮 /为每一个人物按钮设置位置和大小 person0.setBounds(104,54,100,100); person1.setBounds(104,154,100,50); person2.setBounds(54,154,50,100); person3.setBounds(204,154,50,100); person4.setBounds(54,54,50,100); person5.setBounds(204,54,50,100); person6.setBounds(54,254,50,50); person7.setBounds(204,254,50,50); person8.setBounds(104,204,50,50); person9.setBounds(154,204,50,50); person9.requestFocus();/把焦点先设置在这个按钮上 /*其次来画出游戏界面的边框,用定义的left,right,above,below,来控制大小*/ left=new Button(); right=new Button(); above=new Button(); below=new Button(); add(left); add(right); add(above); add(below); left.setBounds(49,49,5,260); right.setBounds(254,49,5,260); above.setBounds(49,49,210,5); below.setBounds(49,304,210,5); validate();/刷新 经过以上操作就完成了界面的布局得到的界面如图一所示: 图一:界面布局 接下来就要为各个按钮注册事件监听 :鼠标事件和键盘事件 键盘事件:KeyEvent为键盘事件的类型,KeyListener是事件监视器实现的接口,其中有三种相应事件:按键、释放键、按下和释放的组合事件。Public void KeyPressed(KeyEvent e)Public void KeyTyped(KeyEvent e)Public void KeyReleased(KeyEvent e)如下: public void keyTyped(KeyEvent e) public void KeyReleased(KeyEvent e) 因为要实现人机交互的效果,所以要响应键盘事件,这一操作是在函数public void keyPressed(KeyEvent e)中完成的:首先通过语句Person man=(Person)e.getSource()获取事件源,然后通过语句if(e.getKeyCode()=KeyEvent.VK_DOWN)响应用户按向下光标的操作,通过语句if(e.getKeyCode()=KeyEvent.VK_LEFT)响应用户按向左光标的操作,通过语句if(e.getKeyCode()=KeyEvent. VK_RIGHT)响应用户按向右光标的操作,通过语句if(e.getKeyCode()=KeyEvent. VK_UP)响应用户按向上光标的操作。*/ public void KeyPressed(KeyEvent e) Person man=(Person)e.getSource();/返回事件源/*用KeyEvent类的getKeycode()方法和getKeychar()判断哪个键被按下、敲击或释放。*/ if(e.getKeyCode()=KeyEvent.VK_DOWN) go(man,below); if(e.getKeyCode()=KeyEvent.VK_UP) go(man,above); if(e.getKeyCode()=KeyEvent.VK_LEFT) go(man,left); if(e.getKeyCode()=KeyEvent.VK_RIGHT) go(man,right); 鼠标事件: public void mouseReleased(MouseEvent e) public void mouseEntered(MouseEvent e) public void mouseExited(MouseEvent e) public void mouseClicked(MouseEvent e) /响应鼠标事件, 通过鼠标点击的位置判断是像那个方向移动 public void mousePressed(MouseEvent e) Person man=(Person)e.getSource(); int x=-1,y=-1; x=e.getX(); y=e.getY(); int w=man.getBounds().width; int h=man.getBounds().height; if(y>h/2) go(man,below); if(y<h/2) go(man,above); if(x<w/2) go(man,left); if(x>w/2) go(man,right); 用 go方法控制人物按钮上下左右移动:鼠标点击想要移动的人物,使用键盘上,下,左,右来控制人物的移动。(需要鼠标以及键盘的响应)。通过向上的响应来使得人物向上走,并判断是否与其他人物重叠,若重叠则返回上单元,若不重叠的继续。通过向上的响应来使得人物向下走,并判断是否与其他人物重叠,若重叠则返回上单元,若不重叠的继续。通过向上的响应来使得人物向左走,并判断是否与其他人物重叠,若重叠则返回上单元,若不重叠的继续。当前人物向上与其他人物不重叠,则向上前进五十单元。当前人物向下与其他人物不重叠,则向下前进五十单元。当前人物向左与其他人物不重叠,则向左前进五十单元。通过向上的响应来使得人物向右走,并判断是否与其他人物重叠,若重叠则返回上单元,若不重叠的继续。当前人物向右与其他人物不重叠,则向右前进五十单元。 public void go(Person man,Button direction) boolean move=true; Rectangle manRect=man.getBounds(); int x=man.getBounds().x; int y=man.getBounds().y; if(direction=below)/向各个方向上的移动 y=y+50; else if(direction=above) y=y-50; else if(direction=left) x=x-50; else if(direction=right) x=x+50; manRect.setLocation(x,y); Rectangle directionRect=direction.getBounds(); for(int k=0;k<10;k+) Rectangle personRect=personk.getBounds();if(manRect.intersects(personRect)&&(man.number!=k)/如果覆盖就不移动 move=false; if(manRect.intersects(directionRect) move=false; if(move=true) /移动到新的位置 man.setLocation(x,y); 发生操作时调用: public void actionPerformed(ActionEvent e) dispose(); new Hua_Rong_Road(); 2. 流程图如图二:图二:流程图五、运行调试与分析讨论运行结果1. 运行小程序如图3所示: 图三2. 点击按钮使按钮获得焦点如图四所示: 图四3.用鼠标或者键盘移动人物按钮如图五: 图五4. 点击重新开始按钮后如图六所示: 图六 六、 设计体会与小结 通过本程序,我练习使用布局管理器设计了一个华容道游戏界面,并且练习使用事件监听器监听焦点的得失,首先增加焦点事件监视器:addFocusListener(事件监听器),当组件具有焦点监视器后,如果组件从无输入焦点变成有输入焦点或从有输入焦点到无输入焦点都会触发FocusEvent事件。创建监视器的类必须要实现FocusListener接口,该接口有两个方法:public void focusGained(FocusEvent e) /获得焦点触发public void focusLost(FocusEvent e) /失去焦点触发 练习了通过鼠标事件实现按钮的移动,鼠标事件的类型是MouseEvent,即组件触发鼠标时,MouseEvent类自动创建一个事件对象。Java分别使用MouseListener接口与MouseMotionListener接口来处理鼠标事件。MouseListener接口可以处理5种鼠标事件:单击、按下、释放、进入和退出。MouseMotionListener接口可以处理2种鼠标事件:拖动、移动。 练习了通过键盘事件实现按钮的移动,当按下、释放或敲击键盘上一个键时就发生了键盘事件,当一个组件处于激活状态时(获得焦点),敲击键盘上一个键就导致了这个组件发生了键盘事件。事件源使用addKeyListener方法获得监视器。KeyEvent为键盘事件的类型,KeyListener是事件监视器实现的接口,其中有三种相应事件:按键、释放键、按下和释放的组合事件。Public void KeyPressed(KeyEvent e)Public void KeyTyped(KeyEvent e)Public void KeyReleased(KeyEvent e) 用KeyEvent类的public int getKeycode()方法和public char getKeychar()判断哪个键被按下、敲击或释放。七、参考文献1 作者:丁振凡 . 参考书籍名称M:java语言实用教程. 出版地: 北京邮电大学出版社.出版年限:2007.2 作者:耿祥义 . 参考书籍名称M: Java基础教程 . 出版地: 清华大学出版社.出版年限:2009. 附录(源码清单)import java.awt.*;import java.awt.event.*;public class MoveExample public static void main(String args) new Hua_Rong_Road(); class Person extends Button implements FocusListener int number; Color c = new Color(255,245,170); Person(int number,String s) super(s); setBackground(c); this.number = number; c = getBackground(); addFocusListener(this); public void focusGained(FocusEvent e) setBackground(Color.red); public void focusLost(FocusEvent e) setBackground(c); class Hua_Rong_Road extends Frame implements MouseListener,KeyListener,ActionListener Person person = new Person10; Button left,right,above,below; Button restart = new Button("重新开始"); public Hua_Rong_Road() init(); setBounds(100,100,320,360); setVisible(true); validate(); addWindowListener( new WindowAdapter() public void windowClosing(WindowEvent e) System.exit(0); ); public void init() setLayout(null); add(restart); restart.setBounds(100,320,120,25); restart.addActionListener(this); String name = "曹操","关羽","张飞","刘备","赵云","黄忠","兵","兵","兵","兵" for(int k = 0;k<name.length;k+) personk = new Person(k,namek); personk.addMouseListener(this); personk.addKeyListener(this); add(personk); person0.setBounds(104,54,100,100); person1.setBounds(104,154,100,50); person2.setBounds(54,154,50,100); person3.setBounds(204,154,50,100); person4.setBounds(54,54,50,100); person5.setBounds(204,54,50,100); person6.setBounds(54,254,50,50); person7.setBounds(204,254,50,50); person8.setBounds(104,204,50,50); person9.setBounds(154,204,50,50); person9.requestFocus(); left = new Button(); right = new Button(); above = new Button(); below = new Button(); add(left); add(right); add(above); add(below); left.setBounds(49,49,5,260); right.setBounds(254,49,5,260); above.setBounds(49,49,210,5); below.setBounds(49,304,210,5); validate(); public void keyTyped(KeyEvent e) public void keyReleased(KeyEvent e) public void keyPressed(KeyEvent e) Person man = (Person)e.getSource(); if(e.getKeyCode()=KeyEvent.VK_DOWN) go(man,below); if(e.getKeyCode()=KeyEvent.VK_UP) go(man,above); if(e.getKeyCode()=KeyEvent.VK_LEFT) go(man,left); if(e.getKeyCode()=KeyEvent.VK_RIGHT) go(man,right); public void mousePressed(MouseEvent e) Person man = (Person)e.getSource(); int x = -1,y = -1; x = e.getX(); y = e.getY(); int w = man.getBounds().width; int h = man.getBounds().height; if(y>h/2) go(man,below); if(y<h/2) go(man,above); if(x<w/2) go(man,left); if(x>w/2) go(man,right); public void mouseReleased(MouseEvent e) public void mouseEntered(MouseEvent e) public void mouseExited(MouseEvent e) public void mouseClicked(MouseEvent e) public void go(Person man,Button direction) boolean move = true; Rectangle manRect = man.getBounds(); int x = man.getBounds().x; int y = man.getBounds().y; if(direction=below) y = y+50; else if(direction=above) y = y-50; else if(direction=left) x = x-50; else if(direction=right) x = x+50; manRect.setLocation(x,y); Rectangle directionRect = direction.getBounds(); for(int k = 0;k<10;k+) Rectangle personRect = personk.getBounds(); if(manRect.intersects(personRect)&&(man.number!=k) move = false; if(manRect.intersects(directionRect) move = false; if(move=true) man.setLocation(x,y); public void actionPerformed(ActionEvent e)