贪吃蛇游戏(java)

来源:互联网 发布:智能健康数据分析图 编辑:程序博客网 时间:2024/05/16 08:03

1、采用MVC(model、view、control)框架模式




 3、包和类的关系树形图为:




 4、源码:

 

 package com.huai;

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 com.huai.listener.SnakeListener;import com.huai.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{

  @Override  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; }}

package com.huai;

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

import com.huai.util.Constant;

public class Food { private int x = 0; private int y = 0; //设置食物的默认颜色为红色 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); }}

package com.huai;

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

import com.huai.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("snack 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; }  }

package com.huai;

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

import com.huai.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;  }     }



package com.huai.listener;

import com.huai.Snake;

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

package com.huai.util;

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

package com.huai.view;

import java.awt.Color;import java.awt.Graphics;

import javax.swing.JPanel;

import com.huai.Food;import com.huai.Ground;import com.huai.Snake;import com.huai.Thorn;import com.huai.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");  } }}

package com.huai.controller;

import java.awt.event.KeyAdapter;import java.awt.event.KeyEvent;

import com.huai.Food;import com.huai.Ground;import com.huai.Snake;import com.huai.Thorn;import com.huai.listener.SnakeListener;import com.huai.view.GamePanel;

public class Controller extends KeyAdapter implements SnakeListener{/** * 整个游戏的控制类,属于MVC设计框架中的Controller * 其中包括控制游戏的监听事件和游戏逻辑 */ Snake snake; Food food; Ground ground; GamePanel gamePanel; Thorn thorn;  public Controller(){}  //利用构造方法初始化对象 public Controller(Snake snake, Food food, Ground ground, GamePanel gamePanel, Thorn thorn) {  super();  this.snake = snake;  this.food = food;  this.ground = ground;  this.gamePanel = gamePanel;  this.thorn = thorn; }

 @Override public void keyPressed(KeyEvent e) {    switch(e.getKeyCode()){  case KeyEvent.VK_UP:   snake.changeDirection(Snake.UP);   snake.setSpeed(150);   break;  case KeyEvent.VK_DOWN:   snake.changeDirection(Snake.DOWN);   snake.setSpeed(150);   break;  case KeyEvent.VK_LEFT:   snake.changeDirection(Snake.LEFT);   snake.setSpeed(150);   break;  case KeyEvent.VK_RIGHT:   snake.changeDirection(Snake.RIGHT);   snake.setSpeed(150);   break;  case KeyEvent.VK_ENTER:   if(!snake.getPause() && snake.getLife()){    //暂停游戏    snake.setPause(true);;   }else if(!snake.getLife()){    //重新开始游戏    snake.setLife(true);    snake.initial();    snake.changeDirection(Snake.UP);    thorn.getThorns().removeAll(thorn.getThorns());    this.startGame();   }else{    snake.setPause(false);   }   break;  case KeyEvent.VK_L:   //当按下L按钮时,是否显示游戏网格   if(ground.isDrawLine()){    ground.setDrawLine(false);   }else{    ground.setDrawLine(true);   }   break;  } }   @Override public void keyReleased(KeyEvent e) {  switch(e.getKeyCode()){  case KeyEvent.VK_UP:   snake.setSpeed(400);   break;  case KeyEvent.VK_DOWN:   snake.setSpeed(400);   break;  case KeyEvent.VK_LEFT:   snake.setSpeed(400);   break;  case KeyEvent.VK_RIGHT:   snake.setSpeed(400);   break;  } }  //这是实现SnakeListener监听器所Override的方法  @Override public void snakeMove(Snake snake) {  //显示snake ,food,ground,和thorn  gamePanel.display(snake, food, ground, thorn);  if(ground.isSnakeHitRock(snake)){   snake.died();  }  if(snake.isEatItself()){   snake.died();  }  if(food.isAte(snake)){   snake.eatFood();   food.newFood(ground.getRandomPoint(snake, thorn));   thorn.newThorn(ground.getRandomPoint(snake, thorn));  }  if(thorn.isSnakeHitThorn(snake)){   snake.died();  } }  public void startGame(){  snake.startMove();//这个将会启动一个新的线程  food.newFood(ground.getRandomPoint(snake, thorn));  thorn.newThorn(ground.getRandomPoint(snake, thorn)); } }

package com.huai.game;

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

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

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

public class Game { public static void main(String args[]){    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.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  frame.setVisible(true);    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(); }}

1 0
原创粉丝点击