Java小程序------贪吃蛇

贪吃蛇

这个小程序总体来说比较简单,就不做太多的解释了,相信大家很容易看懂的


执行程序:程序启动的入口

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

你可能感兴趣的:(java,贪吃蛇,界面)