Snake类主体: import javax.swing.*; import java.awt.event.*; import java.util.*; import java.awt.*; public class SnakePanel extends JPanel implements Runnable { final int latticeSize = 20; // 一个格的大小 final int Width = 20; // 高度 final int Height = 20; //宽度 int score = 0; //分数 int speed = 100; // 速度 int num = 0; boolean runing = true; //运行状态 boolean inOut = true; int snake_x = 1; //蛇的X坐标 int snake_y = 1; //蛇的Y坐标 int food_x,food_y; // 食物X/Y坐标 Random r = new Random(); //随机涵数 enum direction{up,down,left,right}; //枚举方向 direction dir = direction.right; //方向初始化为右 Thread thread = new Thread(this); //定义线程 LinkedList<Node> node = new LinkedList<Node>(); public SnakePanel(){ setFocusable(true); //焦点 for(int i=0;i<3;i++){ //初始化蛇长度为3 node.addFirst(new Node(snake_x++,snake_y)); } food_x = r.nextInt(20); //随机0~20之间的X坐标 food_y = r.nextInt(20); //随机0~20之间的Y坐标 addKeyListener(new KeyAdapter(){ //事件监听键盘 public void keyPressed(KeyEvent e) { switch(e.getKeyCode()){ case KeyEvent.VK_UP: if( dir != direction.down ){ //判断是否为相反方向 dir = direction.up; } break; case KeyEvent.VK_DOWN: if( dir != direction.up ){ dir = direction.down; } break; case KeyEvent.VK_LEFT: if( dir != direction.right ){ dir = direction.left; } break; case KeyEvent.VK_RIGHT: if( dir != direction.left ){ dir = direction.right; } break; case KeyEvent.VK_F5: // 开始/重新开始 if(inOut && num == 0){ thread.start(); //线程开始 num++; }else if(!inOut && num == 1){ snake_x = 1; snake_y = 1; food_x = r.nextInt(20); food_y = r.nextInt(20); dir = direction.right; node.clear(); score = 0; for(int i=0;i<3;i++){ node.addFirst(new Node(snake_x++,snake_y)); } inOut = true; } break; case KeyEvent.VK_ENTER: if(inOut){ //暂停/继续 inOut = false; }else{ inOut = true; } break; case KeyEvent.VK_ESCAPE : System.exit(0); //按Esc退出游戏 break; case KeyEvent.VK_ADD: if(speed != 10){ speed = speed - 10; } break; case KeyEvent.VK_SUBTRACT: speed = speed + 10; break; } } }); } public void run(){ try{ while(runing){ if(inOut){ switch(dir){ case up: node.removeLast(); //删除蛇链表最后一个 snake_y--; break; case down: node.removeLast(); snake_y++; break; case left: node.removeLast(); snake_x--; break; case right: node.removeLast(); snake_x++; break; } node.addFirst(new Node(snake_x,snake_y));//往蛇头插入 移动法 eatFood(); //调用吃东西方法 repaint(); //重绘所有 if( snake_x<0 || snake_y<0 || snake_x >= Width || snake_y >= Height ){ //判断蛇是否出界 JOptionPane.showMessageDialog(null,"游戏结束"); inOut = false; //停止运行 } int i = 0; Iterator it = node.iterator(); while( it.hasNext() ){ Node n = node.getFirst(); int x = n.x; int y = n.y; n = (Node)it.next(); if( i>3 ){ if(n.x == x && n.y == y ){ //判断是否咬到自己 JOptionPane.showMessageDialog(null,"游戏结束"); inOut = false; //停止运行 break; } } i++; } thread.sleep(speed); //间隔100毫秒的速度 } } }catch(InterruptedException e){} } public void eatFood(){ if( food_x == snake_x && food_y == snake_y ){ //判断是否吃到食物 score = score + 10; food_x = r.nextInt(20); food_y = r.nextInt(20); node.addFirst(new Node(snake_x,snake_y)); //添加蛇的长度 } } public void paintComponent(Graphics g){//画笔 g.setColor(Color.black); g.fillRect(0,0,Width*latticeSize,Height*latticeSize); //刷新画版 g.setColor(Color.red); g.drawString("分数:"+score+" 速度 = "+speed,5,15); g.fill3DRect(food_x*latticeSize,food_y*latticeSize,latticeSize,latticeSize,true); //画食物 Iterator it = node.iterator(); //得到node链表的itertor while( it.hasNext()){ //循环判断链表下一个是否存在 Node n = (Node)it.next(); //移动链表指针到下一个 if(n != null ){ //判断是否存在 g.setColor(Color.green); g.fill3DRect(n.x*latticeSize,n.y*latticeSize,latticeSize,latticeSize,true); //画蛇 } } } } class Node{ int x; int y; public Node(int x, int y){ this.x = x; this.y = y; } } JFrame类,加载调用Snake类. import javax.swing.*; import java.awt.*; public class SnakeStart extends JFrame { SnakePanel snake = new SnakePanel(); Label la = new Label(" F5: 开始/重新开始游戏 回车: 暂停/继续 Esc: 退出游戏 + 快 - 慢"); int width; int height; public SnakeStart(){ super("贪食蛇"); width = snake.latticeSize*snake.Width; //得到宽度 height = snake.latticeSize*snake.Height; //得到高度 setBounds(200,200,width,height+23); //设置窗口的位置和大小 add(snake,BorderLayout.CENTER); //把Snake类添加到JFrame的CENTER区 la.setAlignment(Label.CENTER); //设置JLabel文字为居中 la.setBackground(Color.DARK_GRAY); //设置JLabel的背景颜色 la.setForeground(Color.orange); //设置JLabel的前景颜色 add(la,BorderLayout.NORTH); //把JLabel添加至JFrame的NORTH区 setUndecorated(true); //设置JFrame窗口为无标题窗口 setResizable(false); //设置JFrame窗口不可改变大小 setVisible(true); //设置JFrame窗口可见为True; } public static void main(String[] args){ new SnakeStart(); //实例窗口,开始构造涵数`执行程序. } }