java版的贪吃蛇毕业论文范本模板Word下载.docx
《java版的贪吃蛇毕业论文范本模板Word下载.docx》由会员分享,可在线阅读,更多相关《java版的贪吃蛇毕业论文范本模板Word下载.docx(27页珍藏版)》请在冰豆网上搜索。
游戏中的面向对象分析与设计
㈠●涉及到几个对象(类)
㈡●每个类有什么方法
1。
首先得有个游戏显示面板(GamePanel)类
该类有一个方法voiddisplay();
//用来显示游戏面板
2。
得有个蛇(Snake)类
该类有以下几个方法:
voidmove();
//移动(走一步)
voidchangeDirection();
//改变方向
voideatFood();
//吃食物(身体变长)
vooleanisEatBody();
//蛇是否吃到了自己的身体
voiddrawMe();
//显示
3。
一个食物类(Food)类
该类有以下方法:
booleanisSnakeEatFood(Snake);
//判断蛇是否吃到了食物
voiddrawMe();
4。
一个背景石头(Ground)类
BooleanisSnakeEatRock(Snake);
//蛇是否吃到了石头
此时类之间的关系如下图所示:
图1各个类之间的关系
二:
编写贪吃蛇游戏中的各个类的主体框架性代码
本有序遵循MVC(Model—View-Controller)所以首先建立以上几个实体类并定义相应的包名:
liang.snake.entities包下定义Food、Ground、Snake三个类,再在liang。
snake。
view包下定义GamePanel类,再在,按照以上说明的各个类具有的方法,写上如下代码:
packageliang。
entities;
publicclassFood{
publicbooleanisSnakeEatFood(Snakesnake)
{
System。
out。
println(”Snake’seatfood”);
returnfalse;
}
publicvoiddrawme()
out.println("
Food’sdrawme”);
}
}
publicclassGround{
publicbooleanisSnakeEatRock()
returnfalse;
out.println(”Ground'
sdrawme"
);
}
}
packageliang.snake.entities;
publicclassSnake{
publicvoidmove()
System.out。
println("
Snake'
smove"
publicvoidchangeDirection(intdirection)
System.out.println("
schangeDirection"
publicvoideatFood()
{
seatfood”);
publicbooleanisEatBody()
System.out.println(”Snake’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;
food=food;
GamePanel'
sdisplay”);
this.repaint();
三:
编写Controler类与实现蛇移动的事件监听
由于蛇不能直接操作显示面板(GamePanel)所以这里定义一个监听器SnakeListener:
里面定义一个方法:
voidsnakeMove(Snake);
每当蛇移动一步就触发监听器,调用snakeMoved()由Controller去实现监听器的接口,然后由控制器去触发显示面板的事件源,让显示面板完成相应操作。
逻辑图如下:
图2事件监听建立联系
在Snake中增加蛇的方向常量:
publicstaticfinalintUP=1;
publicstaticfinalintDOWN=—1;
publicstaticfinalintLEFT=2;
publicstaticfinalintRIGHT=—2;
并添加一个接口:
snake.Listener;
publicinterfaceSnakeListener{
publicvoidSnakeMove(Snakesnake);
Controler实现SnakeListener接口并处理案件消息:
代码如下:
snake.Controller;
importjava.awt.event。
KeyAdapter;
importjava。
awt。
event。
KeyEvent;
importliang。
snake.Listener。
SnakeListener;
importliang.snake.entities.Food;
snake.entities.Ground;
snake.entities。
snake.view.GamePanel;
publicclassControllerextendsKeyAdapterimplementsSnakeListener{
Snakesnake=newSnake();
Groundground=newGround();
Foodfood=newFood();
GamePanelgamepanel=newGamePanel();
publicController(Snakesnake,Groundground,Foodfood,GamePanelgamepanel){
snake=snake;
ground=ground;
this.food=food;
gamepanel=gamepanel;
publicvoidkeyReleased(KeyEvente){
switch(e.getKeyCode())
{
caseKeyEvent。
VK_UP:
snake。
changeDirection(Snake.UP);
break;
VK_DOWN:
changeDirection(Snake.DOWN);
break;
VK_LEFT:
changeDirection(Snake.LEFT);
caseKeyEvent.VK_RIGHT:
changeDirection(Snake。
RIGHT);
publicvoidnewgame()
{
snake.start();
publicvoidSnakeMove(Snakesnake){
gamepanel。
display(snake,ground,food);
开发到此时,Snake中应该增加监听器,并另启动一个线程来不断调用蛇的move();
在Snake中提供一个启动线程的方法,在Snake中增加如下代码:
privateSet〈SnakeListener〉listener=new
HashSet<
SnakeListener>
();
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();
}
四:
编写对各个类进行测试的程序代码
构建一个新类Game来测试程序代码:
Game;
applet.AudioClip;
BorderLayout;
io。
File;
import.MalformedURLException;
net.URL;
importjavax.swing。
JFrame;
snake.Controller。
Food;
snake.entities.Ground;
view。
GamePanel;
publicclassGame{
publicstaticvoidmain(String[]args){
JFramejf=newJFrame("
我的论文"
Snakesnake=newSnake();
Groundground=newGround();
Foodfood=newFood();
GamePanelgamepanel=newGamePanel();
Controllercontroller=newController(snake,ground,food,gamepanel);
jf.setDefaultCloseOperation(JFrame。
EXIT_ON_CLOSE);
jf.setLocation(400,0);
jf.setSize(800,600);
jf。
add(gamepanel);
addKeyListener(controller);
snake.addSnakeListener(controller);
setVisible(true);
controller.newgame();
运行这个带有main()的类,在Eclipse的Console窗口中可以看到如下信息:
Snake’smove
sdisplay
Snake’sdrawMe
Ground’sdrawme
Food'
sdrawme
sdrawMe
smove
GamePanel’sdisplay
Ground'
Food’sdrawme
这就意味着,当蛇移动一次,就触发监听器,有控制器(controller)给GamePanel发送指令,让它重画,GamePanel中的
publicvoiddisplay(Snakesnake,Groundground,Foodfood)
GamePanel’sdisplay”);
this.snake=snake;
ground=ground;
this.food=food;
repaint();
这个方法依次画出几个实体,所以打印出上述信息。
到了这一步我们的基本框架打好了,下面开始第5步
五:
蛇的数据结构设计与移动显示
分析:
要区分蛇头和蛇尾巴,这就要求这个数据结构是有序的,
还要经常访问第一个和最后一个节点,所以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类来定义常量如下:
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中的move()方法如下:
首先定义publicintolddirection,newdirection;
防止蛇穿过自己身体:
publicvoidmove()
//去尾
if(olddirection+newdirection!
=0)
olddirection=newdirection;
body。
removeLast();
getFirst().x;
inty=body.getFirst()。
y;
switch(olddirection)
caseUP:
y——;
if(y<
0)
y=Global.HIGHT-1;
caseDOWN:
y++;
if(y〉=Global.HIGHT)
y=0;
caseLEFT:
if(x<
x=Global。
WIDTH—1;
x++;
if(x>
=Global.WIDTH)
x=0;
Pointnewhead=newPoint(x,y);
smove”);
println(”Snake'
schangeDirection”);
newdirection=direction;
并修改蛇的初始化方法如下:
olddirection=newdirection=RIGHT;
此时就修正了上面的问题,可以运行Game类来测试下
七:
编写与测试表示食物的类并实现吃食物
首先在Snake类中添加publicPointgetHead()
returnbody。
getFirst();
用来获取头结点,然后再Food类中写上如下代码:
entities;
importjava.awt.Color;
awt.Graphics;
Point;
Global。
Global;
publicclassFoodextendsPoint{
publicvoidnewfood(Pointp)