java贪吃蛇游戏

时间:2024.3.31

《Java程序设计》期末考查

—课程设计报告

题目   贪吃蛇游戏   

专    业信息管理与信息系统

班    级    信息管理班   

学    号  200981020136   

姓    名     周南       

成    绩                  

完成时间   20##12   


目  录

第一章.需求分析

1:研究背景

2:研究方案

第二章.系统设计

1 : 编写贪吃蛇游戏中的各个类的主体框架性代码

2 : 编写Controler类与实现蛇移动的事件监听

3 : 蛇的数据结构设计与移动显示

4: 编写与测试表示食物的类并实现吃食物

总结

参考文献

贪吃蛇游戏

第一章.  需求分析

1研究背景

大概在文艺复兴的时候就有人发明的一种游戏,是现在贪吃蛇的前身。后来慢慢的发展就变成了今天的贪吃蛇了、现在贪吃蛇主要应用于手机游戏。

本文运用软件工程思想、JAVA面向对象编程、类的封装、抽象类的使用(接口),游戏编码规范遵循MVC模式,循序渐进实现贪吃蛇的相关功能。

2,研究方案

  ㈠  ●涉及到几个对象(类)

  ㈡  ●每个类有什么方法

1 . 首先得有个游戏显示面板(GamePanel)类

该类有一个方法void display(); //用来显示游戏面板

2 . 一个蛇(Snake)类

该类有以下几个方法:

void move();  //移动(走一步)

void changeDirection(); //改变方向

void eatFood(); //吃食物(身体变长)

voolean is EatBody();//蛇是否吃到了自己的身体

void drawMe();//显示

3 . 一个食物类(Food)类

该类有以下方法:

boolean is SnakeEatFood(Snake); //判断蛇是否吃到了食物

void drawMe();//显示

此时类之间的关系如下图所示:

图1  各个类之间的关系

第二章.系统设计

一 : 编写贪吃蛇游戏中的各个类的主体框架性代码

public class Food {

      public boolean isSnakeEatFood(Snake snake)

       {

         System.out.println("Snake's eat food");

        return false;

      }

       public void drawme()

       {

         System.out.println("Food's drawme");

       }

}

package liang.snake.entities;

public class Ground {

   public boolean isSnakeEatRock()

    {

      return false;

    }

      public void drawme()

       {

         System.out.println("Ground's drawme");

       }

}

package liang.snake.entities;

public class Snake {

  

    public void move()

     {

       System.out.println("Snake's move");

     }

     public void changeDirection(int direction)

     {

       System.out.println("Snake's changeDirection");

     }

     public void eatFood()

     {

       System.out.println("Snake's eat food");

     }

     public boolean isEatBody()

     {

       System.out.println("Snake's eat body");

          return false;

     }

     public void drawMe(){

       System.out.println("Snake's drawMe");

}

package liang.snake.view;

import java.awt.Graphics;

import javax.swing.JPanel;

import liang.snake.entities.Food;

import liang.snake.entities.Ground;

import liang.snake.entities.Snake;

public class GamePanel extends JPanel{

   private Snake snake;

   private Ground ground;

   private Food food;

   public void paintComponent(Graphics g) {

   snake.drawMe();

   ground.drawme();

   food.drawme();

   }

   public void display(Snake snake,Ground ground,Food food)

    {

      this.snake=snake;

      this.ground=ground;

      this.food=food;

    System.out.println("GamePanel's display");

    this.repaint();

    }

二 : 编写Controler类与实现蛇移动的事件监听

由于蛇不能直接操作显示面板(GamePanel)所以这里定义一个监听器SnakeListener:里面定义一个方法:

void snakeMove(Snake); 每当蛇移动一步就触发监听器,调用snakeMoved()由Controller去实现监听器的接口,然后由控制器去触发显示面板的事件源,让显示面板完成相应操作。

逻辑图如下:

图2 事件监听建立联系

在Snake 中增加蛇的方向常量:

    public static final int UP=1;

    public static final int DOWN=-1;

    public static final int LEFT=2;

    public static final int RIGHT=-2;

并添加一个接口:

package liang.snake.Listener;

import liang.snake.entities.Snake;

   public interface SnakeListener {

      public void SnakeMove(Snake snake);

   }

Controler 实现SnakeListener接口并处理案件消息:代码如下:

package liang.snake.Controller;

import java.awt.event.KeyAdapter;

import java.awt.event.KeyEvent;

import liang.snake.Listener.SnakeListener;

import liang.snake.entities.Food;

import liang.snake.entities.Ground;

import liang.snake.entities.Snake;

import liang.snake.view.GamePanel;

public class Controller extends KeyAdapter implements SnakeListener{

   Snake snake=new Snake();

   Ground ground=new Ground();

    Food food=new Food();

    GamePanel gamepanel=new GamePanel();

    public Controller(Snake snake, Ground ground, Food food, GamePanel gamepanel) {

      this.snake = snake;

      this.ground = ground;

      this.food = food;

      this.gamepanel = gamepanel;

   }

public void keyReleased(KeyEvent e) {

      switch(e.getKeyCode())

      {

      case KeyEvent.VK_UP :

        snake.changeDirection(Snake.UP);

        break;

      case KeyEvent.VK_DOWN :

        snake.changeDirection(Snake.DOWN);

        break;

      case KeyEvent.VK_LEFT :

        snake.changeDirection(Snake.LEFT);

        break;

      case KeyEvent.VK_RIGHT :

        snake.changeDirection(Snake.RIGHT);

        break;

      }

   }

public void newgame()

{

   snake.start();

}

   public void SnakeMove(Snake snake) {

       gamepanel.display(snake,ground,food); 

   }

}

开发到此时,Snake中应该增加监听器,并另启动一个线程来不断调用蛇的move();在Snake中提供一个启动线程的方法,在Snake中增加如下代码:

private Set<SnakeListener> listener=new

HashSet<SnakeListener>();

 public void addSnakeListener(SnakeListener l)

     {

       if(l!=null)

          this.listener.add(l);

     }

}

public void start()

     {

       new Thread(new SnakeDriver()).run();

     }

并在Run方法中增加  

        for(SnakeListener l: listener)

        {

           l.SnakeMove(Snake.this);       }

        try

        {

           Thread.sleep(1000);

        }

        catch (InterruptedException e)

        {

           e.printStackTrace();

        }

三 : 蛇的数据结构设计与移动显示

分析:

要区分蛇头和蛇尾巴,这就要求这个数据结构是有序的,

还要经常访问第一个和最后一个节点,所以LinkedList最合适,因为它有getFirst(),getLast()方法和removeLast()方法

蛇下一步移动到哪是由方向控制的,前面已经定义过,蛇透坐标如下图:

图3 蛇头方向计算新蛇头坐标

在Snake的 move()中增加

body.removeLast();

       int x=body.getFirst().x;

       int y=body.getFirst().y;

       switch(direction)

       {

       case UP:

           y--;

          break;

       case DOWN:

          y++;

          break;

       case LEFT:

          x--;

          break;

       case RIGHT:

          x++;

          break;

       }

       Point newhead=new Point(x,y);

       //加头

       body.addFirst(newhead);

并定义 private int direction;

为了能更方便的维护游戏,这里定义Global类来定义常量如下:

package liang.snake.Global;

public class Global {

   public static final int CELL_SIZE=20;

   public static  int HIGHT=30;

   public static  int WIDTH=30;

}

并修改游戏中窗口大小为:

jf.setSize(Global.CELL_SIZE*Global.WIDTH,Global.CELL_SIZE*Global.HIGHT);

再加上如下代码,对蛇初始化:

public Snake()

      {

        init();

      }

      public void init()

      {

        int x=Global.WIDTH/2;

        int y=Global.HIGHT/2;

        int nodenum=3;

        for(int i=0;i<nodenum;i++)

        {

           body.addFirst(new Point(x++,y));

        } 

        this.direction=RIGHT;

      }

在蛇的drawMe(Graphics g)中些上如下让蛇显示的代码:

这里的画图采用填充3D矩形来实现:

    for(Point p:body)

       {

          g.fill3DRect(p.x*Global.CELL_SIZE, p.y*Global.CELL_SIZE, Global.CELL_SIZE, Global.CELL_SIZE, true);

     }

画图的规则如下图:

图4 计算格子坐标和像素坐标

此时运行Game类就可以看到蛇显示在面板中了,如图:

图5 显示面板显示的蛇

但是蛇越走越长,是因为没有擦除以前的图像,在GamePanel的paintComponent(Graphics g)中添加如下代码:

g.setColor(new Color(0xcfcfcf));

      g.fill3DRect(0, 0,Global.CELL_SIZE*Global.WIDTH , Global.CELL_SIZE*Global.HIGHT, true);

此时蛇就可以正常移动了如图:

图6 移动中的蛇

通过按键改变移动方向,此时的蛇身体节点显示为白色,我们再在蛇的绘制方法中位器指定颜色:代码如下:

图7 指定颜色后的蛇

四: 编写与测试表示食物的类并实现吃食物

首先在Snake类中添加  public Point getHead()

     {

      return body.getFirst();

     }

用来获取头结点,然后再Food类中写上如下代码:

package liang.snake.entities;

import java.awt.Color;

import java.awt.Graphics;

import java.awt.Point;

import liang.snake.Global.Global;

public class Food extends Point{

   public void newfood(Point p)

   {

       this.setLocation(p);

   }

   public boolean isSnakeEatFood(Snake snake)

    {

      System.out.println("Snake's eat food");

      return this.equals(snake.getHead());

   }

    public void drawme(Graphics g)

    {

      System.out.println("Food's drawme");

      g.fill3DRect(this.x*Global.CELL_SIZE,this.y*Global.CELL_SIZE, Global.CELL_SIZE, Global.CELL_SIZE, true);

    }

}

此时就可以画出食物并判断蛇是否吃到了食物,接下来就可以在Controller中处理吃食物的代码,吃了食物我们只要把先前移动去除的尾巴再给加上就实现了蛇吃食物身体变长的效果了,如下:

定义Point oldTail;

在蛇move()中保存去除的尾巴:oldTail= body.removeLast();

在Controller中的SnakeMove(Snake snake)中添加

if(food.isSnakeEatFood(snake))

       {

         snake.eatFood();

         food.newfood(ground.getPoint());

       }

结论

贪吃蛇虽然是一个小游戏,但是它也是我们最常见的游戏之一,大到电脑电视,小到手机游戏机,到处有它的存在,他给人们带来了娱乐。并且通过这次的动手,我发现它的组成与实现其实很麻烦,让我学会了很多东西。

首先感谢学校及老师给了我们这次上机实习的机会.虽然它与实际生活联系不是太密切,但毕竟让我们感到了实战的感觉.在实践编程过程中积累了宝贵的经验.这次数据结构课程设计使我们对此门课充满了乐趣,也学到了很多知识, Java在社会中的用处也随处可见,它的作用也是不会被忽视的, 我们也应该重视.这将会是一门日益重要的学科.,在编程过程中,曾遇到了很多问题,也失败了很多次,不过最终通过不懈的努力,翻阅资料,征求老师和同学的意见还是圆满完成了。这次的设计进一步提高了我对数据结构的认识,也发现了许多问题,更学到了许多知识。这是我对这次课程设计的一点体会.。在这次课程设计的过程中,在我的指导老师曾阳艳的精心指导下,我的编程,理解,动手及思维能力有了提高,同时也对数据结构的感觉更好了.所以在此对他的指导表示感谢!

参考文献

1,《Java实用教程》  郑阿奇

2,《Java实用教程》  耿祥义

3,互联网

更多相关推荐:
贪吃蛇游戏java课程设计

宝鸡文理学院计算机科学系JAVA程序设计课程设计报告题目姓名学号专业班级指导教师日期贪吃蛇游戏赵鹏飞陈瑞李烨20xx9606407320xx9606407720xx9606407220xx96064016软...

贪吃蛇---java课程设计

武汉理工大学课程设计课程名称JAVA课程设计题目贪吃蛇程序设计专业电子商务班级学号姓名成绩指导教师月课程设计任务书设计题目设计目的1巩固和加深课堂所学知识2学习掌握一般的软件的设计方法和查阅运用资料的能力3掌握...

Java程序设计报告《贪吃蛇》

Java程序设计课程设计报告题目贪吃蛇游戏的设计与实现指导老师沈泽刚专业计算机科学与技术班级103姓名梁潇一课程设计目的贪吃蛇游戏一款非常经典的手机游戏因为它比较简单有趣无论老少都比较适合目的是更好地了解和掌握...

java课程设计贪吃蛇游戏设计

前言Java最初被命名为Oak目标设定在家用电器等小型系统的编程语言来解决诸如电视机电话闹钟烤面包机等家用电器的控制和通讯问题由于这些智能化家电的市场需求没有预期的高Sun放弃了该项计划就在Oak几近失败之时随...

java贪吃蛇游戏的设计论文

大连交通大学计算机工程实践摘要近年来Java作为一种新的编程语言以其简单性可移植性和平台无关性等优点得到了广泛地应用特别是Java与万维网的完美结合使其成为网络编程和嵌入式编程领域的首选编程语言JBuilder...

面向对象课程设计--基于java的贪吃蛇游戏的设计与开发

面向对象课程设计1需求分析11游戏开发的可行性游戏开发至今已经有30多年在这个短暂的时期里随着硬件水平的提高游戏开发新技术层出不穷经典游戏比比皆是游戏这个名称一直就存在于每个人的日常生活中如猜拳游戏猜谜游戏大地...

贪吃蛇java课程设计

课程设计说明书NO1沈阳大学课程设计说明书NO2沈阳大学课程设计说明书NO3沈阳大学课程设计说明书NO4沈阳大学课程设计说明书NO5沈阳大学课程设计说明书NO6沈阳大学课程设计说明书NO7沈阳大学课程设计说明书...

贪吃蛇Java课程设计

目录1设计任务与要求111设计任务112具体要求12软件主要模块流程图23总体方案与说明331总体方案332系统模块3321游戏界面设计3322贪吃蛇蛇身及运动设置5323游戏控制设置34程序设计441Game...

Java贪吃蛇游戏设计课程设计

华东交通大学理工学院课程设计报告书所属课程名称JAVA课程设计题目贪吃蛇游戏设计分院专业班级学号指导教师华东交通大学理工学院课程设计论文任务书专业班级姓名一课程设计论文题目贪吃蛇游戏设计二课程设计论文工作自20...

java课程设计贪吃蛇

枣庄学院信息科学与工程学院课程设计任务书题目java设计贪吃蛇游戏学号20xx12310141姓名张丛磊年级20xx级32专业计算机科学技术课程java指导教师刘梦林职称完成时间20xx1225课程设计任务书及...

java贪吃蛇报告

1设计要求与任务11设计要求1学习android基础理论熟悉Java和Android开发包学习xml文件编写熟悉Android手机系统设计中的有关资料熟悉使用eclipse软件工具和ADT插件了解MVC模式和设...

java课程设计贪吃蛇游戏设计asd

前言Java最初被命名为Oak目标设定在家用电器等小型系统的编程语言来解决诸如电视机电话闹钟烤面包机等家用电器的控制和通讯问题由于这些智能化家电的市场需求没有预期的高Sun放弃了该项计划就在Oak几近失败之时随...

java贪吃蛇设计报告(13篇)