java贪吃蛇游戏Word文档格式.docx
《java贪吃蛇游戏Word文档格式.docx》由会员分享,可在线阅读,更多相关《java贪吃蛇游戏Word文档格式.docx(14页珍藏版)》请在冰点文库上搜索。
编写Controler类与实现蛇移动的事件监听
3:
蛇的数据结构设计与移动显示
4:
编写与测试表示食物的类并实现吃食物
总结
参考文献
贪吃蛇游戏
第一章.需求分析
1研究背景
大概在文艺复兴的时候就有人发明的一种游戏,是现在贪吃蛇的前身。
后来慢慢的发展就变成了今天的贪吃蛇了、现在贪吃蛇主要应用于手机游戏。
本文运用软件工程思想、JAVA面向对象编程、类的封装、抽象类的使用(接口),游戏编码规范遵循MVC模式,循序渐进实现贪吃蛇的相关功能。
2,研究方案
㈠●涉及到几个对象(类)
㈡●每个类有什么方法
1.首先得有个游戏显示面板(GamePanel)类
该类有一个方法voiddisplay();
//用来显示游戏面板
2.一个蛇(Snake)类
该类有以下几个方法:
voidmove();
//移动(走一步)
voidchangeDirection();
//改变方向
voideatFood();
//吃食物(身体变长)
vooleanisEatBody();
//蛇是否吃到了自己的身体
voiddrawMe();
//显示
3.一个食物类(Food)类
该类有以下方法:
booleanisSnakeEatFood(Snake);
//判断蛇是否吃到了食物
此时类之间的关系如下图所示:
图1各个类之间的关系
一:
publicclassFood{
publicbooleanisSnakeEatFood(Snakesnake)
{
System.out.println("
Snake'
seatfood"
);
returnfalse;
}
publicvoiddrawme()
Food'
sdrawme"
}
}
packageliang.snake.entities;
publicclassGround{
publicbooleanisSnakeEatRock()
Ground'
publicclassSnake{
publicvoidmove()
smove"
publicvoidchangeDirection(intdirection)
schangeDirection"
publicvoideatFood()
publicbooleanisEatBody()
seatbody"
publicvoiddrawMe(){
sdrawMe"
packageliang.snake.view;
importjava.awt.Graphics;
importjavax.swing.JPanel;
importliang.snake.entities.Food;
importliang.snake.entities.Ground;
importliang.snake.entities.Snake;
publicclassGamePanelextendsJPanel{
privateSnakesnake;
privateGroundground;
privateFoodfood;
publicvoidpaintComponent(Graphicsg){
snake.drawMe();
ground.drawme();
food.drawme();
publicvoiddisplay(Snakesnake,Groundground,Foodfood)
this.snake=snake;
this.ground=ground;
this.food=food;
GamePanel'
sdisplay"
this.repaint();
二:
编写Controler类与实现蛇移动的事件监听
由于蛇不能直接操作显示面板(GamePanel)所以这里定义一个监听器SnakeListener:
里面定义一个方法:
voidsnakeMove(Snake);
每当蛇移动一步就触发监听器,调用snakeMoved()由Controller去实现监听器的接口,然后由控制器去触发显示面板的事件源,让显示面板完成相应操作。
逻辑图如下:
图2事件监听建立联系
在Snake中增加蛇的方向常量:
publicstaticfinalintUP=1;
publicstaticfinalintDOWN=-1;
publicstaticfinalintLEFT=2;
publicstaticfinalintRIGHT=-2;
并添加一个接口:
packageliang.snake.Listener;
publicinterfaceSnakeListener{
publicvoidSnakeMove(Snakesnake);
Controler实现SnakeListener接口并处理案件消息:
代码如下:
packageliang.snake.Controller;
importjava.awt.event.KeyAdapter;
importjava.awt.event.KeyEvent;
importliang.snake.Listener.SnakeListener;
importliang.snake.view.GamePanel;
publicclassControllerextendsKeyAdapterimplementsSnakeListener{
Snakesnake=newSnake();
Groundground=newGround();
Foodfood=newFood();
GamePanelgamepanel=newGamePanel();
publicController(Snakesnake,Groundground,Foodfood,GamePanelgamepanel){
this.snake=snake;
this.ground=ground;
this.food=food;
this.gamepanel=gamepanel;
publicvoidkeyReleased(KeyEvente){
switch(e.getKeyCode())
{
caseKeyEvent.VK_UP:
snake.changeDirection(Snake.UP);
break;
caseKeyEvent.VK_DOWN:
snake.changeDirection(Snake.DOWN);
caseKeyEvent.VK_LEFT:
snake.changeDirection(Snake.LEFT);
caseKeyEvent.VK_RIGHT:
snake.changeDirection(Snake.RIGHT);
publicvoidnewgame()
{
snake.start();
publicvoidSnakeMove(Snakesnake){
gamepanel.display(snake,ground,food);
开发到此时,Snake中应该增加监听器,并另启动一个线程来不断调用蛇的move();
在Snake中提供一个启动线程的方法,在Snake中增加如下代码:
privateSet<
SnakeListener>
listener=new
HashSet<
();
publicvoidaddSnakeListener(SnakeListenerl)
if(l!
=null)
this.listener.add(l);
publicvoidstart()
newThread(newSnakeDriver()).run();
并在Run方法中增加
for(SnakeListenerl:
listener)
{
l.SnakeMove(Snake.this);
}
try
Thread.sleep(1000);
}
catch(InterruptedExceptione)
e.printStackTrace();
三:
蛇的数据结构设计与移动显示
分析:
要区分蛇头和蛇尾巴,这就要求这个数据结构是有序的,
还要经常访问第一个和最后一个节点,所以LinkedList最合适,因为它有getFirst(),getLast()方法和removeLast()方法
蛇下一步移动到哪是由方向控制的,前面已经定义过,蛇透坐标如下图:
图3蛇头方向计算新蛇头坐标
在Snake的move()中增加
body.removeLast();
intx=body.getFirst().x;
inty=body.getFirst().y;
switch(direction)
caseUP:
y--;
caseDOWN:
y++;
caseLEFT:
x--;
caseRIGHT:
x++;
Pointnewhead=newPoint(x,y);
//加头
body.addFirst(newhead);
并定义privateintdirection;
为了能更方便的维护游戏,这里定义Global类来定义常量如下:
packageliang.snake.Global;
publicclassGlobal{
publicstaticfinalintCELL_SIZE=20;
publicstaticintHIGHT=30;
publicstaticintWIDTH=30;
并修改游戏中窗口大小为:
jf.setSize(Global.CELL_SIZE*Global.WIDTH,Global.CELL_SIZE*Global.HIGHT);
再加上如下代码,对蛇初始化:
publicSnake()
init();
publicvoidinit()
intx=Global.WIDTH/2;
inty=Global.HIGHT/2;
intnodenum=3;
for(inti=0;
i<
nodenum;
i++)
body.addFirst(newPoint(x++,y));
this.direction=RIGHT;
在蛇的drawMe(Graphicsg)中些上如下让蛇显示的代码:
这里的画图采用填充3D矩形来实现:
for(Pointp:
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(Graphicsg)中添加如下代码:
g.setColor(newColor(0xcfcfcf));
g.fill3DRect(0,0,Global.CELL_SIZE*Global.WIDTH,Global.CELL_SIZE*Global.HIGHT,true);
此时蛇就可以正常移动了如图:
图6移动中的蛇
通过按键改变移动方向,此时的蛇身体节点显示为白色,我们再在蛇的绘制方法中位器指定颜色:
代码如下:
图7指定颜色后的蛇
四:
编写与测试表示食物的类并实现吃食物
首先在Snake类中添加publicPointgetHead()
returnbody.getFirst();
用来获取头结点,然后再Food类中写上如下代码:
importjava.awt.Color;
importjava.awt.Point;
importliang.snake.Global.Global;
publicclassFoodextendsPoint{
publicvoidnewfood(Pointp)
this.setLocation(p);
System.out.println("
returnthis.equals(snake.getHead());
publicvoiddrawme(Graphicsg)
g.fill3DRect(this.x*Global.CELL_SIZE,this.y*Global.CELL_SIZE,Global.CELL_SIZE,Global.CELL_SIZE,true);
此时就可以画出食物并判断蛇是否吃到了食物,接下来就可以在Controller中处理吃食物的代码,吃了食物我们只要把先前移动去除的尾巴再给加上就实现了蛇吃食物身体变长的效果了,如下:
定义PointoldTail;
在蛇move()中保存去除的尾巴:
oldTail=body.removeLast();
在Controller中的SnakeMove(Snakesnake)中添加
if(food.isSnakeEatFood(snake))
snake.eatFood();
food.newfood(ground.getPoint());
结论
贪吃蛇虽然是一个小游戏,但是它也是我们最常见的游戏之一,大到电脑电视,小到手机游戏机,到处有它的存在,他给人们带来了娱乐。
并且通过这次的动手,我发现它的组成与实现其实很麻烦,让我学会了很多东西。
首先感谢学校及老师给了我们这次上机实习的机会.虽然它与实际生活联系不是太密切,但毕竟让我们感到了实战的感觉.在实践编程过程中积累了宝贵的经验.这次数据结构课程设计使我们对此门课充满了乐趣,也学到了很多知识,Java在社会中的用处也随处可见,它的作用也是不会被忽视的,我们也应该重视.这将会是一门日益重要的学科.,在编程过程中,曾遇到了很多问题,也失败了很多次,不过最终通过不懈的努力,翻阅资料,征求老师和同学的意见还是圆满完成了。
这次的设计进一步提高了我对数据结构的认识,也发现了许多问题,更学到了许多知识。
这是我对这次课程设计的一点体会.。
在这次课程设计的过程中,在我的指导老师曾阳艳的精心指导下,我的编程,理解,动手及思维能力有了提高,同时也对数据结构的感觉更好了.所以在此对他的指导表示感谢!
1,《Java实用教程》郑阿奇
2,《Java实用教程》耿祥义
3,互联网