贪吃蛇系列二

一、包和类关系:

二、源码

Game.class

import java.awt.BorderLayout;
import java.awt.Color;

import controller.Controller;
import snake.Food;
import snake.Ground;
import snake.Snake;
import snake.Thorn;
import util.Constant;
import view.GamePanel;

import javax.swing.JFrame;
import javax.swing.JLabel;

public class Game {
	public static void main(String[] args) {
			// TODO Auto-generated method stub
			 Snake snake = new Snake();
			 Food food = new Food();
			 GamePanel gamePanel = new GamePanel();
			 Ground ground = new Ground();
			 Thorn thorn = new Thorn();
			 Controller controller = new Controller(snake, food, ground, gamePanel, thorn);
			 
			 //创建一个新窗口
			 JFrame frame = new JFrame("贪吃蛇游戏");
			 //将画板嵌入窗口中
			 frame.add(gamePanel);
			 //设置窗口背景色
			 frame.setBackground(Color.magenta);
			 //设置窗口大小
			 frame.setSize(Constant.WIDTH*Constant.CELL_SIZE+6, 
			 Constant.HEIGHT*Constant.CELL_SIZE+40);
			 //设置画板大小
			 gamePanel.setSize(Constant.WIDTH*Constant.CELL_SIZE, 
			 Constant.HEIGHT*Constant.CELL_SIZE);
			 frame.add(gamePanel);
			 //不可改变窗口大小
			 frame.setResizable(false);
			 //设置窗口可见
			 frame.setVisible(true);
			 //关闭窗口
			 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			  
			 gamePanel.addKeyListener(controller);
			 snake.addSnakeListener(controller);
			 frame.addKeyListener(controller);
			  
			 JLabel label1 = new JLabel();
			 label1.setBounds(0, 400, 400, 100);
			 label1.setText("     ENTER=>>PAUSE or AGAIN;   "
			 + " L=>DRAWGRID");
			 label1.setForeground(Color.BLACK);
			 frame.add(label1, BorderLayout.SOUTH);
			  
			 controller.startGame();
		 }
	}

SnakeListener.class

import snake.Snake;

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

}
Constant.class
public class Constant {
	public static int CELL_SIZE = 20;
	public static int WIDTH = 20;
	public static int HEIGHT = 20;
}

GamePanel.class

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
import snake.Food;
import snake.Ground;
import snake.Snake;
import snake.Thorn;
import util.Constant;

public class GamePanel extends JPanel{
	 private static final long serialVersionUID = 1L;
	  
	 Snake snake;
	 Food food;
	 Ground ground;
	 Thorn thorn;
	  
	 public void display(Snake snake, Food food, Ground ground, Thorn thorn){
		 this.snake = snake;
		 this.food = food;
		 this.ground = ground;
		 this.thorn = thorn;
		  
		 System.out.println("display gamePanel");
		 this.repaint();
	 }
	  
	 @Override
	 protected void paintComponent(Graphics g) {
		 if(snake != null && food != null && ground != null){
			 g.setColor(Color.lightGray);
			 g.fillRect(0, 0, Constant.WIDTH*Constant.CELL_SIZE, Constant.HEIGHT*Constant.CELL_SIZE);
			 snake.drawMe(g);
			 food.drawMe(g);
			 ground.drawMe(g);
			 thorn.drawMe(g);
		 }else{
			 System.out.println("snake = null || food = null || ground = null");
		 }
	 }
}

Food.class

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import util.Constant;

public class Food {
	private int x = 0;
	private int y = 0;
	
	//food is red
	private Color color = Color.red;
	
	public void newFood(Point point){
		x = point.x;
		y = point.y;
	}
	
	public boolean isAte(Snake snake){
		if(snake.getHead().equals(new Point(x, y))){
			System.out.println("food isAte");
			return true;
		}
		return false;
	}
	
	public void setFoodColor(Color color){
		this.color = color;
	}
	
	public Color getFoodColor(){
		return this.color;
	}
	
	public void drawMe(Graphics g){
		System.out.println("draw food");
		g.setColor(this.getFoodColor());
		g.fill3DRect(x * Constant.CELL_SIZE, y * Constant.CELL_SIZE, Constant.CELL_SIZE, Constant.CELL_SIZE, true);
	}
}

Ground.class

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.LinkedList;
import java.util.Random;
import util.Constant;

public class Ground {
	//在二维数组中,当为1,表示是砖块
	 private int[][] rock = new int[Constant.WIDTH][Constant.HEIGHT];
	  
	 private boolean drawLine = true;
	  
	 public boolean isDrawLine() {
		 return drawLine;
	 }
	 
	 public void setDrawLine(boolean drawLine) {
		 this.drawLine = drawLine;
	 } 
	 public Ground(){
		 for(int x = 0; x < Constant.WIDTH; x++){
			 for(int y = 0; y < Constant.HEIGHT; y++){
				 rock[0][y] = 1;
				 rock[x][0] = 1;
				 rock[Constant.WIDTH-1][y] = 1;
				 rock[y][Constant.HEIGHT-1] = 1;
			 }
		 }
	 }
	  
	 //打印游戏的网格
	 public void drawGrid(Graphics g){
		 for(int x = 2; x < Constant.WIDTH; x++){
			 g.drawLine(x * Constant.CELL_SIZE, 0, x*Constant.CELL_SIZE,
			 Constant.CELL_SIZE * Constant.HEIGHT);
		 }
		 for(int y = 2; y < Constant.HEIGHT; y++){
			 g.drawLine(0, y * Constant.CELL_SIZE, 
			 Constant.WIDTH*Constant.CELL_SIZE, y*Constant.CELL_SIZE);
		 }
	 }
	 public void drawMe(Graphics g){
		 System.out.println("draw ground");
		  
		 //打印围墙
		 g.setColor(Color.pink);
		 for(int x = 0; x < Constant.WIDTH; x++){
			 for(int y = 0; y < Constant.HEIGHT; y++){
				 if(rock[x][y] == 1){
				  g.fill3DRect(x * Constant.WIDTH, y * Constant.HEIGHT,
				  Constant.CELL_SIZE, Constant.CELL_SIZE, true);
				 }
			 }
		 }
		 if(isDrawLine()){
			 g.setColor(Color.yellow);
			 this.drawGrid(g);
		 }
	 }
	  
	 //得到一个随机点
	 public Point getRandomPoint(Snake snake, Thorn thorn){
		 Random random = new Random();
		 boolean isUnderSnakebody = false;
		 boolean isUnderThorn = false;
		 int x,y = 0;
		 LinkedList<Point> snakeBody = snake.getSnakeBody();
		 LinkedList<Point> thorns = thorn.getThorns();
		 do{
			 x = random.nextInt(Constant.WIDTH);
			 y = random.nextInt(Constant.HEIGHT);
			 for(Point p:snakeBody){
				 if(x == p.x && y == p.y){
					 isUnderSnakebody = true;
				 }
			 }
			 for(Point point : thorns){
				 if(x == point.x && y == point.y){
					 isUnderThorn = true;
				 }
			 }
		 }while(rock[x][y] == 1 && !isUnderSnakebody && !isUnderThorn);
		 
		 return new Point(x, y);
	 }
	  
	 public boolean isSnakeHitRock(Snake snake){
		 System.out.println("snake hit rock");
		  
		 for(int i = 0; i < Constant.WIDTH; i++){
			 for(int j = 0; j < Constant.HEIGHT; j++){
				 if(snake.getHead().x == i && snake.getHead().y == j && rock[i][j] == 1){
					 return true;
				 }
			 }
		 }
		 return false;
	 }
	  
}

Snake.class

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;

import listener.SnakeListener;
import util.Constant;

public class Snake {
	// 和蛇的监听器有关
	Set<SnakeListener> snakeListener = new HashSet<SnakeListener>();

	// 用链表保存蛇的身体节点
	LinkedList<Point> body = new LinkedList<Point>();

	private boolean life = true;

	// 默认速度为400ms
	private int speed = 400;
	private Point lastTail = null;
	private boolean pause = false;

	// 定义各个方向
	public static final int UP = 1;
	public static final int DOWN = -1;
	public static final int LEFT = 2;
	public static final int RIGHT = -2;
	int newDirection = RIGHT;
	int oldDirection = newDirection;

	public Snake() {
		initial();
	}

	public void initial() {
		// 先清空所有的节点
		body.removeAll(body);

		int x = Constant.WIDTH / 2;
		int y = Constant.HEIGHT / 2;

		// 蛇的默认长度为7
		for (int i = 0; i < 7; i++) {
			body.add(new Point(x--, y));
		}
	}

	public void setSpeed(int speed) {
		this.speed = speed;
	}

	public void setLife(boolean life) {
		this.life = life;
	}

	public boolean getLife() {
		return this.life;
	}

	public boolean getPause() {
		return this.pause;
	}

	public void setPause(boolean pause) {
		this.pause = pause;
	}

	public void move() {
		// 蛇移动的实现所采用的数据结构为:蛇尾删除一个节点,蛇头增加一个节点。

		System.out.println("snake move");

		if (!(oldDirection + newDirection == 0)) {
			oldDirection = newDirection;
		}
		lastTail = body.removeLast();

		int x = body.getFirst().x;
		int y = body.getFirst().y;

		switch (oldDirection) {
		case UP:
			y--;
			break;
		case DOWN:
			y++;
			break;
		case LEFT:
			x--;
			break;
		case RIGHT:
			x++;
			break;
		}
		Point point = new Point(x, y);
		body.addFirst(point);
	}

	// 当吃到一个食物的时候,把删掉的蛇尾节点增加回来
	public void eatFood() {
		System.out.println("snake eat food");

		body.addLast(lastTail);
	}

	public boolean isEatItself() {
		for (int i = 2; i < body.size(); i++) {
			if (body.getFirst().equals(body.get(i))) {
				return true;
			}
		}
		return false;
	}

	public void drawMe(Graphics g) {
		System.out.println("draw snake");

		// 循环打印蛇的各个身体节点
		for (Point p : body) {
			if (p.equals(body.getFirst())) {
				// 当是蛇头的时候,就设置颜色为橘色
				g.setColor(Color.orange);
			} else {
				g.setColor(Color.pink);
			}
			g.fill3DRect(p.x * Constant.CELL_SIZE, p.y * Constant.CELL_SIZE,
					Constant.CELL_SIZE, Constant.CELL_SIZE, true);
		}
	}

	public void changeDirection(int direction) {
		System.out.println("snake changeDirection");
		this.newDirection = direction;
	}

	// 内部类,新增一个游戏线程
	public class DriveSnake implements Runnable {
		public void run() {
			while (life) {
				if (!pause) {
					// 只要让蛇不动就可以暂停游戏
					move();
				}
				// 监听蛇每次移动的情况
				for (SnakeListener listener : snakeListener) {
					listener.snakeMove(Snake.this);
				}
				try {
					Thread.sleep(speed);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public void startMove() {
		new Thread(new DriveSnake()).start();
	}

	// 增加监听器的方法
	public void addSnakeListener(SnakeListener listener) {
		if (listener != null) {
			snakeListener.add(listener);
		}
	}

	// 返回蛇的第一个身体节点
	public Point getHead() {
		return body.getFirst();
	}

	// 返回蛇的所有身体节点
	public LinkedList<Point> getSnakeBody() {
		return this.body;
	}

	public boolean died() {
		this.life = false;
		return true;
	}
}

Thorn.class

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.LinkedList;

import util.Constant;

public class Thorn {
	 int x, y;
	 private LinkedList<Point> thorns = new LinkedList<Point>();
	  
	  
	 //返回所有荆棘的链表
	 public LinkedList<Point> getThorns(){
		 return this.thorns;
	 }
	  
	 public void newThorn(Point point){
		 x = point.x;
		 y = point.y;
		  
		 thorns.add(new Point(x, y));
	 }
	  
	 public void drawMe(Graphics g){
		 System.out.println("draw thorns");
		  
		  
		 for(Point p: thorns){
			 int[] xb = {p.x*Constant.CELL_SIZE, 
				  (p.x*Constant.CELL_SIZE +Constant.CELL_SIZE/2),
				  (p.x*Constant.CELL_SIZE+Constant.CELL_SIZE),
				  (p.x*Constant.CELL_SIZE+Constant.CELL_SIZE/4*3), 
				  (p.x*Constant.CELL_SIZE+Constant.CELL_SIZE),
				  (p.x*Constant.CELL_SIZE+Constant.CELL_SIZE/2), 
				  p.x*Constant.CELL_SIZE,
				  (p.x*Constant.CELL_SIZE+Constant.CELL_SIZE/4), 
				  p.x*Constant.CELL_SIZE};
			 int [] yb = {p.y*Constant.CELL_SIZE, 
				  (p.y*Constant.CELL_SIZE+Constant.CELL_SIZE/4),
				  p.y*Constant.CELL_SIZE,
				  (p.y*Constant.CELL_SIZE+Constant.CELL_SIZE/2),
				  (p.y*Constant.CELL_SIZE+Constant.CELL_SIZE),
				  (int)(p.y*Constant.CELL_SIZE+Constant.CELL_SIZE*0.75),
				  (p.y*Constant.CELL_SIZE+Constant.CELL_SIZE),
				  (p.y*Constant.CELL_SIZE+Constant.CELL_SIZE/2),
				  p.y*Constant.CELL_SIZE};
			  
			 g.setColor(Color.darkGray);
			 g.fillPolygon(xb, yb, 8);
		 }
	  
	 }
	  
	  
	 public boolean isSnakeHitThorn(Snake snake){	  
		 for(Point points : thorns){
			 if(snake.getHead().equals(points)){
				  System.out.println("hit thorn");
				  return true;
			 }
		 }
		 return false;
	 }
}




扫描二维码关注公众号,回复: 2252317 查看本文章



转自:https://www.jb51.net/article/115616.htm

猜你喜欢

转载自blog.csdn.net/isringring/article/details/81011850