贪吃蛇
这个小程序总体来说比较简单,就不做太多的解释了,相信大家很容易看懂的
执行程序:程序启动的入口
package cn.hncu; public class GreedySnake { public static void main(String[] args) { Model model=new Model(80, 50); Control control=new Control(model); View view=new View(model,control); model.addObserver(view); (new Thread(model)).start(); } }
控制类:主要进行键盘的按键收集和传递
package cn.hncu; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; public class Control implements KeyListener{ Model model; public Control(Model model){ this.model=model; } public void keyPressed(KeyEvent e) { //此方法收集按键 int key=e.getKeyCode(); if (model.running) { switch (key) { case KeyEvent.VK_UP: model.changeDirection(model.up); break; case KeyEvent.VK_DOWN: model.changeDirection(model.down); break; case KeyEvent.VK_LEFT: model.changeDirection(model.left); break; case KeyEvent.VK_RIGHT: model.changeDirection(model.right); break; default: break; } } if (key==KeyEvent.VK_ENTER) { model.reset(); } } public void keyReleased(KeyEvent e) { } public void keyTyped(KeyEvent e) { } }模型类:创建蛇身和蛇的运动方式的实现,用到了线程,关于线程的知识可见本博客的多线程 点击打开链接
package cn.hncu; import java.util.Arrays; import java.util.LinkedList; import java.util.Observable; import java.util.Random; import javax.swing.JOptionPane; public class Model extends Observable implements Runnable{ public static final int left=1; public static final int up=2; public static final int right=3; public static final int down=4; public boolean coordinate[][];//用这个来当做界面的坐标 public LinkedList node=new LinkedList(); public int direction=2; boolean running=false; public int maxX,maxY; Node food; public int sleeptime=200; public Model(int maxX,int maxY){ this.maxX=maxX; this.maxY=maxY; reset(); } public void reset() { direction=this.up; sleeptime=200; coordinate=new boolean[maxX][]; for (int i = 0; i < maxX; i++) { coordinate[i]=new boolean[maxY]; Arrays.fill(coordinate[i], false); } //initialize the Snake'body int initlenght=10; node.clear(); for (int j = 0; j < initlenght; j++) { int x=maxX/2+j; int y=maxY/2; node.addLast(new Node(x,y)); coordinate[x][y]=true; } food=createFood(); coordinate[food.x][food.y]=true; } public boolean move(){ Node n=(Node)node.getFirst(); int x=n.x; int y=n.y; switch (direction) { case up: y--; break; case down: y++; break; case left: x--; break; case right: x++; break; default: break; } if ((x>=0&&x<maxX)&&(y>=0&&y<maxY)) { if (coordinate[x][y]) { if (x==food.x&&y==food.y) { node.addFirst(food); if (sleeptime>35) { sleeptime-=20; } food=createFood(); coordinate[food.x][food.y]=true; return true; }else { return false; } }else { node.addFirst(new Node(x,y)); coordinate[x][y]=true; n=(Node)node.getLast(); node.removeLast(); coordinate[n.x][n.y]=false; return true; } } return false; } public void changeDirection(int newdir){ if (direction!=newdir) { direction=newdir; } } public Node createFood() { int x=0,y=0; do { Random r = new Random(); x = r.nextInt(maxX); y = r.nextInt(maxY); } while (coordinate[x][y]); return new Node(x, y); } public void run() { running=true; while(running){ try { Thread.sleep(sleeptime); } catch (Exception e) { break; } if (move()) { setChanged(); notifyObservers(); }else { JOptionPane.showMessageDialog(null, "Game Over"); break; } } } } class Node{//创建蛇身 public int x,y; public Node(int x,int y){ this.x=x; this.y=y; } }界面层:展现给用户看的,用图形界面展现蛇的运动
package cn.hncu; import java.awt.BorderLayout; import java.awt.Canvas; import java.awt.Color; import java.awt.Container; import java.awt.Graphics; import java.util.Iterator; import java.util.LinkedList; import java.util.Observable; import java.util.Observer; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; public class View extends JFrame implements Observer{ Control control; Model model; Canvas canvas; public static final int canvasWidth=800,canvasHeight=500; public static final int nodeWidth=10,nodeHeight=10; public View(Model model,Control control){ super("GreedySnake"); this.control=control; this.model=model; this.setLocation(400, 300); this.setResizable(false); this.setDefaultCloseOperation(EXIT_ON_CLOSE); canvas=new Canvas(); canvas.setSize(canvasWidth+1, canvasHeight+1); canvas.addKeyListener(control); this.add(canvas,BorderLayout.NORTH); JPanel panel=new JPanel(); this.add(panel,BorderLayout.SOUTH); JLabel label=new JLabel("Enter for restart"); panel.add(label); this.pack(); this.addKeyListener(control); this.setVisible(true); } public void repaint() { Graphics g=canvas.getGraphics(); // draw background g.setColor(Color.white); g.fillRect(0, 0, canvasWidth, canvasHeight); // draw snake g.setColor(Color.red); LinkedList node=model.node; Iterator it=node.iterator(); while(it.hasNext()){ Node n=(Node)it.next(); drawNode(g,n); } // draw food g.setColor(Color.black); Node n=model.food; drawNode(g,n); } private void drawNode(Graphics g, Node n) { g.fillOval(n.x*nodeWidth, n.y*nodeHeight, nodeWidth, nodeHeight); } public void update(Observable o, Object arg) { repaint(); } }