📄 twosnakemodel.java
字号:
package TwoPlayer;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Random;
import javax.swing.JOptionPane;
class TwoSnakeModel implements Runnable {
TwoSnake gs;
/*
* 上下为偶数,左右为奇数
* 原因见changeDirection(int newDirection)
*/
public static final int UP = 2;
public static final int DOWN = 4;
public static final int LEFT = 1;
public static final int RIGHT = 3;
/*
* 存储蛇身位置,及标志蛇身位置的true、false情况
* true情况下咬到会死
*/
boolean[][] matrixOne;
boolean[][] matrixTwo;
LinkedList nodeArrayOne = new LinkedList();
LinkedList nodeArrayTwo = new LinkedList();
/*
*开始移动方向
*/
int directionOne = 3;
int directionTwo = 3;
/*
* 两次移动间的睡眠时间(ms)
*/
int timeIntervalOne = 200;
int timeIntervalTwo = 200;
/*
* 两蛇的分数
* 计算分数的参数countMoveOne和countMoveTwo
*/
int scoreOne = 0;
int scoreTwo = 0;
int countMoveOne = 0;
int countMoveTwo = 0;
/*
* 目标分数
*/
int targetScore=2000;
/*
* 线程1,2
*/
Thread threadOne, threadTwo;
int one = 1, two = 2;
/*
* 速度因子
*/
double speedChangeRate = 0.75;
/*
* 运行状态
*/
boolean running = false;
/*
* 暂停状态
*/
boolean paused = false;
/*
* 食物位置true、false情况
*/
boolean[][] matrixFood;
Node food;
int maxX;
int maxY;
public TwoSnakeModel(TwoSnake gs, int maxX, int maxY) {
this.gs = gs;
this.maxX = maxX;
this.maxY = maxY;
threadOne = new Thread(this);
threadTwo = new Thread(this);
/*
* 初始化一些变量
*/
matrixOne = new boolean[maxX][];
for (int i = 0; i < maxX; ++i) {
matrixOne[i] = new boolean[maxY];
Arrays.fill(matrixOne[i], false);
}
matrixTwo = new boolean[maxX][];
for (int i = 0; i < maxX; ++i) {
matrixTwo[i] = new boolean[maxY];
Arrays.fill(matrixTwo[i], false);
}
matrixFood = new boolean[maxX][];
for (int i = 0; i < maxX; ++i) {
matrixFood[i] = new boolean[maxY];
Arrays.fill(matrixFood[i], false);
}
/*
* 设置蛇开始状态的长度
* maxX是 游戏界面的宽度/蛇的宽度
*/
int lengthOne = maxX > 20 ? 5 : maxX / 2;
for (int i = 0; i < lengthOne; ++i) {
int x = 0;
int y = 0;
nodeArrayOne.addLast(new Node(x, y));
matrixOne[x][y] = true;
}
int lengthTwo = maxX > 20 ? 5 : maxX / 2;
for (int i = 0; i < lengthTwo; ++i) {
int x = 0;
int y = 1;
nodeArrayTwo.addLast(new Node(x, y));
matrixTwo[x][y] = true;
}
food = createFood();
}
/*
* 改变方向
*
* 判断(%2)是为了当按下方向命令与当前方向"水平"时,不改变方向
* 而按下方向命令与当前方向"垂直"时,改变方向
* eg:当方向向上时
* 按下"向上"和"向下"时方向不变
* 按下"向左"和"向右"时才改变方向
*/
public void changeDirectionOne(int newDirection) {
if (directionOne % 2 != newDirection % 2) {
directionOne = newDirection;
}
}
public void changeDirectionTwo(int newDirection) {
if (directionTwo % 2 != newDirection % 2) {
directionTwo = newDirection;
}
}
public boolean moveOn(int num) {
/*
* 线程1,即蛇1
*/
if (num == one) {
Node n = (Node) nodeArrayOne.getFirst();
int x = n.x;
int y = n.y;
switch (directionOne) {
case UP:
y--;
break;
case DOWN:
y++;
break;
case LEFT:
x--;
break;
case RIGHT:
x++;
break;
}
/*
* 判断是否在游戏界面内
*/
if ((0 <= x && x < maxX) && (0 <= y && y < maxY)) {
/*
* 判断当前点是否有为空
* 不为空情况
*/
if (matrixOne[x][y]) {
return false;
}
/*
* 判断是否是食物
* 是食物就往第一个节点添加一点
*/
else if (matrixFood[x][y]) {
if (x == food.x && y == food.y) {
nodeArrayOne.addFirst(food);
matrixFood[x][y] = false;
/*
* 计算分数,分数跟移动格数有关
* 清空移动格数
*/
int scoreGet = (10000 - 200 * countMoveOne)
/ timeIntervalOne;
scoreOne += scoreGet > 0 ? scoreGet : 10;
countMoveOne = 0;
/*
*
*/
food = createFood();
return true;
}
/*
* 不是食物情况(咬到自己),游戏结束
*/
}
/*
* 为空情况
*/
else {
nodeArrayOne.addFirst(new Node(x, y));
matrixOne[x][y] = true;
n = (Node) nodeArrayOne.removeLast();
matrixOne[n.x][n.y] = false;
countMoveOne++;
return true;
}
}
}
/*
* 线程2,即蛇2
*/
if (num == two) {
Node n = (Node) nodeArrayTwo.getFirst();
int x = n.x;
int y = n.y;
switch (directionTwo) {
case UP:
y--;
break;
case DOWN:
y++;
break;
case LEFT:
x--;
break;
case RIGHT:
x++;
break;
}
/*
* 判断是否在游戏界面内
*/
if ((0 <= x && x < maxX) && (0 <= y && y < maxY)) {
/*
* 判断当前点是否有为空
* 不为空情况
*/
if (matrixTwo[x][y]) {
return false;
}
/*
* 判断是否是食物
* 是食物就往第一个节点添加一点
*/
else if (matrixFood[x][y]) {
if (x == food.x && y == food.y) {
nodeArrayTwo.addFirst(food);
matrixFood[x][y] = false;
/*
* 计算分数,分数跟移动格数有关
* 清空移动格数
*/
int scoreGet = (10000 - 200 * countMoveTwo)
/ timeIntervalTwo;
scoreTwo += scoreGet > 0 ? scoreGet : 10;
countMoveTwo = 0;
/*
*
*/
food = createFood();
return true;
}
/*
* 不是食物情况(咬到自己),游戏结束
*/
}
/*
* 为空情况
*/
else {
nodeArrayTwo.addFirst(new Node(x, y));
matrixTwo[x][y] = true;
n = (Node) nodeArrayTwo.removeLast();
matrixTwo[n.x][n.y] = false;
countMoveTwo++;
return true;
}
}
}
return false;
}
public void run() {
running = true;
while (running) {
if (!paused) {
/*
* 线程1
*/
if (Thread.currentThread() == threadOne) {
try {
Thread.sleep(timeIntervalOne);
} catch (Exception e) {
break;
}
if (moveOn(one)) {
//try解决出错(机房发现的哦错误)
try{
gs.repaint();
}catch(Exception e)
{}
} else {
break;
}
}
/*
* 线程2
*/
else if (Thread.currentThread() == threadTwo) {
try {
Thread.sleep(timeIntervalTwo);
} catch (Exception e) {
break;
}
if (moveOn(two)) {
try{
gs.repaint();
}catch(Exception e)
{}
} else {
break;
}
}
}
}
running = false;
if(Thread.currentThread()==threadOne)
{
/*
* 有一方输了,弹出提示
* 只需一方弹出,running即为false,另一方不需再弹出
*/
if (scoreOne <= targetScore && scoreOne <= targetScore) {
JOptionPane.showMessageDialog(null, "You are Lose!(The target score is "+targetScore+")", "Game Over",
JOptionPane.INFORMATION_MESSAGE);
} else {
if (scoreOne > scoreTwo)
JOptionPane.showMessageDialog(null, "Black Win!",
"Game Over", JOptionPane.INFORMATION_MESSAGE);
else if (scoreOne < scoreTwo)
JOptionPane.showMessageDialog(null, "Blue Win!",
"Game Over", JOptionPane.INFORMATION_MESSAGE);
else if (scoreOne == scoreTwo)
JOptionPane.showMessageDialog(null, "You are Win!",
"Game Over", JOptionPane.INFORMATION_MESSAGE);
}
}
}
/*
* 随机创建一个食物
*/
public Node createFood() {
int x = 0;
int y = 0;
do {
Random r = new Random();
x = r.nextInt(maxX);
y = r.nextInt(maxY);
} while (matrixOne[x][y] || matrixTwo[x][y]);
matrixFood[x][y] = true;
return new Node(x, y);
}
/*
*加快移动速度
*/
public void speedUpOne() {
timeIntervalOne *= speedChangeRate;
}
public void speedUpTwo() {
timeIntervalTwo *= speedChangeRate;
}
/*
* 减慢移动速度
*/
public void speedDownOne() {
timeIntervalOne /= speedChangeRate;
}
public void speedDownTwo() {
timeIntervalTwo /= speedChangeRate;
}
/*
* 改变当前暂停状态
*/
public void changePauseState() {
paused = !paused;
}
}
class Node {
int x;
int y;
Node(int x, int y) {
this.x = x;
this.y = y;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -