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; } }