游戏截图:

贪吃蛇java版代码 java贪吃蛇源代码_贪吃蛇java版代码


贪吃蛇java版代码 java贪吃蛇源代码_贪吃蛇java版代码_02


文件布局:

贪吃蛇java版代码 java贪吃蛇源代码_System_03


代码分享

用到的一些全局变量

//全局变量
public class Global {
	public static final int RECT_WIDTH=20;//每个小方格的长宽
	public static final int WIDTH=30;//长    40个小方格
	public static final int HEIGHT=30;//宽   40个小方格
	public static int GRADE;//成绩
	public static long TIME;//时间
	public static File file;//文件夹
}

定义蛇类

public class Snake {
	private SnakeListener snakeListener;
	public static final int UP=1;
	public static final int DOWN=-1;
	public static final int LEFT=2;
	public static final int RIGHT=-2;//表示蛇运动的方向
	
	private int newdirction=RIGHT;
	private int olddirction=RIGHT;
	
	private Point tail;//存储蛇的尾巴
	
	public LinkedList<Point> body=new LinkedList<Point>();
	private Point p;
	
	//蛇的颜色
	private int x,y,z;
	
	private boolean suspendFlag = false;// 控制线程的执行
	private SnakeDriver sd=new SnakeDriver();
	
	public static boolean life=true;
	public Snake(){
		init();
	}
	//获取蛇的长度
	public int getlenght() {
		return body.size();
	}
	public void init() {
		int x=Global.WIDTH/2;
		int y=Global.HEIGHT/2;
		for(int i=0;i<3;i++) {
			p=new Point(x-i,y);//默认方向是向右的
			body.add(p);
		}
	}
	
	public void move() {
//		System.out.println("蛇在移动...");
		//去尾加头法实现蛇移动  首先要得到蛇头
		tail=body.removeLast();
		
		int x=getSnakehead().x;
		int y=getSnakehead().y;
		if(this.newdirction+this.olddirction!=0)
			this.olddirction=this.newdirction;    //控制方向不往反方向行走
		switch(olddirction) {
		case UP:
			y--;
			break;
		case DOWN:
			y++;
			break;
		case LEFT:
			x--;
			break;
		case RIGHT:
			x++;
			break;
		}
		body.addFirst(new Point(x,y));
	}
	
	//得到蛇头位置
	public Point getSnakehead() {
		return body.getFirst();
	}
	public void eatfood() {
//		System.out.println("蛇正在吃食物...");
		//怎么吃  就是将蛇的尾巴加回来  则用变量存储蛇的尾巴
		body.addLast(tail);
	}
	public void changedirction(int dirction) {
		this.newdirction=dirction;
//		System.out.println("正在改变方向...");
	}
	public boolean iseatself(Snake snake) {
		Point head=snake.getSnakehead();
		for(int i=1;i<body.size();i++)
		{
			if(body.get(i).equals(head))
				return true;
		}
		return false;
	}
	public void drowMe(Graphics g) {
//		System.out.println("蛇正在画出自己...");
		//g.setColor(Color.blue);
		for(int i=0;i<body.size();i++) {
			x=(int) (Math.random()*256);
			y=(int) (Math.random()*256);
			z=(int) (Math.random()*256);
			Color color=new Color(x,y,z);
			g.setColor(color);
			g.fillRect(body.get(i).x*Global.RECT_WIDTH, body.get(i).y*Global.RECT_WIDTH, Global.RECT_WIDTH, Global.RECT_WIDTH);
		}
	}
	//增加了自定义的监听器
	public void addSnakeListener(SnakeListener snakeListener) {
		if(snakeListener!=null){
			this.snakeListener=snakeListener;
		}
	}
	
	public void start() {
//		new SnakeDriver().start();
		sd.start();
	}
	//得到线程对象
	public SnakeDriver getsd() {
		return sd;
	}
	//线程暂停
	public void suspend() {
		suspendFlag=true;
	}

	public class SnakeDriver extends Thread{
		//唤醒线程
		public synchronized void Rouse() {
			suspendFlag=false;
			notify();
		}
		@Override
		public void run() {
			while(life)
			{
				move();
				//每移动一次要判断是否吃到食物和墙
				snakeListener.snakeMove(Snake.this);//调用外部类的当前对象
				try {
					Thread.sleep(200);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				synchronized(this) {
					while(suspendFlag) {
						try {
							wait();
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
			}
			
		}
	}
}

定义食物类

public class Food {
	//定义两变量来存储food的位置
	private int x,y;
	public void drowMe(Graphics g) {
//		System.out.println("食物正在画出自己...");
		g.setColor(Color.red);
		g.fillRect(x*Global.RECT_WIDTH,y*Global.RECT_WIDTH, Global.RECT_WIDTH,Global.RECT_WIDTH);
	}
	public boolean iseatbysnake(Snake snake) {
		//怎么判断食物被蛇吃了  判断是否在同一位置
		Point head=snake.getSnakehead();
		Point p=new Point(x,y);
		if(p.equals(head))
			return true;
		return false;
	}
	//增加食物
	public void addFood(Point p) {
		x=p.x;
		y=p.y;
	}
	//设置food的位置
	public Point setloction() {
		int x=(int)(Math.random()*30)+1;
		int y=(int)(Math.random()*30)+1;
		return new Point(x,y);
	}
}

定义地图类

public class Map {
	private int[][] map=new int[Global.WIDTH+2][Global.HEIGHT+2];//存储边框的数据位置
	
	public Map() {
		for(int y=0;y<Global.HEIGHT+2;y++)
		{
			for(int x=0;x<Global.WIDTH+2;x++)
			{
				if(y==0||y==Global.HEIGHT+2-1)
					map[x][y]=1;
				if(x==0||x==Global.WIDTH+2-1)
					map[x][y]=1;
			}
		}
	}
	public void drowMe(Graphics g) {
//		System.out.println("正在画出地图...");
		SetRectangle(g);
	}
	public boolean iseatbysnake(Snake snake) {
		Point head=snake.getSnakehead();
		for(int k=0;k<Global.WIDTH+2;k++) {
			for(int m=0;m<Global.HEIGHT+2;m++) {
				if(map[k][m]==1&&head.x==k&&head.y==m)
					return true;
			}
		}
		return false;
	}
	private void SetRectangle(Graphics g)
	{
		Graphics2D gp=(Graphics2D)g;
		Rectangle2D rect=new Rectangle2D.Double(20, 20, 600, 600);
		Stroke s=new BasicStroke(5);
		gp.setStroke(s);
		gp.draw(rect);
	}
}

//定义接口用来监听Snake是否碰撞

public interface SnakeListener {
	public void snakeMove(Snake snake);
}

GUI显示

public class GamePanel extends JPanel{
	private Snake snake=new Snake();
	private Food food;
	private Map map;
	
	private int x,y,z;
	
	private JLabel label;  
	private JLabel explain1;
	private JLabel explain2;
	private JLabel explain3;
	private JLabel explain4;
	private JLabel explain5;
	private JLabel grade;
	private JLabel time;
	
	private long endtime;//时间

	public static long TIME;//最终显示时间
	public static int GRADE;//最终显示分数
	private JLabel bgm_label;
	private BufferedImage img=null;
	
	private Font font=new Font("宋体",Font.PLAIN,20);
	public GamePanel() {
		setLayout(null);
		//加入说明
		Count() ;
		//加入图片
		addBgm();
	}
	public void dispaly(Snake snake,Food food,Map map) {
//		System.out.println("面板正在画出自己...");
		this.snake=snake;
		this.food=food;
		this.map=map;
		repaint();     //自动调用了paintComponent方法
	}
	
	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		SetLine(g);
		drawNum(g);
		if(food!=null)
			food.drowMe(g);
		if(map!=null)
			map.drowMe(g);
		if(snake!=null)
			snake.drowMe(g);
	}
	private void drawNum(Graphics g) {
		//分数
		g.setColor(Color.black);
		g.setFont(new Font("宋体",Font.PLAIN,36));
		Global.GRADE=(snake.getlenght()-3)*5;
		g.drawString(""+Global.GRADE+"", 720, 330);
		//时间
		endtime=System.currentTimeMillis();
		Global.TIME=(endtime-Controller.starttime)/1000;
		g.drawString(""+Global.TIME+""+"秒", 720, 390);
	}
	private void SetLine(Graphics g)
	{
		Graphics2D gl=(Graphics2D)g;
		Stroke s=new BasicStroke();
		gl.setStroke(s);
		for(int i=1;i<30;i++)
		{
//			x=(int) (Math.random()*256);
//			y=(int) (Math.random()*256);
//			z=(int) (Math.random()*256);
//			Color color=new Color(x,y,z);
			x=154;//222
			y=157;//225
			z=162;//230
			Color color=new Color(x,y,z);
			gl.setColor(color);
			Line2D Virtical_L=new Line2D.Double(Global.RECT_WIDTH*i+20, 20, Global.RECT_WIDTH*i+20, 620);
			gl.draw(Virtical_L);
			Line2D Level_L=new Line2D.Double(20, Global.RECT_WIDTH*i+20, 620, Global.RECT_WIDTH*i+20);
			gl.draw(Level_L);
		}
	}
	public void Count() {
		label=new JLabel("版权:12210");
		label.setLocation(630, 20);
		label.setSize(200, 50);
		label.setFont(font);
		add(label);
		//解释
		explain1=new JLabel("说明:↑ ↓ ← →键");
		explain2=new JLabel("控制方向");
		explain3=new JLabel("暂停:Space");
		explain4=new JLabel("继续:Enter");
		explain5=new JLabel("退出:Esc");
		explain1.setBounds(630, 90, 200,20);
		explain2.setBounds(630, 130, 200, 20);
		explain3.setBounds(630, 170, 200, 20);
		explain4.setBounds(630, 210, 200, 20);
		explain5.setBounds(630, 250, 200, 20);
		explain1.setFont(font);
		explain2.setFont(font);
		explain3.setFont(font);
		explain4.setFont(font);
		explain5.setFont(font);
		add(explain1);
		add(explain2);
		add(explain3);
		add(explain4);
		add(explain5);
		//分数
		grade=new JLabel("分数:");
		grade.setBounds(630, 300, 100, 30);
		grade.setFont(new Font("宋体",Font.PLAIN,30));
		add(grade);
		//时间
		time=new JLabel("时间:");
		time.setBounds(630, 360, 100, 30);
		time.setFont(new Font("宋体",Font.BOLD,30));
		add(time);
	}
	//加入图片
	public void addBgm() {
		try {
			img=ImageIO.read(new File("bgm.png"));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		bgm_label=new JLabel(new ImageIcon(img));
		bgm_label.setBounds(630,400,img.getWidth(),img.getHeight());
		add(bgm_label);
	}
}

控制游戏

public class Controller extends KeyAdapter implements SnakeListener{
	private Snake snake;
	private Food food;
	private Map map;
	private GamePanel gamepanel;
	
	public static long starttime;//开始游戏时间
	
	public Controller(Snake snake, Food food, Map map, GamePanel gamepanel) {
		super();
		this.snake = snake;
		this.food = food;
		this.map = map;
		this.gamepanel = gamepanel;
	}
	
	@Override
	public void keyPressed(KeyEvent e) {
		super.keyPressed(e);
//		System.out.println("改变方向...");
		switch(e.getKeyCode()) {
		case KeyEvent.VK_UP:
			snake.changedirction(Snake.UP);
			break;
		case KeyEvent.VK_DOWN:
			snake.changedirction(Snake.DOWN);
			break;
		case KeyEvent.VK_RIGHT:
			snake.changedirction(Snake.RIGHT);
			break;
		case KeyEvent.VK_LEFT:
			snake.changedirction(Snake.LEFT);
			break;
		case KeyEvent.VK_SPACE:
			snake.suspend();
			break;
		case KeyEvent.VK_ESCAPE:
			System.exit(0);
			break;
		default:
			snake.getsd().Rouse();
			break;
		}
			
	}

	@Override
	public void snakeMove(Snake snake) {
//		System.out.println("判断是否迟到食物或墙...");
		if(food.iseatbysnake(snake)==true) {
			snake.eatfood();
			//增加新的食物位置
			food.addFood(food.setloction());
		}
		if(map.iseatbysnake(snake)) {
			JOptionPane.showMessageDialog(null, "傻瓜,撞到墙啦!");
			Snake.life=false;
			JOptionPane.showMessageDialog(null, "分数:"+""+Global.GRADE+""+"分"+"   "+"耗时:"+""+Global.TIME+""+"秒");
			System.exit(0);
		}
		if(snake.iseatself(snake)) {
			JOptionPane.showMessageDialog(null, "傻瓜,吃到自己啦!");
			Snake.life=false;
			JOptionPane.showMessageDialog(null, "分数:"+""+Global.GRADE+""+"分"+"   "+"耗时:"+""+Global.TIME+""+"秒");
			System.exit(0);
		}
		gamepanel.dispaly(snake, food, map);;
	}
	public void startGame() {
		starttime=System.currentTimeMillis();
		snake.start();
		food.addFood(food.setloction());
	}
}

主程序

class Window extends JFrame{
	private Snake snake=new Snake();
	private Food food=new Food();
	private Map map=new Map();
	private GamePanel gamepanel=new GamePanel();
	private Controller controller=new Controller(snake, food, map, gamepanel);
	
	//背景音乐的变量
	private URI uri;
	private URL url;
	//增加文字
	JLabel label;
	public Window(){
		this.setBounds(100, 100, 900, 680);
		this.setTitle("贪吃蛇 version2.0");
		this.setResizable(false);
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		
		snake.addSnakeListener(controller);
		gamepanel.addKeyListener(controller);
		gamepanel.setFocusable(true);
		
		this.add(gamepanel);
		this.setVisible(true);
		music();
		controller.startGame();
	}
	//添加背景音乐
	public void music() {
		System.out.println("运行了!");
		try{
			File f=new File("周二珂 - 告白气球.wav");
			uri=f.toURI();
			url=uri.toURL();
			AudioClip auu=Applet.newAudioClip(url);
			auu.loop();
		}catch(Exception e) {
			e.printStackTrace();
		}
	}
}
class GameThread extends Thread{
	@Override
	public void run() {
		new Window();
	}
}
public class Client{
	public static void main(String[] args) throws UnknownHostException, IOException {
//		Socket socket=new Socket("127.0.0.1",9999);
		new GameThread().start();
//		Operation ope=new Operation();
//		ope.Write(socket);
//		ope.Read();
//		socket.close();	
	}

}

嘿嘿 新手 看视频学的 加油2020年
应该能执行成功的
源码下载