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

📄 twosnakemodel.java

📁 是一个贪吃蛇的游戏
💻 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 + -