一、包和类关系:
二、源码
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