java中使用双向链表实现贪吃蛇程序源码分享

时间:2022-01-04 00:10:35

使用双向链表实现贪吃蛇程序

1.链表节点定义:

  1. package snake; 
  2.   
  3. public class SnakeNode { 
  4.     private int x; 
  5.     private int y; 
  6.     private SnakeNode next; 
  7.     private SnakeNode ahead; 
  8.   
  9.     public SnakeNode() { 
  10.     } 
  11.   
  12.     public SnakeNode(int x, int y) { 
  13.         super(); 
  14.         this.x = x; 
  15.         this.y = y; 
  16.     } 
  17.   
  18.     public int getX() { 
  19.         return x; 
  20.     } 
  21.   
  22.     public void setX(int x) { 
  23.         this.x = x; 
  24.     } 
  25.   
  26.     public int getY() { 
  27.         return y; 
  28.     } 
  29.   
  30.     public void setY(int y) { 
  31.         this.y = y; 
  32.     } 
  33.   
  34.     public SnakeNode getNext() { 
  35.         return next; 
  36.     } 
  37.   
  38.     public void setNext(SnakeNode next) { 
  39.         this.next = next; 
  40.     } 
  41.   
  42.     public SnakeNode getAhead() { 
  43.         return ahead; 
  44.     } 
  45.   
  46.     public void setAhead(SnakeNode ahead) { 
  47.         this.ahead = ahead; 
  48.     } 
  49.   

主程序:

  1. package snake; 
  2.   
  3. import java.awt.BorderLayout; 
  4. import java.awt.GridLayout; 
  5. import java.awt.KeyEventPostProcessor; 
  6. import java.awt.KeyboardFocusManager; 
  7. import java.awt.event.KeyEvent; 
  8. import java.util.Random; 
  9.   
  10. import javax.swing.ImageIcon; 
  11. import javax.swing.JFrame; 
  12. import javax.swing.JLabel; 
  13. import javax.swing.JOptionPane; 
  14. import javax.swing.JPanel; 
  15.   
  16. /** 
  17.  * Created by hackcoder on 15-3-11. 
  18.  */ 
  19. public class Snake extends JFrame { 
  20.     private static final int rows = 60; 
  21.     private static final int columns = 80; 
  22.   
  23.     // 方向 
  24.     private static final int UP = 1; 
  25.     private static final int RIGHT = 2; 
  26.     private static final int DOWN = 3; 
  27.     private static final int LEFT = 4; 
  28.   
  29.     private static int DRIECTION_NOW = RIGHT; 
  30.     private static boolean isEat = false
  31.   
  32.     private static int TAILX; 
  33.     private static int TAILY; 
  34.   
  35.     private static SnakeNode snakeHeader = new SnakeNode(); 
  36.     private static SnakeNode snakeTailer = snakeHeader; 
  37.     private static SnakeNode food = new SnakeNode(); 
  38.     private static JLabel[] images = new JLabel[rows * columns]; 
  39.   
  40.     public static void main(String args[]) { 
  41.         snakeHeader.setX(new Random().nextInt(rows - 1)); 
  42.         snakeHeader.setY(new Random().nextInt(columns - 1)); 
  43.         Snake snake = new Snake(); 
  44.         food = getFood(); 
  45.         while (true) { 
  46.             try { 
  47.                 next(); 
  48.                 // 吃到了食物 
  49.                 if (food.getX() == snakeHeader.getX() 
  50.                         && food.getY() == snakeHeader.getY()) { 
  51.                     addTail(); 
  52.                     isEat = true
  53.                 } 
  54.                 //吃到食物,重新生成一个食物 
  55.                 if (isEat) { 
  56.                     food = getFood(); 
  57.                 } 
  58.                 // 判断是否结束游戏 
  59.                 if (judgeEND()) { 
  60.                     JOptionPane.showMessageDialog(null"游戏结束!""游戏结束!"
  61.                             JOptionPane.ERROR_MESSAGE); 
  62.                     break
  63.                 } 
  64.                 SnakeNode pNow = snakeHeader; 
  65.                 while (pNow != null) { 
  66.                     images[columns * pNow.getX() + pNow.getY()] 
  67.                             .setIcon(new ImageIcon("image/black.jpg""")); 
  68.                     pNow = pNow.getNext(); 
  69.                 } 
  70.                 images[columns * food.getX() + food.getY()] 
  71.                         .setIcon(new ImageIcon("image/black.jpg""")); 
  72.                 Thread.sleep(100); 
  73.                 // 清理 
  74.                 pNow = snakeHeader; 
  75.                 while (pNow != null) { 
  76.                     images[columns * pNow.getX() + pNow.getY()] 
  77.                             .setIcon(new ImageIcon("image/white.jpg""")); 
  78.                     pNow = pNow.getNext(); 
  79.                 } 
  80.                 images[columns * food.getX() + food.getY()] 
  81.                         .setIcon(new ImageIcon("image/white.jpg""")); 
  82.   
  83.                 isEat = false
  84.             } catch (InterruptedException e) { 
  85.                 e.printStackTrace(); 
  86.             } 
  87.         } 
  88.     } 
  89.   
  90.     public Snake() { 
  91.         init(); 
  92.         this.setBounds(80, 80, 400, 400); 
  93.         this.setVisible(true); 
  94.         setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 
  95.         // 添加全局键盘监听 
  96.         KeyboardFocusManager manager = KeyboardFocusManager 
  97.                 .getCurrentKeyboardFocusManager(); 
  98.         manager.addKeyEventPostProcessor((KeyEventPostProcessor) this 
  99.                 .getMyKeyEventHandler()); 
  100.     } 
  101.   
  102.     /** 
  103.      * 初始化地图 
  104.      */ 
  105.     public void init() { 
  106.         JPanel p = new JPanel(new GridLayout(rows, columns, 1, 1)); 
  107.         setLayout(new BorderLayout()); 
  108.         for (int x = 0; x < rows; x++) { 
  109.             for (int y = 0; y < columns; y++) { 
  110.                 ImageIcon imageIcon; 
  111.                 if (x == 0 || x == rows - 1 || y == 0 || y == columns - 1) { 
  112.                     imageIcon = new ImageIcon("image/red.jpg"""); 
  113.                 } else { 
  114.                     imageIcon = new ImageIcon("image/white.jpg"""); 
  115.                 } 
  116.                 images[columns * x + y] = new JLabel(imageIcon); 
  117.                 p.add(images[columns * x + y]); 
  118.             } 
  119.         } 
  120.         getContentPane().add(p, BorderLayout.CENTER); 
  121.   
  122.     } 
  123.   
  124.     /** 
  125.      * 键盘监听 
  126.      *  
  127.      * @return 
  128.      */ 
  129.     public KeyEventPostProcessor getMyKeyEventHandler() { 
  130.         return new KeyEventPostProcessor() { 
  131.             public boolean postProcessKeyEvent(KeyEvent e) { 
  132.                 if (e.getID() != KeyEvent.KEY_PRESSED) { 
  133.                     return false
  134.                 } 
  135.                 int keycode = e.getKeyCode(); 
  136.                 if (keycode == KeyEvent.VK_UP) { 
  137.   
  138.                     if (snakeHeader.getNext() != null) { 
  139.                         // 判断方向是否可转 
  140.                         int x1 = snakeHeader.getX(); 
  141.                         int y1 = snakeHeader.getY(); 
  142.                         int x2 = snakeHeader.getNext().getX(); 
  143.                         int y2 = snakeHeader.getNext().getY(); 
  144.                         if (y1 == y2 && x1 - x2 == 1) { 
  145.                             return true
  146.                         } 
  147.                     } 
  148.                     DRIECTION_NOW = UP; 
  149.                 } else if (keycode == KeyEvent.VK_RIGHT) { 
  150.                     if (snakeHeader.getNext() != null) { 
  151.                         int x1 = snakeHeader.getX(); 
  152.                         int y1 = snakeHeader.getY(); 
  153.                         int x2 = snakeHeader.getNext().getX(); 
  154.                         int y2 = snakeHeader.getNext().getY(); 
  155.                         if (x1 == x2 && y2 - y1 == 1) { 
  156.                             return true
  157.                         } 
  158.                     } 
  159.                     DRIECTION_NOW = RIGHT; 
  160.                 } else if (keycode == KeyEvent.VK_DOWN) { 
  161.                     if (snakeHeader.getNext() != null) { 
  162.                         int x1 = snakeHeader.getX(); 
  163.                         int y1 = snakeHeader.getY(); 
  164.                         int x2 = snakeHeader.getNext().getX(); 
  165.                         int y2 = snakeHeader.getNext().getY(); 
  166.                         if (y1 == y2 && x2 - x1 == 1) { 
  167.                             return true
  168.                         } 
  169.                     } 
  170.                     DRIECTION_NOW = DOWN; 
  171.                 } else if (keycode == KeyEvent.VK_LEFT) { 
  172.                     if (snakeHeader.getNext() != null) { 
  173.                         int x1 = snakeHeader.getX(); 
  174.                         int y1 = snakeHeader.getY(); 
  175.                         int x2 = snakeHeader.getNext().getX(); 
  176.                         int y2 = snakeHeader.getNext().getY(); 
  177.                         if (x1 == x2 && y1 - y2 == 1) { 
  178.                             return true
  179.                         } 
  180.                     } 
  181.                     DRIECTION_NOW = LEFT; 
  182.                 } 
  183.                 return true
  184.             } 
  185.         }; 
  186.     } 
  187.   
  188.     /** 
  189.      * 计算贪吃蛇的方向及位移 
  190.      *  
  191.      * @param header 
  192.      */ 
  193.     public static void next() { 
  194.         if (snakeHeader == null
  195.             return
  196.         TAILX = snakeTailer.getX(); 
  197.         TAILY = snakeTailer.getY(); 
  198.         SnakeNode pNow = snakeTailer; 
  199.         while (pNow != null) { 
  200.             if (pNow == snakeHeader) { 
  201.                 break
  202.             } 
  203.             pNow.setX(pNow.getAhead().getX()); 
  204.             pNow.setY(pNow.getAhead().getY()); 
  205.             pNow = pNow.getAhead(); 
  206.         } 
  207.   
  208.         if (DRIECTION_NOW == RIGHT) { 
  209.             snakeHeader.setY(snakeHeader.getY() + 1); 
  210.         } else if (DRIECTION_NOW == LEFT) { 
  211.             snakeHeader.setY(snakeHeader.getY() - 1); 
  212.         } else if (DRIECTION_NOW == UP) { 
  213.             snakeHeader.setX(snakeHeader.getX() - 1); 
  214.         } else if (DRIECTION_NOW == DOWN) { 
  215.             snakeHeader.setX(snakeHeader.getX() + 1); 
  216.         } 
  217.     } 
  218.   
  219.     public static void addTail() { 
  220.         SnakeNode tail = new SnakeNode(TAILX, TAILY); 
  221.         snakeTailer.setNext(tail); 
  222.         tail.setAhead(snakeTailer); 
  223.         snakeTailer = snakeTailer.getNext(); 
  224.   
  225.     } 
  226.   
  227.     public static SnakeNode getFood() { 
  228.         SnakeNode food = new SnakeNode(); 
  229.         boolean flag = true
  230.         while (true) { 
  231.             int x = new Random().nextInt(rows); 
  232.             int y = new Random().nextInt(columns); 
  233.             if (x == 0 || x == rows - 1 || y == 0 || y == columns - 1) { 
  234.                 continue
  235.             } 
  236.             SnakeNode pNow = snakeHeader; 
  237.             while (pNow != null) { 
  238.                 if (x == pNow.getX() && y == pNow.getY()) { 
  239.                     flag = false
  240.                 } 
  241.                 pNow = pNow.getNext(); 
  242.             } 
  243.             if (flag) { 
  244.                 food = new SnakeNode(x, y); 
  245.                 break
  246.             } 
  247.         } 
  248.         return food; 
  249.     } 
  250.   
  251.     public static boolean judgeEND() { 
  252.         //碰墙判断 
  253.         if (snakeHeader.getX() == 0 || snakeHeader.getX() == rows - 1 
  254.                 || snakeHeader.getY() == 0 || snakeHeader.getY() == columns - 1) { 
  255.             return true
  256.         } 
  257.         //碰身体判断 
  258.         SnakeNode pNow = snakeHeader.getNext(); 
  259.         while (pNow != null) { 
  260.             if (snakeHeader.getX() == pNow.getX() 
  261.                     && snakeHeader.getY() == pNow.getY()) { 
  262.                 System.out.println("=========碰到身体==========="); 
  263.                 return true
  264.             } 
  265.             pNow = pNow.getNext(); 
  266.         } 
  267.         return false
  268.     } 
  269.