java贪吃蛇游戏编写代码

本文实例为大家分享了java贪吃蛇游戏展示的具体代码,供大家参考,具体内容如下

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

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

3、源码:

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();
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Java编写迷宫小游戏

    缘起: 去年(大三上学期)比较喜欢写小游戏,于是想试着写个迷宫试一下. 程序效果: 按下空格显示路径: 思考过程: 迷宫由一个一个格子组成,要求从入口到出口只有一条路径. 想了一下各种数据结构,似乎树是比较合适的,从根节点到每一个子节点都只有一条路径.假设入口是根节点,出口是树中某个子节点,那么,从根节点到该子节点的路径肯定是唯一的. 所以如果能构造一棵树把所有的格子都覆盖到,也就能够做出一个迷宫了. 另外还要求树的父节点和子节点必须是界面上相邻的格子. 在界面显示时,父节点和子节点之间共用的边

  • Java版坦克大战游戏源码示例

    整理文档,搜刮出一个Java版坦克大战游戏的代码,稍微整理精简一下做下分享. package tankwar; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.io.File; import java.io.FileInputStream; imp

  • 用Java实现小球碰壁反弹的简单实例(算法十分简单)

    核心代码如下: if(addX){ x+=3; }else{ x-=3; } if(addY){ y+=6; }else{ y-=6; } if(x<=0||x>=(width-50)){ addX=!addX; } if(y<=0||y>=(height-50)){ addY=!addY; } 根据x和y递增的值,来决定角度. 以上这篇用Java实现小球碰壁反弹的简单实例(算法十分简单)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

  • java中的数学计算函数的总结

    java中的数学计算函数 Math类: java.lang.Math类中包含基本的数字操作,如指数.对数.平方根和三角函数. java.math是一个包,提供用于执行任意精度整数(BigInteger)算法和任意精度小数(BigDecimal)算法的类. java.lang.Math类中包含E和PI两个静态常量,以及进行科学计算的类(static)方法,可以直接通过类名调用. public static final Double E = 2.7182818284590452354 public

  • Java编程实现游戏中的简单碰撞检测功能示例

    本文实例讲述了Java编程中的简单碰撞检测功能.分享给大家供大家参考,具体如下: 今天在家正在写一个坦克大战的小游戏来玩,遇到了一个简单的圆和圆的碰撞检测的小问题, 碰撞检测的过程处理主要有以下三步: 1.碰撞检测(Collision Detection):返回两个或多个物体是否发生碰撞的布尔判断. 2.碰撞确定(Collision Determination):找到物体之间实际相交位置. 3.碰撞响应(Collision Response):针对两个物体之间的碰撞决定采取何种操作. 下面是关于

  • Java计算一个数加上100是完全平方数,加上168还是完全平方数

    题目:一个整数,它加上100后是一个完全平方数,加上168又是一个完全平方数,请问该数是多少? 程序分析:在10万以内判断,先将该数加上100后再开方,再将该数加上268后再开方,如果开方后的结果满足如下条件,即是结果.请看具体分析: 程序设计: public class test { public static void main (String[]args){ long k=0; for(k=1;k<=100000l;k++) if(Math.floor(Math.sqrt(k+100))=

  • Java使用Math.random()结合蒙特卡洛方法计算pi值示例

    本文实例讲述了Java使用Math.random()结合蒙特卡洛方法计算pi值.分享给大家供大家参考,具体如下: 一.概述 蒙特·卡罗方法(Monte Carlo method),也称统计模拟方法,是二十世纪四十年代中期由于科学技术的发展和电子计算机的发明,而被提出的一种以概率统计理论为指导的一类非常重要的数值计算方法.是指使用随机数(或更常见的伪随机数)来解决很多计算问题的方法.与它对应的是确定性算法. 详细可参考百度百科:https://baike.baidu.com/item/%E8%92

  • 利用java、js或mysql计算高德地图中两坐标之间的距离

    前言 因为工作的原因,最近在做与地图相关的应用,使用了高德地图,研究了下高德地图计算两坐标距离的方法,官网上提供的开发包中有相关的方法,但是我的产品中比较特殊,无法直接使用提供的方法,所以就自己封装了相关计算方法,供大家参考,下面话不多说了,来一起看看详细的介绍吧. Java实现 首先定义一个用于存储经纬度的类,这里起个名字叫:LngLat package amap; import java.text.DecimalFormat; import java.text.DecimalFormatSy

  • java 简单的计算器程序实例代码

    java 简单的计算器程序 实现实例: import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Calculator { public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { CalculatorFrame frame = new Calculato

  • java计算两个日期之前的天数实例(排除节假日和周末)

    如题所说,计算两个日期之前的天数,排除节假日和周末.这里天数的类型为double,因为该功能实现的是请假天数的计算,有请一上午假的为0.5天. 不够很坑的是每个日期都要查询数据库,感觉很浪费时间. 原则: 1.节假日存放在数据库中 实现步骤: 1.循环每个日期 2.判断每个日期是否为节假日或者为周末 3.若不是节假日和周末,天数+1 代码: public double calLeaveDays(Date startTime,Date endTime){ double leaveDays = 0;

随机推荐