java中使用双向链表实现贪吃蛇程序源码分享
使用双向链表实现贪吃蛇程序
1.链表节点定义:
packagesnake;
publicclassSnakeNode{
privateintx;
privateinty;
privateSnakeNodenext;
privateSnakeNodeahead;
publicSnakeNode(){
}
publicSnakeNode(intx,inty){
super();
this.x=x;
this.y=y;
}
publicintgetX(){
returnx;
}
publicvoidsetX(intx){
this.x=x;
}
publicintgetY(){
returny;
}
publicvoidsetY(inty){
this.y=y;
}
publicSnakeNodegetNext(){
returnnext;
}
publicvoidsetNext(SnakeNodenext){
this.next=next;
}
publicSnakeNodegetAhead(){
returnahead;
}
publicvoidsetAhead(SnakeNodeahead){
this.ahead=ahead;
}
}
主程序:
packagesnake;
importjava.awt.BorderLayout;
importjava.awt.GridLayout;
importjava.awt.KeyEventPostProcessor;
importjava.awt.KeyboardFocusManager;
importjava.awt.event.KeyEvent;
importjava.util.Random;
importjavax.swing.ImageIcon;
importjavax.swing.JFrame;
importjavax.swing.JLabel;
importjavax.swing.JOptionPane;
importjavax.swing.JPanel;
/**
*Createdbyhackcoderon15-3-11.
*/
publicclassSnakeextendsJFrame{
privatestaticfinalintrows=60;
privatestaticfinalintcolumns=80;
//方向
privatestaticfinalintUP=1;
privatestaticfinalintRIGHT=2;
privatestaticfinalintDOWN=3;
privatestaticfinalintLEFT=4;
privatestaticintDRIECTION_NOW=RIGHT;
privatestaticbooleanisEat=false;
privatestaticintTAILX;
privatestaticintTAILY;
privatestaticSnakeNodesnakeHeader=newSnakeNode();
privatestaticSnakeNodesnakeTailer=snakeHeader;
privatestaticSnakeNodefood=newSnakeNode();
privatestaticJLabel[]images=newJLabel[rows*columns];
publicstaticvoidmain(Stringargs[]){
snakeHeader.setX(newRandom().nextInt(rows-1));
snakeHeader.setY(newRandom().nextInt(columns-1));
Snakesnake=newSnake();
food=getFood();
while(true){
try{
next();
//吃到了食物
if(food.getX()==snakeHeader.getX()
&&food.getY()==snakeHeader.getY()){
addTail();
isEat=true;
}
//吃到食物,重新生成一个食物
if(isEat){
food=getFood();
}
//判断是否结束游戏
if(judgeEND()){
JOptionPane.showMessageDialog(null,"游戏结束!","游戏结束!",
JOptionPane.ERROR_MESSAGE);
break;
}
SnakeNodepNow=snakeHeader;
while(pNow!=null){
images[columns*pNow.getX()+pNow.getY()]
.setIcon(newImageIcon("image/black.jpg",""));
pNow=pNow.getNext();
}
images[columns*food.getX()+food.getY()]
.setIcon(newImageIcon("image/black.jpg",""));
Thread.sleep(100);
//清理
pNow=snakeHeader;
while(pNow!=null){
images[columns*pNow.getX()+pNow.getY()]
.setIcon(newImageIcon("image/white.jpg",""));
pNow=pNow.getNext();
}
images[columns*food.getX()+food.getY()]
.setIcon(newImageIcon("image/white.jpg",""));
isEat=false;
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
}
publicSnake(){
init();
this.setBounds(80,80,400,400);
this.setVisible(true);
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
//添加全局键盘监听
KeyboardFocusManagermanager=KeyboardFocusManager
.getCurrentKeyboardFocusManager();
manager.addKeyEventPostProcessor((KeyEventPostProcessor)this
.getMyKeyEventHandler());
}
/**
*初始化地图
*/
publicvoidinit(){
JPanelp=newJPanel(newGridLayout(rows,columns,1,1));
setLayout(newBorderLayout());
for(intx=0;x<rows;x++){
for(inty=0;y<columns;y++){
ImageIconimageIcon;
if(x==0||x==rows-1||y==0||y==columns-1){
imageIcon=newImageIcon("image/red.jpg","");
}else{
imageIcon=newImageIcon("image/white.jpg","");
}
images[columns*x+y]=newJLabel(imageIcon);
p.add(images[columns*x+y]);
}
}
getContentPane().add(p,BorderLayout.CENTER);
}
/**
*键盘监听
*
*@return
*/
publicKeyEventPostProcessorgetMyKeyEventHandler(){
returnnewKeyEventPostProcessor(){
publicbooleanpostProcessKeyEvent(KeyEvente){
if(e.getID()!=KeyEvent.KEY_PRESSED){
returnfalse;
}
intkeycode=e.getKeyCode();
if(keycode==KeyEvent.VK_UP){
if(snakeHeader.getNext()!=null){
//判断方向是否可转
intx1=snakeHeader.getX();
inty1=snakeHeader.getY();
intx2=snakeHeader.getNext().getX();
inty2=snakeHeader.getNext().getY();
if(y1==y2&&x1-x2==1){
returntrue;
}
}
DRIECTION_NOW=UP;
}elseif(keycode==KeyEvent.VK_RIGHT){
if(snakeHeader.getNext()!=null){
intx1=snakeHeader.getX();
inty1=snakeHeader.getY();
intx2=snakeHeader.getNext().getX();
inty2=snakeHeader.getNext().getY();
if(x1==x2&&y2-y1==1){
returntrue;
}
}
DRIECTION_NOW=RIGHT;
}elseif(keycode==KeyEvent.VK_DOWN){
if(snakeHeader.getNext()!=null){
intx1=snakeHeader.getX();
inty1=snakeHeader.getY();
intx2=snakeHeader.getNext().getX();
inty2=snakeHeader.getNext().getY();
if(y1==y2&&x2-x1==1){
returntrue;
}
}
DRIECTION_NOW=DOWN;
}elseif(keycode==KeyEvent.VK_LEFT){
if(snakeHeader.getNext()!=null){
intx1=snakeHeader.getX();
inty1=snakeHeader.getY();
intx2=snakeHeader.getNext().getX();
inty2=snakeHeader.getNext().getY();
if(x1==x2&&y1-y2==1){
returntrue;
}
}
DRIECTION_NOW=LEFT;
}
returntrue;
}
};
}
/**
*计算贪吃蛇的方向及位移
*
*@paramheader
*/
publicstaticvoidnext(){
if(snakeHeader==null)
return;
TAILX=snakeTailer.getX();
TAILY=snakeTailer.getY();
SnakeNodepNow=snakeTailer;
while(pNow!=null){
if(pNow==snakeHeader){
break;
}
pNow.setX(pNow.getAhead().getX());
pNow.setY(pNow.getAhead().getY());
pNow=pNow.getAhead();
}
if(DRIECTION_NOW==RIGHT){
snakeHeader.setY(snakeHeader.getY()+1);
}elseif(DRIECTION_NOW==LEFT){
snakeHeader.setY(snakeHeader.getY()-1);
}elseif(DRIECTION_NOW==UP){
snakeHeader.setX(snakeHeader.getX()-1);
}elseif(DRIECTION_NOW==DOWN){
snakeHeader.setX(snakeHeader.getX()+1);
}
}
publicstaticvoidaddTail(){
SnakeNodetail=newSnakeNode(TAILX,TAILY);
snakeTailer.setNext(tail);
tail.setAhead(snakeTailer);
snakeTailer=snakeTailer.getNext();
}
publicstaticSnakeNodegetFood(){
SnakeNodefood=newSnakeNode();
booleanflag=true;
while(true){
intx=newRandom().nextInt(rows);
inty=newRandom().nextInt(columns);
if(x==0||x==rows-1||y==0||y==columns-1){
continue;
}
SnakeNodepNow=snakeHeader;
while(pNow!=null){
if(x==pNow.getX()&&y==pNow.getY()){
flag=false;
}
pNow=pNow.getNext();
}
if(flag){
food=newSnakeNode(x,y);
break;
}
}
returnfood;
}
publicstaticbooleanjudgeEND(){
//碰墙判断
if(snakeHeader.getX()==0||snakeHeader.getX()==rows-1
||snakeHeader.getY()==0||snakeHeader.getY()==columns-1){
returntrue;
}
//碰身体判断
SnakeNodepNow=snakeHeader.getNext();
while(pNow!=null){
if(snakeHeader.getX()==pNow.getX()
&&snakeHeader.getY()==pNow.getY()){
System.out.println("=========碰到身体===========");
returntrue;
}
pNow=pNow.getNext();
}
returnfalse;
}
}