📄 snakemode1.java
字号:
/*******************************************************************************
* 文件名:SnakeModel.java 作者:C.Jason 要点分析:
* 1)数据结构:matrix[][]用来存储地图上面的信息,如果什么也没有设置为false,
* 如果有食物或蛇,设置为true;nodeArray,一个LinkedList,用来保存蛇的每
* 一节;food用来保存食物的位置;而Node类是保存每个位置的信息。 2)重要函数: changeDirection(int newDirection)
* ,用来改变蛇前进的方向,而且只是 保存头部的前进方向,因为其他的前进方向已经用位置来指明了。 其中newDirection
* 必须和原来的direction不是相反方向,所以相反方向的值用了同样的奇偶性。在测试 的时候使用了direction%2!=newDirection%2
* 进行判断。 moveOn(),用来更新蛇的位置,对于当前方向,把头部位置进行相应改变。如果越界,
* 结束;否则,检测是否遇到食物(加头部)或身体(结束);如果什么都没有,加上头部, 去掉尾部。由于用了LinkedList数据结构,省去了相当多的麻烦。
******************************************************************************/
import java.util.*;
import javax.swing.*;
// ----------------------------------------------------------------------
// Node:结点类
// ----------------------------------------------------------------------
class Node
{
int x;
int y;
Node(int x, int y)
{
this.x = x;
this.y = y;
}
}
// ----------------------------------------------------------------------
// SnakeModel:贪吃蛇模型
// ----------------------------------------------------------------------
class SnakeModel implements Runnable
{
GreedSnake gs;
boolean[][] matrix;// 界面数据保存在数组里
LinkedList nodeArray = new LinkedList();
Node food;
int maxX;// 最大宽度
int maxY;// 最大长度
int oldDirection=2,nowDirection = 2;// 方向
boolean running = false;
int timeInterval = 1000;// 间隔时间(速度)
double speedChangeRate = 0.75;// 速度改变程度
boolean paused = false;// 游戏状态
int score = 0;
int countMove = 0;
// UP和DOWN是偶数,RIGHT和LEFT是奇数
public static final int UP = 2;
public static final int DOWN = 4;
public static final int LEFT = 1;
public static final int RIGHT = 3;
// ----------------------------------------------------------------------
// GreedModel():初始化界面
// ----------------------------------------------------------------------
public SnakeModel(GreedSnake gs, int maxX, int maxY)
{
this.gs = gs;
this.maxX = maxX;
this.maxY = maxY;
matrix = new boolean[maxX][];
for (int i = 0; i < maxX; ++i)
{
matrix[i] = new boolean[maxY];
Arrays.fill(matrix[i], false);// 没有蛇和食物的地区置false
}
// 初始化贪吃蛇
int initArrayLength = maxX > 20 ? 10 : maxX / 2;
for (int i = 0; i < initArrayLength; ++i)
{
int x = maxX / 2 + i;
int y = maxY / 2;
nodeArray.addLast(new Node(x, y));
matrix[x][y] = true;// 蛇身处置true
}
food = createFood();
matrix[food.x][food.y] = true;// 食物处置true
}
// ----------------------------------------------------------------------
// changeDirection():改变运动方向
// ----------------------------------------------------------------------
public void changeDirection(int newDirection)
{
if (Math.abs(oldDirection-newDirection)!=2)// 避免冲突
{
nowDirection = newDirection;
}
}
// ----------------------------------------------------------------------
// moveOn():贪吃蛇运动函数
// ----------------------------------------------------------------------
public boolean moveOn()
{
Node n = (Node) nodeArray.getFirst();
int x = n.x;
int y = n.y;
switch (nowDirection)
{
case UP:
y--;
break;
case DOWN:
y++;
break;
case LEFT:
x--;
break;
case RIGHT:
x++;
break;
}
oldDirection=nowDirection;
if ((0 <= x && x < maxX) && (0 <= y && y < maxY))
{
if (matrix[x][y])// 吃到食物或者撞到身体
{
if (x == food.x && y == food.y)// 吃到食物
{
nodeArray.addFirst(food);// 在头部加上一结点
// 计分规则与移动长度和速度有关
int scoreGet = (10000 - 200 * countMove) / timeInterval;
score += scoreGet > 0 ? scoreGet : 10;
countMove = 0;
food = createFood();
matrix[food.x][food.y] = true;
return true;
} else
return false;// 撞到身体
} else
// 什么都没有碰到
{
nodeArray.addFirst(new Node(x, y));// 加上头部
matrix[x][y] = true;
n = (Node) nodeArray.removeLast();// 去掉尾部
matrix[n.x][n.y] = false;
countMove++;
return true;
}
}
return false;// 越界(撞到墙壁)
}
// ----------------------------------------------------------------------
// run():贪吃蛇运动线程
// ----------------------------------------------------------------------
public void run()
{
running = true;
while (running)
{
try
{
Thread.sleep(timeInterval);
} catch (Exception e)
{
break;
}
if (!paused)
{
if (moveOn())// 未结束
{
gs.repaint();
} else
// 游戏结束
{
JOptionPane.showMessageDialog(null, "GAME OVER",
"Game Over", JOptionPane.INFORMATION_MESSAGE);
break;
}
}
}
running = false;
}
// ----------------------------------------------------------------------
// createFood():生成食物及放置地点
// ----------------------------------------------------------------------
private Node createFood()
{
int x = 0;
int y = 0;
do
{
Random r = new Random();
x = r.nextInt(maxX);
y = r.nextInt(maxY);
} while (matrix[x][y]);
return new Node(x, y);
}
// ----------------------------------------------------------------------
// speedUp():加快蛇运动速度
// ----------------------------------------------------------------------
public void speedUp()
{
timeInterval *= speedChangeRate;
}
// ----------------------------------------------------------------------
// speedDown():放慢蛇运动速度
// ----------------------------------------------------------------------
public void speedDown()
{
timeInterval /= speedChangeRate;
}
// ----------------------------------------------------------------------
// changePauseState(): 改变游戏状态(暂停或继续)
// ----------------------------------------------------------------------
public void changePauseState()
{
paused = !paused;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -