Swing java代码 贪吃蛇

本博客记录我这个小白开始涉略Swing的界面设计咯,今天就奉献出自己学习贪吃蛇的的代码,一些也是从网上大牛那学来的,嘻嘻,就当我这个小白认真学习的见证吧! ps:Cc
SnakeView.class//关于贪吃蛇的游戏界面类
(用到了观察者observer和被观察者observable)
1 package GreedSnake; 2 3 import java.awt.BorderLayout; 4 import java.awt.Canvas; 5 import java.awt.Color; 6 import java.awt.Dimension; 7 import java.awt.FlowLayout; 8 import java.awt.Graphics; 9 import java.awt.GraphicsConfiguration; 10 import java.awt.HeadlessException; 11 import java.util.Iterator; 12 import java.util.LinkedList; 13 import java.util.Observable; 14 import java.util.Observer; 15 16 import javax.swing.JFrame; 17 import javax.swing.JLabel; 18 import javax.swing.JPanel; 19 import javax.swing.JTextField; 20 import javax.swing.UIManager; 21 22 import GreedSnake.SnakeModel.Node; 23 24 public class SnakeView extends JFrame implements Observer 25 { 26 SnakeControl control; 27 SnakeModel model; 28 Canvas gameCanvas; 29 JLabel scorelable; 30 public static final int gameWidth=600; 31 public static final int gameHeight=600; 32 public static final int nodeWidth = 10;// 33 public static final int nodeHeight = 10; 34 public SnakeView(SnakeModel model,SnakeControl control)//传入蛇SnakeModel对象以及KeyListener 35 { 36 super("My GreedSnake"); 37 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 38 this.control=control; 39 this.model=model; 40 BorderLayout layout=new BorderLayout();//边界布局,组件必须指定方向(NORTH...) 41 setLayout(layout); 42 //上面 43 scorelable=new JLabel();//添加上面的计分板 44 add(scorelable,BorderLayout.NORTH); 45 //中间 46 gameCanvas=new Canvas();//添加游戏界面,利用Canvas画板 47 gameCanvas.setSize(gameWidth+10,gameHeight+10);//设置画板的尺寸, 48 // 10代表与右边距离 49 //gameCanvas.addKeyListener(control); 50 add(gameCanvas,BorderLayout.CENTER); 51 52 JPanel panelhaha = new JPanel(); 53 panelhaha.setLayout(new BorderLayout()); 54 JLabel labelHelp; 55 labelHelp=new JLabel("CC PLAY Snake",JLabel.CENTER); 56 panelhaha.add(labelHelp,BorderLayout.NORTH); 57 add(panelhaha, BorderLayout.SOUTH); 58 59 this.pack();//来使得框架尽可能适应组件大小 60 this.addKeyListener(control);//添加keyListener的触发事件,控制蛇运动 61 setResizable(false);//使得窗口无法变化大小 62 setVisible(true); 63 64 } 65 public void update(Observable o, Object arg) 66 { 67 repaint();//update是observer的setchange() 68 } 69 public void repaint() 70 { 71 Graphics p=gameCanvas.getGraphics(); 72 //对贪吃蛇界面进行画刷的颜色填充 73 p.setColor(Color.black); 74 p.fillRect(0,0, gameWidth, gameHeight); 75 //对蛇体进行矩阵填充节点 76 p.setColor(Color.white); 77 LinkedList snake=model.nodeSnake; 78 Iterator it=snake.iterator();//迭代器获取LinkList 79 while(it.hasNext()) 80 { 81 Node n=(Node)it.next(); 82 drawNode(p,n); 83 } 84 scorelable.setText("Code by CC:"); 85 86 //对食物进行矩阵的填充 87 p.setColor(Color.red); 88 Node n=model.food; 89 drawNode(p, n); 90 } 91 private void drawNode(Graphics g,Node n) 92 { 93 g.fillRect(n.x*nodeWidth, n.y*nodeHeight, nodeWidth-1,nodeHeight-1);/*设置 Snake 节点Size 94 =(0,canvaswight/nodeWidth) 因为要保证每个结点能够以10为单位*/ 95 } 96 public static void main(String args[]) 97 { 98 SnakeModel model=new SnakeModel(60,60); 99 SnakeControl control=new SnakeControl(model); 100 SnakeView snakeView=new SnakeView(model, control); 101 model.addObserver(snakeView);//将SnakeView设置为model的一个观察者 102 (new Thread(model)).start();//为SnakeModel开一个线程 103 } 104 }
SnakeModel.class//关于蛇的系列操作以及蛇的坐标,方向设置
1 package GreedSnake; 2 3 import java.util.Arrays; 4 import java.util.LinkedList; 5 import java.util.Observable; 6 import java.util.Random; 7 8 import javax.swing.JOptionPane; 9 10 public class SnakeModel extends Observable implements Runnable 11 { 12 boolean[][]matrix;//指示当前位子是否有蛇体或者食物 13 LinkedList nodeSnake=new LinkedList(); 14 Node food; 15 int score; 16 boolean pause=false;//设置游戏中断 17 //初始化60,60,画面(0,0)-(59,59) 18 int maxX;//画面的最大横坐标 19 int maxY;//画面的最大纵坐标 20 int direction=2; //指示蛇运行的方向 21 boolean running =false;//指示蛇是否在运动 22 public static final int UP=2; 23 public static final int DOWN=4; 24 public static final int LEFT=1; 25 public static final int RIGHT=3; 26 public SnakeModel(int maxX,int maxY) 27 { 28 this.maxX=maxX; 29 this.maxY=maxY; 30 reset();//初始化游戏 31 } 32 public void reset() 33 { 34 direction=SnakeModel.DOWN; 35 pause=false; 36 matrix=new boolean[maxX][]; 37 for(int i=0;i<maxX;i++) 38 { 39 matrix[i]=new boolean[maxY]; 40 Arrays.fill(matrix[i],false); 41 } 42 43 //Init Snake 44 int initArrayLength = maxX > 60 ? 30 : maxX / 2;//初始化蛇的长度 45 nodeSnake.clear(); 46 for(int i=0;i<initArrayLength;i++) 47 { 48 int x=maxX/2+i; 49 int y=maxY/2; 50 nodeSnake.addLast(new Node(x, y));//不断向蛇尾初始化节点 51 matrix[x][y]=true; 52 } 53 54 //Create food 55 food=createfood();//获得初始化食物坐标 56 matrix[food.x][food.y]=true; 57 } 58 public void Changedirection(int Newdirection) 59 { 60 if(direction%2!=Newdirection%2)//若与当前方向相反或者一样,则不变方向 61 direction=Newdirection; 62 } 63 public boolean moveon() 64 { 65 Node n=(Node)nodeSnake.getFirst();//蛇头+direction来判断下一步 66 int x=n.x; 67 int y=n.y; 68 //根据方向判断走向 69 switch (direction) 70 { 71 case UP: 72 y--; 73 break; 74 case DOWN: 75 y++; 76 break; 77 case LEFT: 78 x--; 79 break; 80 case RIGHT: 81 x++; 82 break; 83 } 84 if((x>=0&&x<=maxX-1)&&(y>=0&&y<=maxY-1))//判断是否在画面中 85 { 86 if(matrix[x][y]) 87 { 88 if(food.x==x&&food.y==y) 89 { 90 nodeSnake.addFirst(food); 91 92 food=createfood(); 93 matrix[food.x][food.y]=true; 94 return true; 95 } 96 else return false; 97 } 98 else 99 { 100 //将尾巴放到头部 101 nodeSnake.addFirst(new Node(x, y)); 102 matrix[x][y]=true; 103 n=(Node)nodeSnake.removeLast(); 104 matrix[n.x][n.y]=false; 105 return true; 106 } 107 } 108 return false;//触到边界 109 } 110 public Node createfood() 111 { 112 int x=0; 113 int y=0; 114 do//生成食物节点的坐标 115 { 116 Random r=new Random(); 117 x=r.nextInt(maxX); 118 y=r.nextInt(maxY); 119 } while (matrix[x][y]); 120 return new Node(x, y); 121 } 122 class Node 123 { 124 int x; 125 int y; 126 Node(int x,int y) 127 { 128 this.x=x; 129 this.y=y; 130 } 131 } 132 public void run() 133 { 134 running=true; 135 while(running) 136 { 137 try 138 { 139 Thread.sleep(100); 140 } catch (InterruptedException e) 141 { 142 e.printStackTrace(); 143 } 144 if(!pause) 145 { 146 if(moveon()) 147 { 148 // if(score>=100) 149 // { 150 // JOptionPane.showMessageDialog(null, "猪智23333333", "Game Over", 151 // JOptionPane.INFORMATION_MESSAGE); 152 // } 153 //用来判断Observer的对象是否发生更新 154 //若更新,则触发SnakeViewd的update()来重绘画面 155 setChanged(); 156 notifyObservers(); 157 } 158 else{ 159 JOptionPane.showMessageDialog(null, "you have failed", "Game Over", 160 JOptionPane.INFORMATION_MESSAGE);//跳出结束文本框 161 break; 162 } 163 } 164 } 165 running=false; 166 } 167 public void StopSnake() 168 { 169 pause=!pause; 170 } 171 }
SnakeControl.class//关于键盘对蛇的方向操作以及中断继续游戏的操作
1 package GreedSnake; 2 3 import java.awt.event.KeyEvent; 4 import java.awt.event.KeyListener; 5 6 public class SnakeControl implements KeyListener 7 { 8 SnakeModel model; 9 public SnakeControl(SnakeModel model) 10 { 11 this.model=model; 12 } 13 public void keyPressed(KeyEvent e) 14 { 15 int keyCode=e.getKeyCode();//获取当前键盘的键值 16 if(model.running)//Snake is running 17 { 18 switch (keyCode) 19 { 20 case KeyEvent.VK_UP: 21 model.Changedirection(SnakeModel.UP); 22 break; 23 case KeyEvent.VK_DOWN: 24 model.Changedirection(SnakeModel.DOWN); 25 break; 26 case KeyEvent.VK_LEFT: 27 model.Changedirection(SnakeModel.LEFT); 28 break; 29 case KeyEvent.VK_RIGHT: 30 model.Changedirection(SnakeModel.RIGHT); 31 break; 32 case KeyEvent.VK_SPACE: 33 model.StopSnake();; 34 break; 35 } 36 } 37 if(keyCode==KeyEvent.VK_ENTER) 38 model.reset(); 39 } 40 @Override 41 public void keyReleased(KeyEvent e) 42 { 43 // TODO 自动生成的方法存根 44 45 } 46 @Override 47 public void keyTyped(KeyEvent e) 48 { 49 // TODO 自动生成的方法存根 50 51 } 52 53 }