Java实现贪吃蛇

贪吃蛇

这是用Java的Swing工具实现的一个小程序。
与传统的贪吃蛇游戏一样,通过“上、下、左、右”控制方向觅食
  死亡条件:①头碰到身体。②头碰到墙壁。

项目主要分为三块
一个是蛇snake
一个是蛋egg
还有一个是界面yard

主要源码可以在我的GItHub仓库中找到

仓库地址

Snake

package demo01;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;

public class Snake {
	Node head = null;
	Node tail = null;
	int size = 0;
	Node node=new Node (20,40,Dir.L);
	private Yard y;
	
	//定义一个蛇
	public Snake(Yard y) {
		head=node;
		tail=node;
		size=1;
		this.y=y;
	}
	
	//尾部添加一个节点
	public void addToTail() {
		Node node = null;
		switch(tail.dir) {
		case L :
			node = new Node (tail.row , tail.col + 1 , tail.dir);
			break;
		case U :
			node = new Node (tail.row + 1 , tail.col , tail.dir);
			break;
		case R :
			node = new Node (tail.row , tail.col - 1 , tail.dir);
			break;
		case D :
			node = new Node (tail.row - 1 , tail.col , tail.dir);
			break;
		}
		tail.next=node;
		
		node.prev=tail;
		tail=node;
		size++;
	}
	
	//头部添加一个节点
	public void addToHead() {
		Node node = null;
		switch(head.dir) {
		case L :
			node = new Node (head.row , head.col - 1 , head.dir);
			break;
		case U :
			node = new Node (head.row - 1 , head.col , head.dir);
			break;
		case R :
			node = new Node (head.row , head.col + 1 , head.dir);
			break;
		case D :
			node = new Node (head.row + 1 , head.col , head.dir);
			break;
		}
		node.next=head;
		
		head.prev=node;
		head=node;
		size++;
	}
	
	//画出蛇,同时蛇开始移动
	public void draw(Graphics g) {
		move();
		for(Node n = head ; n!=null;n = n.next) {
			n.draw(g);
		}
	}
	
	//蛇开始移动,就是把头部前面加一个,尾部去掉一个别的不变
	private void move() {
		addToHead();
		deleteFromTail();
		checkdead();
	}

	//检验是否死掉
	private void checkdead() {
		// TODO Auto-generated method stub
		if(head.row<3||head.row>Yard.ROWS-2||head.col<1||head.col>Yard.COLS-2) {
			y.stop();
		}
		
		for(Node n=head.next;n!=null;n=n.next) {
			if(head.row==n.row&&head.col==n.col) {
				y.stop();
			}
		}
	}

	//删除蛇的尾部
	private void deleteFromTail() {
		if(size==0) {
			return;
		}
		tail=tail.prev;
		tail.next=null;
		
	}

	//蛇身上的节点
	private class Node {
		//每个点的深度
		int w=Yard.BLOCK_SIZE;
		//每个点的宽度
		int h=Yard.BLOCK_SIZE;
		//点的坐标col是x,row是y
		int row , col;
		//方向的枚举型
		Dir dir=Dir.L;
		
		Node next=null;
		Node prev=null;
		//初始化
		Node(int row , int col , Dir dir) {
			this.row = row;
			this.col = col;
			this.dir = dir;
		}
		
		void draw(Graphics g) {
			Color c=g.getColor();
			//设置颜色
			g.setColor(Color.BLACK);
			//画出节点
			g.fillRect(col*Yard.BLOCK_SIZE ,row*Yard.BLOCK_SIZE ,  w , h);
		
			g.setColor(c);
			
		}
	}
	
	public void eat(Egg e) {
		if(this.getRect().intersects(e.getRect())) {
			e.reAppear();
			addToHead();
			y.setScore(y.getScore()+1);
		}
	}
	
	public Rectangle getRect() {
		return new Rectangle(Yard.BLOCK_SIZE*head.col , Yard.BLOCK_SIZE*head.row , head.w , head.h);
	}
	
	//根据监听器判断蛇的方向
	public void keyPress(KeyEvent e) {
		int key =e.getKeyCode();
		switch(key){
		case KeyEvent.VK_UP:
			if(head.dir!=Dir.D)
				head.dir=Dir.U;
			break;
		case KeyEvent.VK_DOWN:
			if(head.dir!=Dir.U)
				head.dir=Dir.D;
			break;
		case KeyEvent.VK_LEFT:
			if(head.dir!=Dir.R)
				head.dir=Dir.L;
			break;
		case KeyEvent.VK_RIGHT:
			if(head.dir!=Dir.L)
				head.dir=Dir.R;
			break;
		}
		
	}
}

Egg

package demo01;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.Random;

public class Egg {
	int row,col;
	int w=Yard.BLOCK_SIZE;
	int h=Yard.BLOCK_SIZE;
	private Color color=Color.GREEN;
	private static Random r=new Random();

	public Egg(int row, int col) {
		super();
		this.row = row;
		this.col = col;
	}
	public Egg() {
		this(r.nextInt(Yard.ROWS-6)+3,r.nextInt(Yard.COLS-6)+3);
	}
	
	public void draw(Graphics g) {
		Color c=g.getColor();
		g.setColor(color);
		g.fillOval(col*Yard.BLOCK_SIZE ,row*Yard.BLOCK_SIZE ,  w , h);
		g.setColor(c);
		if(color==Color.GREEN) {
			color=Color.RED;
		}else {
			color=Color.GREEN;
		}
		
	}
	
	public Rectangle getRect() {
		return new Rectangle(Yard.BLOCK_SIZE*col , Yard.BLOCK_SIZE*row , w , h);
	}
	
	public void reAppear() {
		this.col=r.nextInt(Yard.COLS-6)+3;
		this.row=r.nextInt(Yard.ROWS-6)+3;
	}
}

Yard

package demo01;

import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class Yard extends Frame {
	
	PaintThread paintThread=new PaintThread();
	Thread t=new Thread(paintThread);
	private boolean gameOver=false;
	public final static int ROWS=50;	
	public final static int COLS=50;
	public final static int BLOCK_SIZE=10;
	private int score=0;
	
	Egg e=new Egg();
	
	Snake s=new Snake(this);
	
	Image offScreenImage=null;

	public static void main(String[] args) {
		new Yard().launch();
	}
	
	public void launch () {
		//创建窗口
		setBounds(200,200, COLS*BLOCK_SIZE, ROWS*BLOCK_SIZE);
		//设置可见性
		setVisible(true);
		//添加关闭监听
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		//添加键盘监听
		addKeyListener(new KeyMonitor());
		//刷新线程启动
		t.start();
	}
	
	@Override
	public void paint(Graphics g) {
		Color c=g.getColor();
		//背景色
		g.setColor(Color.GRAY);
		//背景大小
		g.fillRect(0,0, COLS*BLOCK_SIZE, ROWS*BLOCK_SIZE);
		//画线的颜色
		g.setColor(Color.DARK_GRAY);
		//画线
		for(int i=1;i<ROWS;i++) {
			g.drawLine(0, BLOCK_SIZE*i,COLS*BLOCK_SIZE , BLOCK_SIZE*i);
//			g.drawLine(BLOCK_SIZE*i,0, BLOCK_SIZE*i, COLS*BLOCK_SIZE);
		}
		for(int i=1;i<COLS;i++) {
			
			g.drawLine(BLOCK_SIZE*i,0, BLOCK_SIZE*i, ROWS*BLOCK_SIZE);
		}
		g.setColor(Color.yellow);
		if(gameOver) {
			g.setFont(new Font("宋体",Font.BOLD,30));
			g.drawString("game over! you score :"+score,40,60);
			paintThread.gameOver();
		}else {
			g.drawString("score:"+score,10, 50);
			
		}
		g.setColor(c);
		//画鸡蛋
		e.draw(g);
		//画蛇
		s.draw(g);
		//蛇吃蛋
		s.eat(e);
		
		
	}
	
	public int getScore() {
		return score;
	}

	public void setScore(int score) {
		this.score = score;
	}

	@Override
	public void update(Graphics g) {
		//双缓存结构
		if(offScreenImage==null) {
			offScreenImage=this.createImage(BLOCK_SIZE*COLS, BLOCK_SIZE*ROWS);
		}
		Graphics goff=offScreenImage.getGraphics();
		print(goff);
		g.drawImage(offScreenImage,0,0,null);
		
	}
	
	public void stop() {
		gameOver=true;
		
	}
	
	//刷新的线程,每五十毫秒重新画一次蛇
	private class PaintThread implements Runnable{
		private boolean Running=true;
		@Override
		public void run() {
			while(Running) {
				repaint();
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
		}
		public void gameOver() {
			Running=false;
		}
		
	}
	//键盘监听
	private class KeyMonitor extends KeyAdapter{
		@Override
		public void keyPressed(KeyEvent e) {
			s.keyPress(e);
		}
	}
}

你可能感兴趣的:(Java)