📄 snakemodel.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 + -