疯狂贪吃蛇JAVA实现课程设计报告.pdf
安阳工学院安阳工学院计算机科学与信息工程学院计算机科学与信息工程学院JAVAJAVA 程序设计课程综合项目报告程序设计课程综合项目报告项目题目:疯狂贪吃蛇专业班级:11 计科信息学生姓名:潘 强学生学号:201103020005指导教师姓名: 许研2013 年 12 月2目录一、系统目标. 3二、系统设计思路.3三、系统详细设计.4四、系统实现. 8五、系统设计总结.14六、参考文献.153疯狂贪吃蛇疯狂贪吃蛇一、系统目标一、系统目标运用 java 技术开发出贪吃蛇游戏,这个程序是用一个小矩形表示蛇的一节身体,身体每长一节,增加一个矩形块。移动时必须从蛇头开始,也就是蛇尾不能改作蛇头。当游戏者按了方向键后,蛇头朝着指定的方向移动,一步移动一节身体。 图形的实现是从蛇头的新位置开始画出蛇。用户可以用上下左右键控制蛇头的方向。非常简单!可以实现如下功能:1. 贪吃蛇游戏是大家很常见的小游戏,在生活工作之余大家可以玩它,已达到放松各种压力的目的。2. 游戏可以进行升级,也就是增加吃食物的难度,以便使大家更有挑战性,不觉得太无趣。3. 游戏界面大小可以任意指定,数据从文件读入。4. 利用 swing 实现良好的 GUI 界面。二、系统设计思路二、系统设计思路1. 贪吃蛇是很经典的格子游戏。所谓格子游戏就是在设计游戏时的主要思想是每个设对象都是由格子组成,游戏运行界面也是由格子组成。格子思想决定了此类游戏在设计时的算法思想。2. 方向键控制一个方块的移动的方法,一个方块的移动是靠移动其坐标位置来实现的。3. 方向键控制是上下左右对一个方块的控制,用四个判断语句实现。4. 蛇的移动算法思想可以看成是第一个方块移动,第二个方块移到第一个方块的位置, 第三个方块移动到第二个方块的位置 第 N个方块移动到第N-1个方块的位置。这样连续的移动就是蛇的移动了。方向控制键控制了第一个方块的移动后,后面方块跟着移动 ,这样也实现了方向键控制对长蛇的移动。45. 食物的随机产生的方法食物的随机产生需要一个随机种子函数然后利用系统时间做为随机种子。6. 蛇的身体变长的方法当然要当蛇吃到食物时才能使身体变长。因此有两个需要解决的问题:问题一:如何知道是否吃到食物?问题二:吃到食物后身体变长?解决问题一的方法是需要一个判断语句, 当蛇头即构成蛇的第一个方块跟食物所在方块的坐标一样时判断吃到食物。解决问题二则要相对复杂一些,需要多个判断语句构成。7. 游戏结束的方法,当蛇碰到边框时或者吃到自己时游戏结束。根据这个思想可以用判断语句实现 。 然后是游戏结束后的处理,比如显示继续玩游戏还是退出游戏,并显示所吃到的食物的个数和时间等。三、系统详细设计三、系统详细设计【类的设计】1.创建的类的描述。1. LoginLogin 类,登陆界面要求输入登陆者输入用户名和密码,分别设 Go 和 Cancel两个登陆选项。LoginLogin属性: 用户名密码Go(进入游戏)Cancel(取消)操作: Enter()Close()2.SnakeFrame2.SnakeFrame 类,创建游戏窗口主界面。采用图形界面设计,有窗体,菜单栏和游戏操作界面。3.SnakeModel3.SnakeModel 类,此类为蛇的初始化状态及模型,所有的游戏的开始都通过此类初始化及对蛇的操作。SnakeModelSnakeModel属性: rows,cols,snakeHead,runingDiriction,locRO,snake,playBlockssnakeFood,gameScore,AddScore操作: LocationRO getSnakeHead(),LocationRO getSnakeTail(),Location getRuningDiriction(),LinkedList getSnake(),LinkedList getOthers(), getScore(),getAddScore(),setSnakeHead(Location snakeHead),LocationRO getSnakeFood(),setSnakeFood(), moveTo(Object a,LinkedList fromlist,LinkedList tolist),init(),SnakeModel(int rows1,int cols1),move(Location direction)4. SnakePanelSnakePanel 类,此类为游戏界面创建蛇的面板和蛇的移动控制实现。5SnakePanelSnakePanel属性: gridsPanel,row;col; gridsPanel;direction;snake;snakeBody;otherBlocks;snakeHead;snakeFood;gameScore=0; speed;AddScore; t;isEnd;notExit;操作: SnakePanel(SnakeFrame parent,int row,int col), newGame(long speed)stopGame(),returnGame(),getGameScore(),updateTextFiled(String str)updateColors(),run(),keyPressed(KeyEvent event)keyReleased(KeyEvent event),keyTyped(KeyEvent event)change(SnakeFrame parent,int row2, int col2)5. LocationROLocationRO 类,随机生成的食物位置。用来随机生成食物。引导蛇的移动方向。6. LocationLocation 类,对蛇的位置的描述类。LocationLocation属性: xy操作:Location(int x,int y) ,getX(),getY(),setX(int x),setY(int y) ,equalOrRev(Location e),equals(Location e) ,reverse(Location e)2.类之间的调用关系。【用户界面】1. 登陆界面2. 游戏主界面LoginLogin 登陆登陆SnakeFrameSnakeFrameLocationLocationSnakeModelSnakeModelSnakePanelSnakePanelLocationROLocationRO6【程序技巧】1. 为游戏设置权限,为游戏设置登陆界面。2. 游戏界面采用图形界面美观大方易操作。3. 功能齐全,可以选择开始,暂停,继续可以随时操控游戏状态,方便易操作,人性化设计。4. 设置菜单功能齐全,可以让界面显示网格和取消显示网格,还可以根据自己的实际能力情况选择游戏的等级。5. 窗口大小菜单可以根据自己的需要和爱好调整窗体的大小, 可以选择大中小三种窗体。适合不同的需要。6. 本程序设置了作者信息菜单可以查询程序的制作人的信息等。7. 对于新手用户,我为他们设置了操作指南菜单,帮助他们方便快捷的学会游戏的操作步骤。【模块划分及调用关系】7主要模块【模块流程图】1. 游戏界面模块和登陆模块流程图。开始登陆界面游戏界面取消登录退出程序结束开始登陆界面输入用户名和密码进入游戏取消登录设置作者信息结束游戏帮助窗口大小文件操作指南开始暂停继续等级显示网格视图软件信息中小大退出结束82. 游戏模块否是否是否是四、系统实现四、系统实现【测试数据】1. 游戏登陆测试,用户名:杨文,密码:123456.2. 进入主界面。3. 测试文件菜单;游戏开始,贪吃蛇窗墙则游戏结束;退出提示。4. 测试设置菜单。5. 测试窗口大小菜单。6. 测试作者信息菜单。7. 测试帮助菜单。【输出结果】1.登陆测试2.进入主界面是否碰到蛇身墙是否吃到食物蛇 身 加 长 , 分 数 增 加提示游戏结结束随机显示食物蛇蛇运动是否开始游戏开始创建贪吃蛇是否结束暂停93.测试文件菜单文件主界面1.菜单/开始102.贪吃蛇窗墙则游戏结束3.退出提示。文件/退出。114.测试设置菜单.5.测试窗口大小菜单。126. 测试作者信息菜单。137.测试帮助菜单。14五、系统设计总结五、系统设计总结通过一学期的学习,我自己认为自己学java没学好,而在整个新技术专题中我觉得贪吃蛇的游戏应该是最简单的。通过这次课程设计, 我对java又有了更深刻的认识。 也有了更深一步的喜爱,决定一定要努力学好java,并能更好的应用于以后的工作中。这次贪吃蛇的设计,我做的不是很完美,也没想象中的那么好,但也获得了许多宝贵的经验:1) 在设计程序之前,务必要对自己所要设计的题目和内容有一个系统的, 大概的了解,知道所设计的题目和内容包含哪些资源。152) 设计程序采用什么编程语言并不是非常重要,关键是要有一个清晰的思路和一个完整的软件流程图,所有要先把设计原理与思路搞清楚,再把流程图画出来,这样设计起来就简单多了。3) 在设计程序时,不能妄想一次就将整个程序设计好,“反复修改,不断改进”是程序设计的必经之路,发现错误也是取得成绩及成绩的一种必经之路。4) 要养成注释程序的好习惯,一个程序的完美与否不仅仅是实现功能,而应该让人一看就能明白自己的思路,这样也为资料的保存和交流提供了方便。在以后的学习和工作中,我希望我能把这些经验应用起来。为以后的工作顺利进行,也让自己获得一定的能力,能够拥有一份好的工作。六、参考文献六、参考文献1魏伟译JBuilder 开发人员指南M北京:机械工业出版社,2001.1.2胡雷, 叶曙光, 徐饪JBuilder 9.0 入门与提高M北京:机械工业出版社,2004.3田勇,孙新Jbuilder 开发人员指南M北京: 机械工业出版社,2001.4李尊朝,苏军.Java 语言程序设计(第二版)M.北京:中国铁道出版社2009.5黄晓东.Java 课程设计案例精编(第二版)M.北京:中国水利水电出版社,2008.6陆 光义,宋现锋 .Java 游戏编程导学 M. 北京:清华大学出版社.2004.附件:附件:详细代码详细代码1.1. LoginLogin 类类package SnakeGameDemo;import java.awt.Color;import java.awt.Container;import java.awt.Graphics;import java.awt.GridLayout;import java.awt.Image;import java.awt.Label;16import java.awt.Panel;import java.awt.TextField;import java.awt.Toolkit;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JOptionPane;import javax.swing.JPanel;/登陆界面public class Login extends JFrame private TextField f1;/创建文本框private TextField f2;private JButton b1;/创建按钮private JButton b2;public Login() /登陆界面Container cp=getContentPane();/获取容器cp.setLayout(new GridLayout(4,1);/设置布局管理为网格四行一列Label l1=new Label(用户名);/创建标签了 l1,l2Label l2=new Label(密码);Panel p1=new Panel();/创建面板,p1,p2,p3,p4Panel p2=new Panel();Panel p3=new Panel();MyPanel1 p4=new MyPanel1();/创建插入图片平面 p4f1=new TextField(10);f2=new TextField(10);f2.setEchoChar(*);/回显字符为* 用于输入密码, 设置为不可见17b1=new JButton(确定);/新建按钮 b1,b2b2=new JButton(取消);p1.add(l1);/第一行添加 label 1p1.add(f1);p2.add(l2);p2.add(f2);p3.add(b1);p3.add(b2);cp.add(p4);/面板 p4,p1,p2,p3 分别加入容器 cpcp.add(p1);cp.add(p2);cp.add(p3);b1.addActionListener(new Enter();/添加按钮事件响应b2.addActionListener(new Close();class Enter implements ActionListener public void actionPerformed(ActionEvent e) JButton bt=(JButton)e.getSource();if(f1.getText().equals(潘强)&(f2.getText().equals(123456)&bt=b1)JFrame.setDefaultLookAndFeelDecorated(true);SnakeFrame frame=new SnakeFrame();/创建游戏主界面frame.setSize(frame.col*11+11,frame.row*11+100);frame.setResizable(false);18frame.setLocation(500,200);/设置窗体位置frame.setTitle(疯狂贪吃蛇);frame.setVisible(true);else JOptionPane.showMessageDialog(null, 用户名或密码错误,请重新登录!);/错误用户提示class Close implements ActionListener /关闭登陆按钮响应public void actionPerformed(ActionEvent e) JButton bt=(JButton)e.getSource();if(bt=b2) System.exit(0);/退出/主函数 程序开始public static void main(String args) Login log=new Login();log.setTitle(疯狂贪吃蛇界面登陆);log.setBounds(500, 200, 300, 300);log.setBackground(Color.blue);log.setVisible(true);class MyPanel1 extends JPanel /插入登陆界面图片Imageimg=Toolkit.getDefaultToolkit().getImage(imgs/201.jpg);/ 添 加19图片public void paint(Graphics g) g.drawImage(img,0,0,this);2. SnakeFrame 类package SnakeGameDemo;import java.awt.Color;import java.awt.Container;import java.awt.FlowLayout;import java.awt.GridLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.ButtonGroup;import javax.swing.JCheckBoxMenuItem;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JMenu;import javax.swing.JMenuBar;import javax.swing.JMenuItem;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JRadioButtonMenuItem;import javax.swing.JTextField;import SnakeGameDemo.SnakePanel;20public class SnakeFrame extends JFrame implements ActionListenerint row=20;int col=30;SnakePanel p=new SnakePanel(this,row,col);JMenuBar menubar=new JMenuBar();/菜单条JMenu fileMenu=new JMenu(文件);/菜单JMenuItem newgameitem=new JMenuItem(开始);/菜单条目JMenuItem stopitem=new JMenuItem(暂停);JMenuItem runitem=new JMenuItem(继续);JMenuItem exititem=new JMenuItem(退出);/设置菜单JMenu optionMenu=new JMenu(设置);/* 等级选项* ButtonGroup创建一组按钮选项* JRadioButtonMenuItem 是属于一组菜单项中的一个菜单项,该组中只能选择一个项。* 被选择的项显示其选择状态。选择此项的同时,其他任何以前被选择的项都切换到未选择状态。* Panel 是最简单的容器类。应用程序可以将其他组件放在面板提供的空间内,这些组件包括其他面板。*/JMenu degreeMenu=new JMenu(等级);ButtonGroup groupDegree = new ButtonGroup();21JRadioButtonMenuItemoneItem=newJRadioButtonMenuItem(初级);JRadioButtonMenuItemtwoItem=newJRadioButtonMenuItem(中级);JRadioButtonMenuItem threeItem= new JRadioButtonMenuItem(高级);/ 设置“窗口大小”菜单JMenu windowsMenu = new JMenu(窗口大小);JMenu windowsMenu1 = new JMenu(视图);ButtonGroup groupDegree1 = new ButtonGroup();JRadioButtonMenuItemminItem=newJRadioButtonMenuItem(小);JRadioButtonMenuItemmidItem=newJRadioButtonMenuItem(中);JRadioButtonMenuItemmaxItem=newJRadioButtonMenuItem(大);/ 设置“作者信息”菜单JMenu XinXi=new JMenu(关于开发者);JMenuItem XinXiItem=new JMenuItem(软件相关);/设置“帮助”菜单JMenu helpMenu=new JMenu(帮助);JMenuItem helpItem=new JMenuItem(操作指南);/可以被选定或取消选定的菜单项.finalJCheckBoxMenuItemshowGridItem=newJCheckBoxMenuItem(显示网格);JLabel scorelabel;/为分数创建标签public JTextField scoreField;/显示分数的文本框private long speedtime=200;private String helpstr = 游戏说明:n1 :方向键控制蛇移动22的方向.+n2 :单击菜单文件-开始开始游戏.+n3 :单击菜单文件-暂停或者单击键盘空格键暂停游戏.+n4 :单击菜单文件-继续继续游戏.+n5 :单击菜单设置-等级可以设置难度等级.+n6 :单击菜单设置-显示网格可以设置是否显示网格.+n7 :红色为食物,吃一个得 10 分同时蛇身加长.+n8 :蛇不可以出界或自身相交,否则结束游戏.;SnakeFrame() setJMenuBar(menubar);fileMenu.add(newgameitem);fileMenu.add(stopitem);fileMenu.add(runitem);fileMenu.add(exititem);menubar.add(fileMenu);oneItem.setSelected(true);/设置可选择groupDegree.add(oneItem);groupDegree.add(twoItem);groupDegree.add(threeItem);degreeMenu.add(oneItem);degreeMenu.add(twoItem);degreeMenu.add(threeItem);optionMenu.add(degreeMenu);minItem.setSelected(true);groupDegree1.add(minItem);groupDegree1.add(midItem);groupDegree1.add(maxItem);windowsMenu1.add(minItem);23windowsMenu1.add(midItem);windowsMenu1.add(maxItem);windowsMenu.add(windowsMenu1);/ 风格选项showGridItem.setSelected(true);optionMenu.add(showGridItem);menubar.add(optionMenu);helpMenu.add(helpItem);XinXi.add(XinXiItem);menubar.add(windowsMenu);menubar.add(XinXi);menubar.add(helpMenu);Container contentpane=getContentPane();contentpane.setLayout(new FlowLayout();/设置布局管理contentpane.add(p);scorelabel=new JLabel(得分: );scoreField=new JTextField(0,15);scoreField.setEnabled(false);scoreField.setHorizontalAlignment(0);/设置图标和文本的水平对齐方式JPanel toolPanel=new JPanel();toolPanel.add(scorelabel);toolPanel.add(scoreField);contentpane.add(toolPanel);/事件监听 使得按钮可以响应24oneItem.addActionListener(this);twoItem.addActionListener(this);threeItem.addActionListener(this);minItem.addActionListener(this);midItem.addActionListener(this);maxItem.addActionListener(this);newgameitem.addActionListener(this);stopitem.addActionListener(this);runitem.addActionListener(this);exititem.addActionListener(this);XinXiItem.addActionListener(this);helpItem.addActionListener(this);showGridItem.addActionListener(this);public void actionPerformed(ActionEvent e)/ 事件响应从接口 ActionListener 复制的描述 ,发生操作时调用。try/异常捕获if(e.getSource()=helpItem)JOptionPane.showConfirmDialog(p,helpstr,操纵说明,JOptionPane.PLAIN_MESSAGE);else if(e.getSource()=exititem)JOptionPane.showConfirmDialog(null,你确定退出游戏吗?, ,JOptionPane.YES_NO_OPTION);25elseif(e.getSource()=newgameitem)p.newGame(speedtime);else if(e.getSource()=stopitem) p.stopGame();else if(e.getSource()=runitem) p.returnGame();else if(e.getSource()=showGridItem) if(!showGridItem.isSelected() p.setBackground(Color.lightGray);/ 设 置 背 景颜色elsep.setBackground(Color.darkGray);else if(e.getSource()=oneItem) speedtime=200;else if(e.getSource()=twoItem) speedtime=100;else if(e.getSource()=threeItem) speedtime=50;else if(e.getSource()=minItem)row=20;col=30;p.change(this,row,col);this.setSize(col*11+11,row*11+100);else if(e.getSource()=XinXiItem)JOptionPane.showMessageDialog(this,疯狂贪吃蛇nn 安阳工学院n 计算机科学与信息工程学院n计算机科学与技术+n 信息方向 11-1n 学号:201103020005 +n 姓名:潘 强n 指导老师:许研n2013 年 12 月,软件相关,JOptionPane.INFORMATION_MESSAGE);else if(e.getSource()=midItem)row=30;col=45;26p.change(this,row,col);this.setSize(col*11+11,row*11+100);else if(e.getSource()=maxItem) row=40;col=60;p.change(this,row,col);this.setSize(col*11+11,row*11+100);catch(Exception ee)ee.printStackTrace();/异常处理2.SnakeModelpackage SnakeGameDemo;import java.util.LinkedList;import javax.swing.JOptionPane;publicclass SnakeModel private int rows,cols;/行列数private Location snakeHead,runingDiriction;/运行方向private LocationRO locRO;/LocationRO 类数组private LinkedList snake,playBlocks;/蛇及其它区域块private LocationRO snakeFood;/目标食物private int gameScore=0;/分数private boolean AddScore=false;/加分/获得蛇头public LocationRO getSnakeHead()return (LocationRO)(snake.getLast();27/蛇尾public LocationRO getSnakeTail()return (LocationRO)(snake.getFirst();/运行路线public Location getRuningDiriction()return runingDiriction;/获得蛇实体区域public LinkedList getSnake()return snake;/其他区域public LinkedList getOthers()return playBlocks;/获得总分public int getScore()return gameScore;/获得增加分数public boolean getAddScore()return AddScore;/设置蛇头方向private void setSnakeHead(Location snakeHead)this.snakeHead=snakeHead;28/获得目标食物public LocationRO getSnakeFood()return snakeFood;/随机设置目标食物private void setSnakeFood()snakeFood=(LocationRO)(playBlocks.get(int)(Math.random()*playBlocks.size();/移动privatevoidmoveTo(Objecta,LinkedListfromlist,LinkedListtolist)fromlist.remove(a);tolist.add(a);/初始设置public void init()playBlocks.clear();snake.clear();gameScore=0;for(int i=0;irows;i+)for(int j=0;jcols;j+)playBlocks.add(locROij);29/初始化蛇的形状for(int i=4;i7;i+)moveTo(locRO4i,playBlocks,snake);/蛇头位置snakeHead=new Location(4,6);/设置随机块snakeFood=new LocationRO(0,0);setSnakeFood();/初始化运动方向runingDiriction=new Location(0,1);/Snake 构造器public SnakeModel(int rows1,int cols1)rows=rows1;cols=cols1;locRO=new LocationROrowscols;snake=new LinkedList();playBlocks=new LinkedList();for(int i=0;irows;i+)for(int j=0;jcols;j+)locROij=new LocationRO(i,j);init();/*定义布尔型 move 方法, 如果运行成功则返回 true,否则返回 false/ *参数 direction 是 Location 类型,/ *direction 的值:(-1,0)表示向上;(1,0)表示向下;30/ *(0,-1)表示向左;(0,1)表示向右;/ */public boolean move(Location direction)/判断设定的方向跟运行方向是不是相反if (direction.reverse(runingDiriction)snakeHead.setX(snakeHead.getX()+runingDiriction.getX();snakeHead.setY(snakeHead.getY()+runingDiriction.getY();elsesnakeHead.setX(snakeHead.getX()+direction.getX();snakeHead.setY(snakeHead.getY()+direction.getY();/如果蛇吃到了目标食物tryif (snakeHead.getX()=snakeFood.getX()&(snakeHead.getY()=snakeFood.getY()moveTo(locROsnakeHead.getX()snakeHead.getY(),playBlocks,snake);setSnakeFood();gameScore+=10;AddScore=true;31elseAddScore=false;/是否出界if(snakeHead.getX()rows)&(snakeHead.getY()=0&(snakeHead.getY()=0)/如果不出界,判断是否与自身相交if(snake.contains(locROsnakeHead.getX()snakeHead.getY()/如果相交,结束游戏JOptionPane.showMessageDialog(null,GameOver!, 游戏结束, JOptionPane.INFORMATION_MESSAGE);return false;else/如果不相交,就把 snakeHead 加到 snake 里面,并且把尾巴移出moveTo(locROsnakeHead.getX()snakeHead.getY(),playBlocks,snake);moveTo(snake.getFirst(),snake,playBlocks);else/出界,游戏结束JOptionPane.showMessageDialog(null, Game Over!,游戏结束, JOptionPane.INFORMATION_MESSAGE);32return false;catch(ArrayIndexOutOfBoundsException e)return false;/设置运行方向if (!(direction.reverse(runingDiriction)|direction.equals(runingDiriction)runingDiriction.setX(direction.getX();runingDiriction.setY(direction.getY();return true;4.SnakePanelpackage SnakeGameDemo;import java.awt.Color;import java.awt.GridLayout;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.util.Iterator;import java.util.LinkedList;import javax.swing.JFrame;import javax.swing.JPanel;33publicclassSnakePanelextendsJPanelimplementsRunnable,KeyListenerJFrame parent=new JFrame();private int row;/网格行数 30-34160-671 40-451private int col;/列数private JPanel gridsPanel;/面板网格private Location direct