JAVA贪吃蛇游戏代码.docx
《JAVA贪吃蛇游戏代码.docx》由会员分享,可在线阅读,更多相关《JAVA贪吃蛇游戏代码.docx(13页珍藏版)》请在冰点文库上搜索。
JAVA贪吃蛇游戏代码
packagecom.duchun.anjoyo;
/**程序名称:
贪食蛇
**原作者:
BigF
**修改者:
algo
**说明:
我以前也用C写过这个程序,现在看到BigF用Java写的这个,发现虽然作者自称是Java的初学者,
**但是明显编写程序的素养不错,程序结构写得很清晰,有些细微得地方也写得很简洁,一时兴起之
**下,我认真解读了这个程序,发现数据和表现分开得很好,而我近日正在学习MVC设计模式,
**因此尝试把程序得结构改了一下,用MVC模式来实现,对源程序得改动不多。
**我同时也为程序增加了一些自己理解得注释,希望对大家阅读有帮助。
**/
/***@authorWangYu
**@version1.0
**Description:
**
**Createon:
Date:
2005-6-13Time:
15:
57:
16
**LastModified:
**History:
**/
publicclassGreedSnake{
publicstaticvoidmain(String[]args){
SnakeModelmodel=newSnakeModel(20,30);
SnakeControlcontrol=newSnakeControl(model);
SnakeViewview=newSnakeView(model,control);
//添加一个观察者,让view成为model的观察者
model.addObserver(view);
(newThread(model)).start();
}
}
文件2:
packagecom.duchun.anjoyo;
//SnakeControl.java
importjava.awt.event.KeyEvent;
importjava.awt.event.KeyListener;
/***MVC中的Controler,负责接收用户的操作,并把用户操作通知Model*/
publicclassSnakeControlimplementsKeyListener{
SnakeModelmodel;
publicSnakeControl(SnakeModelmodel){
this.model=model;
}
publicvoidkeyPressed(KeyEvente){
intkeyCode=e.getKeyCode();
if(model.running){
//运行状态下,处理的按键
switch(keyCode){
caseKeyEvent.VK_UP:
model.changeDirection(SnakeModel.UP);
break;
caseKeyEvent.VK_DOWN:
model.changeDirection(SnakeModel.DOWN);
break;
caseKeyEvent.VK_LEFT:
model.changeDirection(SnakeModel.LEFT);
break;
caseKeyEvent.VK_RIGHT:
model.changeDirection(SnakeModel.RIGHT);
break;
caseKeyEvent.VK_ADD:
caseKeyEvent.VK_PAGE_UP:
model.speedUp();
break;
caseKeyEvent.VK_SUBTRACT:
caseKeyEvent.VK_PAGE_DOWN:
model.speedDown();
break;
caseKeyEvent.VK_SPACE:
caseKeyEvent.VK_P:
model.changePauseState();
break;
default:
}
}//任何情况下处理的按键,按键导致重新启动游戏
if(keyCode==KeyEvent.VK_R||keyCode==KeyEvent.VK_S||keyCode==KeyEvent.VK_ENTER){
model.reset();
}
}
publicvoidkeyReleased(KeyEvente){}
publicvoidkeyTyped(KeyEvente){}
}
文件3:
packagecom.duchun.anjoyo;
importjavax.swing.*;
importjava.util.Arrays;
importjava.util.LinkedList;
importjava.util.Observable;
importjava.util.Random;
classSnakeModelextendsObservableimplementsRunnable{
boolean[][]matrix;//指示位置上有没蛇体或食物
LinkedListnodeArray=newLinkedList();//蛇体
Nodefood;
intmaxX;
intmaxY;
intdirection=2;//蛇运行的方向
booleanrunning=false;//运行状态
inttimeInterval=200;//时间间隔,毫秒
doublespeedChangeRate=0.75;//每次得速度变化率
booleanpaused=false;//暂停标志
intscore=0;//得分
intcountMove=0;//吃到食物前移动的次数//UPandDOWNshouldbeeven//RIGHTand
//LEFTshouldbeodd
publicstaticfinalintUP=2;
publicstaticfinalintDOWN=4;
publicstaticfinalintLEFT=1;
publicstaticfinalintRIGHT=3;
publicSnakeModel(intmaxX,intmaxY){
this.maxX=maxX;
this.maxY=maxY;
reset();
}
publicvoidreset(){
direction=SnakeModel.UP;//蛇运行的方向
timeInterval=200;//时间间隔,毫秒
paused=false;//暂停标志
score=0;//得分
countMove=0;//吃到食物前移动的次数0
//initialmatirx,全部清
matrix=newboolean[maxX][];
for(inti=0;imatrix[i]=newboolean[maxY];
Arrays.fill(matrix[i],false);
}
//initialthesnake
//初始化蛇体,如果横向位置超过20个,长度为10,否则为横向位置的一半
intinitArrayLength=maxX>20?
10:
maxX/2;
nodeArray.clear();
for(inti=0;iintx=maxX/2+i;
//maxX被初始化为20
inty=maxY/2;
//maxY被初始化为30
//nodeArray[x,y]:
[10,15]-[11,15]-[12,15]~~[20,15]
//默认的运行方向向上,所以游戏一开始nodeArray就变为:
//[10,14]-[10,15]-[11,15]-[12,15]~~[19,15]
nodeArray.addLast(newNode(x,y));
matrix[x][y]=true;
}//创建食物
food=createFood();
matrix[food.x][food.y]=true;
}
publicvoidchangeDirection(intnewDirection){
//改变的方向不能与原来方向同向或反向
if(direction%2!
=newDirection%2){
direction=newDirection;
}
}
/***运行一次*@return*/
publicbooleanmoveOn(){
Noden=(Node)nodeArray.getFirst();
intx=n.x;
inty=n.y;
//根据方向增减坐标值
switch(direction){
caseUP:
y--;
break;
caseDOWN:
y++;
break;
caseLEFT:
x--;
break;
caseRIGHT:
x++;
break;
}
//如果新坐标落在有效范围内,则进行处理
if((0<=x&&xif(matrix[x][y]){
//如果新坐标的点上有东西(蛇体或者食物)
if(x==food.x&&y==food.y){
//吃到食物,成功
nodeArray.addFirst(food);
//从蛇头赠长
//分数规则,与移动改变方向的次数和速度两个元素有关
intscoreGet=(10000-200*countMove)/timeInterval;
score+=scoreGet>0?
scoreGet:
10;
countMove=0;
food=createFood();
//创建新的食物
matrix[food.x][food.y]=true;
//设置食物所在位置
returntrue;
}else
//吃到蛇体自身,失败
returnfalse;
}else{
//如果新坐标的点上没有东西(蛇体),移动蛇体
nodeArray.addFirst(newNode(x,y));
matrix[x][y]=true;
n=(Node)nodeArray.removeLast();
matrix[n.x][n.y]=false;
countMove++;
returntrue;
}
}
returnfalse;
//触到边线,失败
}
publicvoidrun(){
running=true;
while(running){
try{
Thread.sleep(timeInterval);
}catch(Exceptione){
break;
}
if(!
paused){
if(moveOn()){
setChanged();
//Model通知View数据已经更新
notifyObservers();
}else{
JOptionPane.showMessageDialog(null,"youfailed",
"GameOver",JOptionPane.INFORMATION_MESSAGE);
break;
}
}
}
running=false;
}
privateNodecreateFood(){
intx=0;
inty=0;
//随机获取一个有效区域内的与蛇体和食物不重叠的位置
do{
Randomr=newRandom();
x=r.nextInt(maxX);
y=r.nextInt(maxY);
}while(matrix[x][y]);
returnnewNode(x,y);
}
publicvoidspeedUp(){
timeInterval*=speedChangeRate;
}
publicvoidspeedDown(){
timeInterval/=speedChangeRate;
}
publicvoidchangePauseState(){
paused=!
paused;
}
publicStringtoString(){
Stringresult="";
for(inti=0;iNoden=(Node)nodeArray.get(i);
result+="["+n.x+","+n.y+"]";
}
returnresult;
}
}
classNode{
intx;
inty;
Node(intx,inty){
this.x=x;
this.y=y;
}
}
文件4:
packagecom.duchun.anjoyo;
importjavax.swing.*;
importjava.awt.*;
importjava.util.Iterator;
importjava.util.LinkedList;
importjava.util.Observable;
importjava.util.Observer;
publicclassSnakeViewimplementsObserver{
SnakeControlcontrol=null;
SnakeModelmodel=null;
JFramemainFrame;
CanvaspaintCanvas;
JLabellabelScore;
publicstaticfinalintcanvasWidth=200;
publicstaticfinalintcanvasHeight=300;
publicstaticfinalintnodeWidth=10;
publicstaticfinalintnodeHeight=10;
publicSnakeView(SnakeModelmodel,SnakeControlcontrol){
this.model=model;
this.control=control;
mainFrame=newJFrame("GreedSnake");
Containercp=mainFrame.getContentPane();
//创建顶部的分数显示
labelScore=newJLabel("Score:
");
cp.add(labelScore,BorderLayout.NORTH);
//创建中间的游戏显示区域
paintCanvas=newCanvas();
paintCanvas.setSize(canvasWidth+1,canvasHeight+1);
paintCanvas.addKeyListener(control);
cp.add(paintCanvas,BorderLayout.CENTER);
//创建底下的帮助栏
JPanelpanelButtom=newJPanel();
panelButtom.setLayout(newBorderLayout());
JLabellabelHelp;
labelHelp=newJLabel("PageUp,PageDownforspeed;",JLabel.CENTER);
panelButtom.add(labelHelp,BorderLayout.NORTH);
labelHelp=newJLabel("ENTERorRorSforstart;",JLabel.CENTER);
panelButtom.add(labelHelp,BorderLayout.CENTER);
labelHelp=newJLabel("SPACEorPforpause",JLabel.CENTER);
panelButtom.add(labelHelp,BorderLayout.SOUTH);
cp.add(panelButtom,BorderLayout.SOUTH);
mainFrame.addKeyListener(control);
mainFrame.pack();
mainFrame.setResizable(false);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setVisible(true);
}
voidrepaint(){
Graphicsg=paintCanvas.getGraphics();
//drawbackground
g.setColor(Color.WHITE);
g.fillRect(0,0,canvasWidth,canvasHeight);
//drawthesnake
g.setColor(Color.BLACK);
LinkedListna=model.nodeArray;
Iteratorit=na.iterator();
while(it.hasNext()){
Noden=(Node)it.next();
drawNode(g,n);
}//drawthefood
g.setColor(Color.RED);
Noden=model.food;
drawNode(g,n);
updateScore();
}
privatevoiddrawNode(Graphicsg,Noden){
g.fillRect(n.x*nodeWidth,n.y*nodeHeight,nodeWidth-1,
nodeHeight-1);
}
publicvoidupdateScore(){
Strings="Score:
"+model.score;
labelScore.setText(s);
}
publicvoidupdate(Observableo,Objectarg){
repaint();
}
}