贪食蛇游戏(java实现)


Dir.java

public enum Dir {
	L,U,R,D
}

Egg.java

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 static Random r = new Random() ;
	private Color color = Color.GREEN ;
	
	public Egg(int row, int col) {
		super();
		this.row = row;
		this.col = col;
	}
	
	public int getRow() {
		return row;
	}

	public void setRow(int row) {
		this.row = row;
	}

	public int getCol() {
		return col;
	}

	public void setCol(int col) {
		this.col = col;
	}

	public Egg(){
		this(r.nextInt(Yard.ROWS-3)+2,r.nextInt(Yard.COLS-2)+1) ;
		
	}
	
	public void reAppear(){
		this.row = r.nextInt(Yard.ROWS-3)+2;
		this.col = r.nextInt(Yard.COLS-2)+1;
	}

	public Rectangle getRect() {
		return new Rectangle(Yard.BLOCK_SIZE*this.col,Yard.BLOCK_SIZE*this.row,this.w,this.h) ;
	}
	
	public void draw(Graphics g){
		Color c = g.getColor() ;
		g.setColor(color) ;
		g.fillOval(Yard.BLOCK_SIZE*col,Yard.BLOCK_SIZE*row,w,h) ;
		g.setColor(c) ;
		if(color == Color.GREEN) color = Color.RED ;
		else color = Color.GREEN ;
	}
	
	
}


Snake.java

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


public class Snake {
	private Node head = null ;
	private Node tail = null ;
	private int size = 0 ;
	private Yard y ;
	
	private Node n = new Node(20,29,Dir.L) ;
	
	public int getSize(){
		return this.size ;
	}
	public Snake(Yard y){
		head = n ;
		tail = n ;
		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){
		if(size <= 0) return ;
		move() ;
		for(Node n = head; n!=null; n=n.next){
			n.draw(g) ;
		}
	

	}
	
	private void move() {
		addToHead() ;
		deleteFromTail() ;
		checkDead() ;
	}
	
	private void checkDead() {
		if(head.row < 2 || head.col < 1 || head.row >Yard.ROWS-2 || 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 ;
		size--;
	}

	private class Node{
		int w = Yard.BLOCK_SIZE ;
		int h = Yard.BLOCK_SIZE ;
		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.fillOval(Yard.BLOCK_SIZE*col,Yard.BLOCK_SIZE*row,w,h) ;
			g.setColor(c) ;
		}
	}
	
	public void eat(Egg e){
		if(this.getRect().intersects(e.getRect())){
			this.addToTail();
			y.setScore(y.getScore() + 5) ;
			e.reAppear() ;
			for(Node n=head.next; n!=null; n=n.next){
				if(n.col==e.col && n.row==e.row){
					e.reAppear() ;
				}
			}
		}
		
	}
	
	private Rectangle getRect(){
		return new Rectangle(Yard.BLOCK_SIZE*head.col,Yard.BLOCK_SIZE*head.row,head.w,head.h) ;
	}
	
	public void keyPressed(KeyEvent e) {
		int key = e.getKeyCode();
		switch(key){
		case KeyEvent.VK_LEFT :
			if(head.dir != Dir.R)
			head.dir = Dir.L ;
			break ;
		case KeyEvent.VK_UP :
			if(head.dir != Dir.D)
			head.dir = Dir.U ;
			break ;
		case KeyEvent.VK_RIGHT :
			if(head.dir != Dir.L)
			head.dir = Dir.R ;
			break ;
		case KeyEvent.VK_DOWN :
			if(head.dir != Dir.U)
			head.dir = Dir.D;
			break ;
		}
	}
}

Yard.java(主类)
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;

import javax.swing.JOptionPane;



@SuppressWarnings("serial")
public class Yard extends Frame {
	
	PaintThread paintThread = new PaintThread() ;
	private boolean gameOver = false ;
	
	private Font fontGameOver = new Font("宋体",Font.BOLD,50) ;
	
	public static final int ROWS = 30 ;
	public static final int COLS = 30 ;
	public static final int BLOCK_SIZE = 15 ;
	private static int score = 0 ;
	private static int level ;
	public int getScore() {
		return score;
	}

	@SuppressWarnings("static-access")
	public void setScore(int score) {
		this.score = score;
	}

	Snake s = new Snake(this) ;
	Image offScreenImage = null ;
	Egg e = new Egg() ;
	public static void setLevel(){
		String slevel = JOptionPane.showInputDialog("请输入难度:(1~10),1为最高") ;
		level = Integer.parseInt(slevel) ;
		level *= 20 ;
	}
	@SuppressWarnings("static-access")
	public void launch(){
		this.setLevel() ;
		this.addKeyListener(new KeyMonitor()) ;
		this.setLocation(200,200) ;
		this.setSize(COLS*BLOCK_SIZE,ROWS*BLOCK_SIZE) ;
		this.addWindowListener(new WindowAdapter(){
			@Override
			public void windowClosing(WindowEvent arg0) {
				System.exit(0) ;
			}
		}) ;
		this.setVisible(true) ;
		
		new Thread(paintThread).start();
	}
	
	public void stop(){
		gameOver = true ;
	}
	
	@Override
	public void update(Graphics g) {
		if(offScreenImage == null){
			offScreenImage = this.createImage(COLS*BLOCK_SIZE,ROWS*BLOCK_SIZE) ;
		}
		Graphics gOff = offScreenImage.getGraphics() ;
		print(gOff) ;
		g.drawImage(offScreenImage,0,0,null) ;
	}


	@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) ;
		}
		for(int i=1;i<COLS;i++){
			g.drawLine(BLOCK_SIZE*i, 0, BLOCK_SIZE*i, BLOCK_SIZE*ROWS) ;
		}
		g.setColor(Color.DARK_GRAY) ;
		for(int i=0;i<15;i++){
			g.drawLine(0,BLOCK_SIZE*2-i,COLS*BLOCK_SIZE,BLOCK_SIZE*2-i) ;
			g.drawLine(0,BLOCK_SIZE*(ROWS-1)+i,COLS*BLOCK_SIZE,BLOCK_SIZE*(ROWS-1)+i) ;
			g.drawLine(BLOCK_SIZE-i,0,BLOCK_SIZE-i,ROWS*BLOCK_SIZE) ;
			g.drawLine(BLOCK_SIZE*(COLS-1)+i,0,BLOCK_SIZE*(COLS-1)+i,ROWS*BLOCK_SIZE) ;
		}
		g.setColor(Color.YELLOW) ;
		g.drawString("分数:" + score,10,60) ;
		g.drawString("长度:"+s.getSize(), 10, 43) ;
		
		
		
		
		s.draw(g) ;
		e.draw(g) ;
		s.eat(e) ;
		if(gameOver){
			g.setFont(fontGameOver) ;
			g.drawString("游戏结束", 120,200) ;
			g.drawString("按F2重新开始",70,250) ;
			paintThread.pause() ;
		}
		g.setColor(c) ;
		
	}
	
	private class PaintThread implements Runnable{
		
		private boolean running = true ;
		private boolean pause = false ;
		@Override
		public void run() {
			while(running){
				if(pause) continue ;
				else repaint() ;
				try{
					Thread.sleep(level) ;
				}catch(InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
//		PUBLIC VOID GAMEOVER(){
//			RUNNING = FALSE ;
//		}
		public void reStart(){
			this.pause = false ;
			s = new Snake(Yard.this) ;
			gameOver = false ;
		}
		public void pause(){
			this.pause = true ;
		}
	}

	
	private class KeyMonitor extends KeyAdapter{

		@Override
		public void keyPressed(KeyEvent e) {
			int key = e.getKeyCode();
			if(key == KeyEvent.VK_F2){
				Yard.setLevel() ;
				paintThread.reStart() ;
				Yard.score = 0 ;
			}
			s.keyPressed(e) ;
		}
		
	}
	
	public static void main(String[] args) {
		new Yard().launch() ;
	}

}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值