1、java版的贪吃蛇毕业论文贪吃蛇【1】姓名:摘要:本文用J2SE实现大家耳熟能详的一个贪吃蛇游戏来综合运用所学知识,本游戏运用软件工程思想(螺旋模型),打好游戏主体框架,JAVA的面向对象思想,封装类,接口等概念,来完成本游戏,打到综合运用知识的目的。本游戏开发平台:WINXP;JAVA开发环境: JDK1.6 +Eclipse;开发语言:J2SE关键词:中央控制器;游戏面板;食物;蛇;石头The Greed SnakeAbstract:In this paper, J2SE implementation of a Snake game familiar to the integrated u
2、se of what they have learned, this game is the use of software engineering thinking (spiral model), the main framework of the fight game, JAVA object-oriented thinking, wrapper classes, interface concepts to complete this game, hitting the integrated use of knowledge and purpose. The game developmen
3、t platform: WINXP;. JAVA Development Environment: JDK1.6 + Eclipse;. Development Languages: J2SEKeywords:Controller;GamePanel;Food;Snake;Ground前言贪吃蛇游戏背景:蛇引诱夏娃吃了苹果之后,就被贬为毒虫,阴险的象征。 而蛇吃东西是整只动物吞进去的,大概在文艺复兴的时候(好象是那个时候但是不确定)就有人发明的一种游戏,是现在贪吃蛇的前身。后来慢慢的发展就变成了今天的贪吃蛇了、现在贪吃蛇主要应用于手机游戏。本文运用软件工程思想、JAVA面向对象编程、类的封装、
4、抽象类的使用(接口),游戏编码规范遵循MVC模式,循序渐进实现贪吃蛇的相关功能。一 :游戏中的面向对象分析与设计 涉及到几个对象(类) 每个类有什么方法1 . 首先得有个游戏显示面板(GamePanel)类该类有一个方法void display(); /用来显示游戏面板2 . 得有个蛇(Snake)类该类有以下几个方法:void move(); /移动(走一步)void changeDirection(); /改变方向void eatFood(); /吃食物(身体变长)voolean is EatBody();/蛇是否吃到了自己的身体void drawMe();/显示3 . 一个食物类(Foo
5、d)类该类有以下方法:boolean is SnakeEatFood(Snake); /判断蛇是否吃到了食物void drawMe();/显示4 . 一个背景石头(Ground)类该类有以下方法:Boolean isSnakeEatRock(Snake); /蛇是否吃到了石头void drawMe();/显示此时类之间的关系如下图所示:图1各个类之间的关系二 :编写贪吃蛇游戏中的各个类的主体框架性代码本有序遵循MVC(Model-View-Controller)所以首先建立以上几个实体类并定义相应的包名:liang.snake.entities包下定义Food、Ground、Snake 三个类
6、,再在liang.snake.view包下定义GamePanel类,再在,按照以上说明的各个类具有的方法,写上如下代码:package liang.snake.entities;publicclass Food publicboolean isSnakeEatFood(Snake snake) System.out.println(Snakes eat food);returnfalse;publicvoid drawme() System.out.println(Foods drawme); package liang.snake.entities;publicclass Ground pu
7、blicboolean isSnakeEatRock() returnfalse; publicvoid drawme() System.out.println(Grounds drawme); package liang.snake.entities;publicclass Snake publicvoid move() System.out.println(Snakes move); publicvoid changeDirection(int direction) System.out.println(Snakes changeDirection); publicvoid eatFood
8、() System.out.println(Snakes eat food); publicboolean isEatBody() System.out.println(Snakes eat body);returnfalse; publicvoid drawMe() System.out.println(Snakes drawMe);package liang.snake.view;import java.awt.Graphics;import javax.swing.JPanel;import liang.snake.entities.Food;import liang.snake.ent
9、ities.Ground;import liang.snake.entities.Snake;publicclass GamePanelextends JPanelprivate Snake snake;private Ground ground;private Food food;publicvoid paintComponent(Graphics g) snake.drawMe();ground.drawme();food.drawme();publicvoid display(Snake snake,Ground ground,Food food) this.snake=snake;th
10、is.ground=ground;this.food=food; System.out.println(GamePanels display);this.repaint(); 三 : 编写Controler类与实现蛇移动的事件监听 由于蛇不能直接操作显示面板(GamePanel)所以这里定义一个监听器SnakeListener:里面定义一个方法:void snakeMove(Snake); 每当蛇移动一步就触发监听器,调用snakeMoved()由Controller去实现监听器的接口,然后由控制器去触发显示面板的事件源,让显示面板完成相应操作。逻辑图如下:图2事件监听建立联系在Snake 中
11、增加蛇的方向常量:publicstaticfinalintUP=1;publicstaticfinalintDOWN=-1;publicstaticfinalintLEFT=2;publicstaticfinalintRIGHT=-2;并添加一个接口:package liang.snake.Listener;import liang.snake.entities.Snake;publicinterface SnakeListener publicvoid SnakeMove(Snake snake);Controler 实现SnakeListener接口并处理案件消息:代码如下:package
12、 liang.snake.Controller;import java.awt.event.KeyAdapter;import java.awt.event.KeyEvent;import liang.snake.Listener.SnakeListener;import liang.snake.entities.Food;import liang.snake.entities.Ground;import liang.snake.entities.Snake;import liang.snake.view.GamePanel;publicclass Controller extends Key
13、Adapter implements SnakeListenerSnake snake=new Snake();Ground ground=new Ground(); Food food=new Food(); GamePanel gamepanel=new GamePanel();public Controller(Snake snake, Ground ground, Food food, GamePanel gamepanel) this.snake = snake;this.ground = ground;this.food = food;this.gamepanel = gamepa
14、nel;publicvoid keyReleased(KeyEvent e) switch(e.getKeyCode()case KeyEvent.VK_UP :snake.changeDirection(Snake.UP);break;case KeyEvent.VK_DOWN :snake.changeDirection(Snake.DOWN);break;case KeyEvent.VK_LEFT :snake.changeDirection(Snake.LEFT);break;case KeyEvent.VK_RIGHT :snake.changeDirection(Snake.RIG
15、HT);break;publicvoid newgame()snake.start();publicvoid SnakeMove(Snake snake) gamepanel.display(snake,ground,food);开发到此时,Snake中应该增加监听器,并另启动一个线程来不断调用蛇的move();在Snake中提供一个启动线程的方法,在Snake中增加如下代码:private Set listener=newHashSet(); publicvoid addSnakeListener(SnakeListener l) if(l!=null)this.listener.add(l
16、); publicvoid start() new Thread(new SnakeDriver().run(); 并在Run方法中增加for(SnakeListener l: listener)l.SnakeMove(Snake.this);tryThread.sleep(1000); catch (InterruptedException e) e.printStackTrace();四 :编写对各个类进行测试的程序代码构建一个新类Game来测试程序代码:package liang.snake.Game;import java.applet.AudioClip;import java.aw
17、t.BorderLayout;import java.io.File;import .MalformedURLException;import .URL;import javax.swing.JFrame;import liang.snake.Controller.Controller;import liang.snake.entities.Food;import liang.snake.entities.Ground;import liang.snake.entities.Snake;import liang.snake.view.GamePanel;publicclass Game pub
18、licstaticvoid main(String args) JFrame jf=new JFrame(我的论文);Snake snake=new Snake(); Ground ground=new Ground(); Food food=new Food(); GamePanel gamepanel=new GamePanel(); Controller controller=new Controller(snake, ground, food, gamepanel); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.setLo
19、cation(400, 0); jf.setSize(800, 600); jf.add(gamepanel); jf.addKeyListener(controller); snake.addSnakeListener(controller); jf.setVisible(true); controller.newgame();运行这个带有main()的类,在Eclipse 的Console窗口中可以看到如下信息:Snakes moveGamePanels displaySnakes drawMeGrounds drawmeFoods drawmeSnakes drawMeGrounds d
20、rawmeFoods drawmeSnakes moveGamePanels displaySnakes drawMeGrounds drawmeFoods drawme这就意味着,当蛇移动一次,就触发监听器,有控制器(controller)给GamePanel发送指令,让它重画,GamePanel中的publicvoid display(Snake snake,Ground ground, Food food) System.out.println(GamePanels display);this.snake=snake;this.ground=ground;this.food=food;t
21、his.repaint();这个方法依次画出几个实体,所以打印出上述信息。到了这一步我们的基本框架打好了,下面开始第5步五 : 蛇的数据结构设计与移动显示 分析:要区分蛇头和蛇尾巴,这就要求这个数据结构是有序的,还要经常访问第一个和最后一个节点,所以LinkedList最合适,因为它有getFirst(),getLast()方法和removeLast()方法蛇下一步移动到哪是由方向控制的,前面已经定义过,蛇透坐标如下图:图3蛇头方向计算新蛇头坐标在Snake的 move()中增加body.removeLast();int x=body.getFirst().x;int y=body.getFi
22、rst().y;switch(direction) caseUP: y-;break;caseDOWN: y+;break;caseLEFT: x-;break;caseRIGHT: x+;break; Point newhead=new Point(x,y);/加头body.addFirst(newhead);并定义 privateintdirection;为了能更方便的维护游戏,这里定义Global类来定义常量如下:package liang.snake.Global;publicclass Global publicstaticfinalintCELL_SIZE=20;publicsta
23、ticintHIGHT=30;publicstaticintWIDTH=30;并修改游戏中窗口大小为:jf.setSize(Global.CELL_SIZE*Global.WIDTH,Global.CELL_SIZE*Global.HIGHT);再加上如下代码,对蛇初始化:public Snake()init();publicvoid init()int x=Global.WIDTH/2;int y=Global.HIGHT/2;int nodenum=3;for(int i=0;inodenum;i+)body.addFirst(new Point(x+,y);this.direction=
24、RIGHT;在蛇的drawMe(Graphics g)中些上如下让蛇显示的代码:这里的画图采用填充3D矩形来实现:for(Point p:body) g.fill3DRect(p.x*Global.CELL_SIZE, p.y*Global.CELL_SIZE, Global.CELL_SIZE, Global.CELL_SIZE, true); 画图的规则如下图:图4计算格子坐标和像素坐标此时运行Game类就可以看到蛇显示在面板中了,如图:图5显示面板显示的蛇但是蛇越走越长,是因为没有擦除以前的图像,在GamePanel的paintComponent(Graphics g)中添加如下代码:g
25、.setColor(new Color(0xcfcfcf);g.fill3DRect(0, 0,Global.CELL_SIZE*Global.WIDTH , Global.CELL_SIZE*Global.HIGHT, true);此时蛇就可以正常移动了如图:图6移动中的蛇通过按键改变移动方向,此时的蛇身体节点显示为白色,我们再在蛇的绘制方法中位器指定颜色:代码如下:图7指定颜色后的蛇六 : 试与修正蛇的移动与显示问题 此时的蛇当移动到窗口边界的时候就能走出窗口还有蛇可以穿过自己的身体,这些游戏规则中式不允许的, 下面来修正这些问题,修改Snake中的move()方法如下:首先定义publi
26、cintolddirection,newdirection;防止蛇穿过自己身体:publicvoid move() /去尾if(olddirection+newdirection!=0) olddirection=newdirection; body.removeLast();int x=body.getFirst().x;int y=body.getFirst().y;switch(olddirection) caseUP: y-;if(y=Global.HIGHT) y=0; break;caseLEFT: x-;if(x=Global.WIDTH) x=0 ; break; Point
27、newhead=new Point(x,y);/加头body.addFirst(newhead); System.out.println(Snakes move); publicvoid changeDirection(int direction) System.out.println(Snakes changeDirection);newdirection=direction;并修改蛇的初始化方法如下:olddirection=newdirection=RIGHT;此时就修正了上面的问题,可以运行Game类来测试下七 : 编写与测试表示食物的类并实现吃食物首先在Snake类中添加public
28、 Point getHead() returnbody.getFirst(); 用来获取头结点,然后再Food类中写上如下代码:package liang.snake.entities;importjava.awt.Color;import java.awt.Graphics;import java.awt.Point;import liang.snake.Global.Global;publicclassFoodextends Pointpublicvoid newfood(Point p)this.setLocation(p);publicboolean isSnakeEatFood(Sn
29、ake snake) System.out.println(Snakes eat food);returnthis.equals(snake.getHead();publicvoid drawme(Graphics g) System.out.println(Foods drawme);g.fill3DRect(this.x*Global.CELL_SIZE,this.y*Global.CELL_SIZE, Global.CELL_SIZE, Global.CELL_SIZE, true); 此时就可以画出食物并判断蛇是否吃到了食物,接下来就可以在Controller中处理吃食物的代码,吃了食物我们只要把先前移动去除的尾巴再给加上就实现了蛇吃食物身体变长的效果了,如下:定义Point oldTail;在蛇move()中保存去除的尾巴:oldTail= body.removeLast();在Controller
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1