⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 snakemodel.java

📁 MVC设计模式早在面向对象语言Smalltalk-80中就被提出并在此后得到业界的广泛接受。它包括三类对象:(1)模型(Model)对象:是应用程序的主体部分。(2)视图(View)对象:是应用程序中
💻 JAVA
字号:
/********************************************************************************************/
/*                                                                                          */
/*                              SnakeModel.java                                             */
/*                                                                                          */
/*                               贪吃蛇蛇的模型,封装了蛇的属性和动作                       */
/*                                                                                          */
/*                      Programed by Luo Pengkui on 2004-9                                  */
/*                                                                                          */
/********************************************************************************************/

import javax.swing.*;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Observable;
import java.util.Random;
import java.awt.Point;

//------------------------------------ BEGIN ------------------------------------------------


public class SnakeModel extends Observable implements Runnable
{

    private LinkedList m_nodeArray = new LinkedList();          // 蛇体用LinkedList类建造
    private int m_maxX;                                         // 运动的最大范围
    private int m_maxY;
    private int m_currentDirection = 2;                         // 贪吃蛇当前的运动方向
    private boolean m_isRunning = false;                        // 贪吃蛇当前的运行状态

    private MatrixModel m_matrix;

    private boolean m_scoreAutoDecrease = true;                 // 分数是否自动递减
    private boolean m_speedUpAfterEaten = false;                // 吃食后是否自动加速


    private int m_timeInterval;                                 // 运行速度(时间间隔),单位毫秒
    private double m_speedChangeRate = 0.95;                    // 每次速度变化率
    private boolean m_isPaused = false;                         // 暂停标志
    private ScoreModel m_score;                                 // 得分
    private int m_countMove = 0;                                // 吃到食物前移动的次数

    public static final int UP = 2;                             // 设置上下左右方向键的运算值
    public static final int DOWN = 4;
    public static final int LEFT = 1;
    public static final int RIGHT = 3;

    public static final int EMPTY = 0;                          // 格点的四种状态(空,果实,蛇 ,墙)
    public static final int FRUIT = 1;
    public static final int SNAKE = 2;
    public static final int WALL  = 3;

    public SnakeModel( MatrixModel matrix )                     // 构造器,只用于传递引用
    {
        m_matrix = matrix;
        m_score = new ScoreModel();
    }

    public void mb_resetSnake(int maxX, int maxY,               // 初始化蛇模型
        int timeInterval,int snakeLength, boolean scoreAutoDecrease,
        double speedChangeRate, boolean speedUpAfterEaten)
    {
        m_maxX = maxX;
        m_maxY = maxY;
        m_currentDirection = SnakeModel.UP;                     // 蛇运行的方向默认向上
        m_timeInterval = timeInterval;
        m_scoreAutoDecrease = scoreAutoDecrease;
        m_speedUpAfterEaten = speedUpAfterEaten;
        m_speedChangeRate = speedChangeRate;
        m_isPaused = false;                                     // 暂停标志
        m_score. mb_setScore( 100 );
        m_countMove = 0;                                        // 吃到食物前移动的次数

        // 初始化蛇体
        m_nodeArray.clear();
        for (int i = 0; i < snakeLength; ++i)
        {
            int x = m_maxX / 2 + i;
            int y = m_maxY / 2;
            m_nodeArray. addLast(new Point(x, y));
            m_matrix.mb_setGridState( x,y,SNAKE );
        }
    }

    public void mb_setDirection( int newDirection )
    {
        // 改变的方向不能与原来方向同向或反向,这里利用了奇偶性使判断简化
        if ( m_currentDirection % 2 != newDirection % 2)
        {
            m_currentDirection = newDirection;
        }
    }


    public boolean mb_moveOn()                                  // 蛇前进一次
    {
        Point node = ( Point )m_nodeArray.getFirst();
        int x = node.x;
        int y = node.y;

        switch (m_currentDirection)                             // 根据方向增减坐标值
        {
            case UP:
                y--;
                break;
            case DOWN:
                y++;
                break;
            case LEFT:
                x--;
                break;
            case RIGHT:
                x++;
                break;
        }

        boolean flag = false;
        switch ( m_matrix.mb_getGridState(x,y) )
        {
            case WALL:                                          // 触墙而死
                flag = false;
                break;
            case SNAKE:                                         // 吃到蛇体而死
                flag = false;
                break;
            case EMPTY:                                         // 如果新坐标的点上没有东西(蛇体),移动蛇体
                m_nodeArray.addFirst(new Point(x, y));
                m_matrix.mb_setGridState( x,y,SNAKE );
                node = ( Point )m_nodeArray.removeLast();       // 去尾,并返回尾节点
                m_matrix.mb_setGridState( node.x, node.y, EMPTY );  // 释放尾节点
                m_countMove++;
                flag = true;
                break;
            case FRUIT:                                         // 如果新坐标的点上是食物,成功
                m_nodeArray.addFirst( new Point(x,y) );         // 从蛇头赠长
                m_matrix.mb_setGridState( x,y,SNAKE );

                // 分数规则,与移动改变方向的次数和速度两个元素有关
                int scoreGet = (10000 - 150 * m_countMove) / m_timeInterval;
                int tempScore = ( scoreGet > 0 ? scoreGet : 10 );
                m_score.mb_addScore( tempScore );
                if (m_speedUpAfterEaten )                       // 吃食后是否自动加速
                    mb_speedUp();
                m_countMove = 0;
                flag = true;
                break;
            default:;
        }
        return flag;
    } // End of method : mb_moveOn()

    public void run()
    {
        m_isRunning = true;
        while (m_isRunning)
        {
            try
            {
                Thread.sleep(m_timeInterval);                   // 延时
                if((m_scoreAutoDecrease)&&(!m_isPaused))        // 分数是否自动递减
                    m_score.mb_addScore(-2);
            }
            catch (Exception e)
            {
                break;
            }

            if (!m_isPaused)
            {
                if ( mb_moveOn() )
                {
                    setChanged();           // Model通知View数据已经更新, in Class Observable
                    notifyObservers();
                }
                else
                {
                    JOptionPane.showMessageDialog(null,"对不起,游戏结束!","Game Over",JOptionPane.INFORMATION_MESSAGE);
                    break;
                }
            }
        }
        m_isRunning = false;
    }

    // -------------------------------------------------------------------------
    // 以下是对一些私有变量的操作

    public void mb_speedUp()                                    // 加速
    {
        m_timeInterval *= m_speedChangeRate;
    }

    public void mb_speedDown()                                  // 减速
    {
        m_timeInterval /= m_speedChangeRate;
    }

    public void mb_changePauseState()                           // 暂停或重启
    {
        m_isPaused = !m_isPaused;
    }

    public ScoreModel mb_getScoreModel()                        // 返回分数
    {
        return m_score;
    }

    public LinkedList mb_getNodeArray()                         // 返回蛇身点列
    {
        return m_nodeArray;
    }

    public boolean mb_isRunning()                               // 返回蛇的运行状态
    {
        return m_isRunning;
    }

    public String toString()                                    // 重写toString方法
    {
        String result = "";
        for (int i = 0; i < m_nodeArray.size(); ++i) {
            Point n = (Point) m_nodeArray.get(i);
            result += "[" + n.x + "," + n.y + "]";
        }
        return result;
    }
}

//------------------------------------- END -------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -