贪吃蛇项目文档

4 篇文章 0 订阅

 

贪吃蛇游戏开发文档

1.系统介绍

1.1系统目标

贪吃蛇是一个益智性游戏。通过本游戏的设计和实现,可以提升java技术能力,提升开发的能力以及掌握项目的开发流程。

1.2开发环境

系统环镜:windows

开发工具:eclipse mars,jdk1.8

1.3需求分析

在一定范围内,生成一条蛇,和随机生成一个实物。当蛇吃到食物以后蛇身变长,

通过键盘的方向键控制蛇的运行方向,当蛇头碰到障碍物或者蛇身,游戏结束。

控制游戏暂停,继续,游戏开始结束游戏。

1.3.1 绘制图形的需求

绘制一个简介清晰的小蛇和食物。其中小蛇包括蛇头,蛇身,蛇尾。

小蛇:绘制成圆形的图像,其中舌头是填充为黄色,蛇身和蛇尾填充为黄色

食物:绘制成方形的图形,食物要求填充为红色。

 1.3.2 显示需求

  当游戏开始后,小蛇是一直移动状态。当小蛇吃掉食物以后蛇身变长,同时当前食物消失,食物随机产生。蛇身随着蛇的移动不断刷新。

1.3.3 按键的需求

通过键盘方向键(wasd或者上下左右)进行蛇的移动,当蛇头碰到边界蛇身,游戏结束。

  通过按钮实现游戏暂停继续,重新开始及结束游戏

在横线对象内绘制线,在图像方法内调用食物对象和贪吃蛇对象,draw()方法

1.4技术要求

面向对象技术

gui编程技术

事件处理机制

1.4.1

面向对象的特性:

封装:隐藏内部的实现细节,提供可以对外访问的借口

继承:子类拥有父类的属性和行为,实现代码的高效率重用。

多态:同一个动作作用于不同的对象产生不同的行为。

-----------------------------------------

类的组成部分·:

属性

方法

构造器(构造了对象的生命周期)

内部类

代码块面向对象

1.4.2gui编程

java提供三个包用于开发gui

java。awt:提供字体绘制图形

javax.swing:提供gui变成的各种组件如窗体,按钮,文本框

java。awt。event:提供事件处理机制

 

1.4.3

贪吃蛇的移动是持续性的,只要贪吃蛇没有死亡就可以继续以多,用多线程

主线程

键盘监听线程

状态监听线程

绘制动画线程

 

1.4.4事件处理机制

事件

1)例如键盘

事件源

2)按钮

监听器

3)listner

事件编程的步骤

1.编写事件处理类(事件监听者)

 

2.实现监听接口

控制贪吃蛇运行方向的绑定,实现接口

implements KeyListener

public void keyControl(KeyEvent e){

        //通过对案件的判断修改蛇头移动方向,从而控制贪吃蛇方向

         switch (e.getKeyCode()) {

        case KeyEvent.VK_UP:

        //如果蛇头方向不超下可以实现向上移动

        if (head.dir.equals(Config.D)) {

       

          break;   

        }

        head.dir=Config.U;

        break;

        case KeyEvent.VK_DOWN:

        //如果蛇头方向不超上就可以实现向下移动

        if(head.dir.equals(Config.U)){

          break;

        }

        head.dir=Config.D;

        break;

         case KeyEvent.VK_RIGHT:

        if(head.dir.equals(Config.L)){

          break;

        }

        head.dir=Config.R;

        break;

        case KeyEvent.VK_LEFT:

        if (head.dir.equals(Config.R)) {

          break;

        }

        head.dir=Config.L;

        break

     default:

        break;

     }

      }

 

按钮的监听绑定:

extends JPanel implements ActionListener

 

3.重写事件处理方法

 

     @Override

   public void keyReleased(KeyEvent e) {

     // 調用貪吃蛇控制方向的方法

//   System.out.println(e.getKeyCode());

     snake.keyControl(e);

    

   }

在实现的方法类中调用控制方向的方法

 

重写按钮的监听方法

//actionevent: 获取事件作用的对象

   @Override

   public void actionPerformed(ActionEvent e) {

     // TODO Auto-generated method stub

        //监听对象是暂停游戏

     if (e.getSource() == pause) {

        Config.isPause =false;

     }

     //监听对象是继续游戏

     if (e.getSource() == continu) {

         Config.isPause =true;

         //设置键盘监听焦点

         myPanel.setFocusable(true);

         myPanel.requestFocus();

     }

     //监听对象是重新开始游戏

     if (e.getSource()== restart) {

        //1.停掉当前线程

        myPanel.snakeThread.stopThread();

        //2.重新生成蛇和食物

        Food food =new Food();

        myPanel.food =food;

        myPanel.snake=new Snake(food);

        //还原config的控制条件还原初始状态

        Config.isPause=true;

        Config.isLive=true;

       

        //3.启动创建一个新的线程(内部类对象)

            SnakeThread snakeThread =myPanel.new SnakeThread();

        //4.启动线程

            snakeThread.start();

            myPanel.snakeThread =snakeThread;

            //获取键盘焦点

            myPanel.setFocusable(true);

        myPanel.requestFocus();

     }

     //监听对象是退出游戏

     if (e.getSource() == exit) {

       System.exit(0);

        }

   }

 

 

 

 

4.指定事件响应者实现注册监听

 4.1@Override

   public void keyReleased(KeyEvent e) {

     // 調用貪吃蛇控制方向的方法

//   System.out.println(e.getKeyCode());

     snake.keyControl(e);

    

   }

4.2 //注册按钮监听

     pause.addActionListener(this);

     continu.addActionListener(this);

     restart.addActionListener(this);

     exit.addActionListener(this);

2.系统设计

2.1类的设计

蛇类           snake

食物类        food

节点类(指定贪吃蛇的颜色和形状)           node

常量类 指定方向以及画布的大小         config

按钮类        button

 

2.2功能设计

1mypanle类实现贪吃蛇对象显示和食物对象显示以及贪吃蛇移动的实现

2.实现蛇类的上下左右移动

3.当蛇头吃到食物时增长蛇头

4.当蛇头碰到障碍物和自己节点时结束游戏

5绑定按钮实现对贪吃蛇状态的控制

 

3.系统实现

3.1开发食物对象

1)需要在主界面中创建食物对象,Food food =new Food();

2)在food类中创建绘制食物图形的方法public voiddraw(Graphics g)

3)随机生成食物所在的位置public void repair()

3.2贪吃蛇对象

初始化贪吃蛇的位置

//指定蛇头。蛇身,蛇尾节点。

    head =new Node(7, 13,Config.R);

    body =new Node(7, 12,Config.R);

    tail =new Node(7, 11,Config.R);

 

绑定蛇头蛇身蛇尾的关系

// 绑定蛇头,蛇身,蛇尾节点之间的关系。

    head.next =body;

    body.pre =head;

    body.next= tail;

    tail.pre = body;

通过便利绘制蛇的节点,并且在一个方法上设置上颜色和形状draw方法

3.3实现贪吃蛇的移动

//貪吃蛇移動的方法

   public void move(){

      // 1.添加蛇頭2.去除蛇尾3.吃食物4.死亡檢測

       addHead();//添加蛇頭。

       removeTail();//去除蛇尾

       eat();

       deadCheck();

   }

贪吃蛇的移动依靠线程

通过重写run方法判断蛇的存货状态来确定蛇是否移动

class SnakeThread extends Thread{

       boolean flag =true;//重新开始

     @Override

     public void run(){

   //当贪吃蛇没有死亡的时候则应该继续移动

        while(Config.isLive && flag){

          //Config.isLive判斷貪吃蛇是否存活

          try {

             //当前线程休眠0.3

          Thread.sleep(300);

          } catch (InterruptedException e) {

             // TODO Auto-generated catch block

             e.printStackTrace();

          }

             //config.ispause=true:的情况下:代表继续游戏

          //configispause==false:代表是暂停游戏

          if (Config.isLive && Config.isPause) {

             //该方法适用于重绘的组件,具有页面刷新的效果

             //重绘的步骤:调用repaint方法--》调用awt线程--update方法清楚当前显示--》调用repainrt方法实现绘制图形

             repaint();//重绘

          }

         

          if (!Config.isLive) {

             //弹出借宿游戏结束的对话框

             JOptionPane.showMessageDialog(MyPanel.this,"游戏结束");

            

          }

       

        }

       

     }

   //当贪吃蛇没有死亡的时候则应该继续移动

        while(Config.isLive && flag){

          //Config.isLive判斷貪吃蛇是否存活

          try {

             //当前线程休眠0.3

          Thread.sleep(300);

          } catch (InterruptedException e) {

             // TODO Auto-generated catch block

             e.printStackTrace();

          }

             //config.ispause=true:的情况下:代表继续游戏

          //configispause==false:代表是暂停游戏

          if (Config.isLive && Config.isPause) {

             //该方法适用于重绘的组件,具有页面刷新的效果

             //重绘的步骤:调用repaint方法--》调用awt线程--update方法清楚当前显示--》调用repainrt方法实现绘制图形

             repaint();//重绘

          }

         

          if (!Config.isLive) {

             //弹出借宿游戏结束的对话框

             JOptionPane.showMessageDialog(MyPanel.this,"游戏结束");

            

          }

       

        }

       

     }

 

 

   //当贪吃蛇没有死亡的时候则应该继续移动

        while(Config.isLive && flag){

          //Config.isLive判斷貪吃蛇是否存活

          try {

             //当前线程休眠0.3

          Thread.sleep(300);

          } catch (InterruptedException e) {

             // TODO Auto-generated catch block

             e.printStackTrace();

          }

             //config.ispause=true:的情况下:代表继续游戏

          //configispause==false:代表是暂停游戏

          if (Config.isLive && Config.isPause) {

             //该方法适用于重绘的组件,具有页面刷新的效果

             //重绘的步骤:调用repaint方法--》调用awt线程--update方法清楚当前显示--》调用repainrt方法实现绘制图形

             repaint();//重绘

          }

         

          if (!Config.isLive) {

             //弹出借宿游戏结束的对话框

             JOptionPane.showMessageDialog(MyPanel.this,"游戏结束");

            

          }

       

        }

       

     }

 

   //当贪吃蛇没有死亡的时候则应该继续移动

        while(Config.isLive && flag){

          //Config.isLive判斷貪吃蛇是否存活

          try {

             //当前线程休眠0.3

          Thread.sleep(300);

          } catch (InterruptedException e) {

             // TODO Auto-generated catch block

             e.printStackTrace();

          }

             //config.ispause=true:的情况下:代表继续游戏

          //configispause==false:代表是暂停游戏

          if (Config.isLive && Config.isPause) {

             //该方法适用于重绘的组件,具有页面刷新的效果

             //重绘的步骤:调用repaint方法--》调用awt线程--update方法清楚当前显示--》调用repainrt方法实现绘制图形

             repaint();//重绘

          }

         

          if (!Config.isLive) {

             //弹出借宿游戏结束的对话框

             JOptionPane.showMessageDialog(MyPanel.this,"游戏结束");

         

设置停止线程的方法

Public void stopthread();

用来绑定停止按钮,实现暂停游戏

 

 

 

 

3.4实现贪吃蛇吃食物增长

1.eat()方法通过判断食物蛇头是否重合进行,如果重合就实现添加蛇头和随机生成食物的方法

public void eat(){

        //判断两个矩形是否重合(蛇头是否碰到食物)

        Rectangle a = getHeadRec();

        Rectangle b = food.getFoodRec();

        if (a.intersects(b)) {

         addHead();

         food.repair();

        }

      }

3.5检验贪吃蛇是否死亡

当蛇头碰到边界或者碰到自己节点,修改蛇的状态停止线程的运行

  //检测贪吃蛇是否死亡

      public void deadCheck(){

        //当蛇头碰到边界

        //行的范围:0 - config.rows-1

        //列的范围:0 - Config.col-1

        if (head.row<0 || head.col<0 || head.row>Config.ROWS-1 ||head.col>Config.COLS-1) {

            Config.isLive=false;

           }

        //当蛇头碰到蛇身

        //便利蛇身,判断节点与舌头重合

        for (Node n =head.next;n!=null;n=n.next) {   

          //判断蛇头的行和列  和当前蛇身节点的位置是否相同

         if (head.row == n.row && head.col==n.col) {

          Config.isLive=false;

          break;

        }

3.6实现按钮与状态的绑定

首先实现implements ActionListener接口

重写接口方法actionPerformed

进行按钮当前状态的判断

//actionevent: 获取事件作用的对象

   @Override

   public void actionPerformed(ActionEvent e) {

     // TODO Auto-generated method stub

        //监听对象是暂停游戏

     if (e.getSource() == pause) {

        Config.isPause =false;

     }

     //监听对象是继续游戏

     if (e.getSource() == continu) {

         Config.isPause =true;

         //设置键盘监听焦点

         myPanel.setFocusable(true);

         myPanel.requestFocus();

     }

     //监听对象是重新开始游戏

     if (e.getSource()== restart) {

        //1.停掉当前线程

        myPanel.snakeThread.stopThread();

        //2.重新生成蛇和食物

        Food food =new Food();

        myPanel.food =food;

        myPanel.snake=new Snake(food);

        //还原config的控制条件还原初始状态

        Config.isPause=true;

        Config.isLive=true;

       

        //3.启动创建一个新的线程(内部类对象)

            SnakeThread snakeThread =myPanel.new SnakeThread();

        //4.启动线程

            snakeThread.start();

            myPanel.snakeThread =snakeThread;

            //获取键盘焦点

            myPanel.setFocusable(true);

        myPanel.requestFocus();

     }

     //监听对象是退出游戏

     if (e.getSource() == exit) {

       System.exit(0);

把按钮注册监听添加到你定义的按钮中

   //注册按钮监听

     pause.addActionListener(this);

     continu.addActionListener(this);

     restart.addActionListener(this);

     exit.addActionListener(this);

3.7bug

3.7.1贪吃蛇蛇的节点与食物重合

//判断随机生成食物坐标不能喝贪吃蛇接节点坐标重合

     for (Node n=snake.head;n !=null;n=n.next) {

        //判断节点所在行与食物所在行是否一致

        boolean x=n.row ==food.getRow();

        //判断节点所在列于十五所在列是否一致

        boolean y=n.col==food.getCol();

         if (x && y) {

           //随机生成食物

           food.repair();

           break;

        }

     }

3.7.2,食物与贪吃蛇蛇头重合

public void eat(){

        //判断两个矩形是否重合(蛇头是否碰到食物)

        Rectangle a = getHeadRec();

        Rectangle b = food.getFoodRec();

        if (a.intersects(b)) {

         addHead();

         food.repair();

        }

      }

      //获取蛇头坐标

      public Rectangle getHeadRec(){

        //获取蛇头坐标矩形

        

        return new Rectangle(head.col*Config.SPAN,head.row*Config.SPAN,Config.SPAN,Config.SPAN);

      }

获取食物坐标

   //获取食物坐标

   public Rectangle getFoodRec(){

    

     return new Rectangle(col*Config.SPAN, row*Config.SPAN,Config.SPAN, Config.SPAN);

    

   }

 

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值