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;//默认速度为400msprivate 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;//蛇的默认长度为7for(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{  @Overridepublic 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();}@Overrideprotected 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;}@Overridepublic 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;}}@Overridepublic 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的方法@Overridepublic void snakeMove(Snake snake) {//显示snake ,food,ground,和thorngamePanel.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();}
}

贪吃蛇游戏(java)相关推荐

  1. 贪吃蛇游戏(java)(全注释)

    没想到发的第一篇关于java的博客会是这个,写作业用来练手,顺道就搬上来了. 代码肯定不最优的,欢迎大家一起来探讨~ 先搬个效果图~ 然后结构~ 一共分成4个部分,Define包下有蛇,食物和成绩数据 ...

  2. Java项目:贪吃蛇游戏(java+swing)

    源码获取:博客首页 "资源" 里下载! 功能简介: 贪吃蛇游戏 大嘴鱼洁面类.完成大嘴鱼的界面的绘制: /*** 大嘴鱼洁面类.完成大嘴鱼的界面的绘制.*/ public clas ...

  3. 贪吃蛇游戏java代码_Java实现贪吃蛇游戏

    最近JAVA和JSwing上手练习了一下贪吃蛇,供大家参考,具体内容如下 欢迎交流和加入新的内容 用到了JSwing,下面是一些具体的思路 实现 * 蛇: 采用单链表记录首尾,整个蛇被分为lattic ...

  4. java贪吃蛇不能回头,儿时回忆!泪流满面,Java 实现贪吃蛇游戏的示例(附代码)...

    image.png image.png java实现贪吃蛇游戏需要创建一个桌面窗口出来,此时就需要使用java中的swing控件 创建一个新窗口 JFrame frame = new JFrame(& ...

  5. java超级简单贪吃蛇_java实现简易贪吃蛇游戏

    本文实例为大家分享了java实现贪吃蛇游戏的具体代码,供大家参考,具体内容如下 1.封装贪吃蛇身体,抽象出贪吃蛇结点类Node,结点用ArrayList存储 import java.awt.*; pu ...

  6. 手机java做贪吃蛇_如何用Java写一个贪吃蛇游戏

    这是一位拓胜学员用Java写贪吃蛇游戏的心得:今天课程设计终于结束了自己学java没以前学C+那么用功了觉得我学习在哪里都是个开口向上的抛物线,现在应该在右半边吧,好了进入正题. 写java贪吃蛇也是 ...

  7. Java学习(8):贪吃蛇游戏

    根据视频编写的贪吃蛇游戏 主方法 public class Start {public static void main(String[] args) {new Yard().launch();} } ...

  8. 【使用java swing制作简易贪吃蛇游戏】软件实习项目二

    一.项目准备 需求分析: 实现贪吃蛇游戏基本功能,屏幕上随机出现一个"食物",称为豆子,上下左右控制"蛇"的移动,吃到"豆子"以后" ...

  9. JAVA简易贪吃蛇游戏实现

    JAVA简易贪吃蛇游戏实现 自学java不久,最近看了些GUI编程,就拿贪吃蛇练个手,很基础 刚学的 也是最简易的版本.纯粹就想通过博客记录来巩固自己的学习效果. 游戏介绍 玩家通过按键控制蛇身的移动 ...

  10. Java 贪吃蛇游戏引言

    欢迎关注公众号: 贪吃蛇小游戏是一款十分经典的小游戏,适合用于新手的练习,花了近两个月的时间,终于可以运行出比较完善的贪吃蛇了,相比于CSDN中的大神,花个几天的时间就可以做出Java版本的贪吃蛇小游 ...

最新文章

  1. solr 实现对经纬度的查询
  2. 系统间数据交互注意项
  3. heic怎么查看,如何打开heic
  4. 源码详解Java的反射机制
  5. pythonreplace回调函数,python回调函数返回非
  6. matlab可以连接阻抗分析仪么,MFIA 5MHz阻抗分析仪
  7. 网络启动安装linux客户机nfs设置,NFS服务端和客户端安装配置
  8. C++ 面向对象与面向过程的区别与联系
  9. 剑指offer——面试题28:字符串的排列
  10. Java jar 包免费下载(全)
  11. 东南部海域有7、8级大风 华北平原大气扩散条件转差
  12. SuperMap iDesktop常见问题解答集锦 (二)
  13. CSDN,hen hao,hen qiang da
  14. 2012湘潭ICPC邀请赛感悟
  15. ubuntu 14.04全攻略
  16. 不是买一台电脑就能敲代码!学习java必须了解的计算机知识以及准备工作
  17. FreeBSD开发手册(一)
  18. python 游戏按键精灵 PyDirectInput介绍
  19. 最近火爆的chatgpt,程序员如何使用其进行代码开发
  20. 摸索一下午,终于解决Tomcat9中文乱码问题!!

热门文章

  1. 7-27 冒泡法排序 (C语言)
  2. 【c语言】蓝桥杯算法提高 3-2求存款
  3. java 类的合成_Java设计模式-合成模式
  4. python读取字符串的list dict_转:Python 列表(list)、字典(dict)、字符串(string)常用基本操作小结...
  5. 深度优先(DFS)和广度优先(BFS)
  6. 乐观锁 -业务判断 解决高并发问题
  7. vim插件的安装方式 -- vim注释插件和doxygen函数注释生成插件-ctrlp插件-tabular等号对齐 插件...
  8. Java测试工具使用(1)--Junit
  9. Android入门:Activity四种启动模式
  10. 项目进度管理和项目成本管理作业