A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

以前有看过C#编程中有一个骑士飞行棋的小案例,一直想用java语言来实现,但是java不支持控制台打印有颜色的字符,效果没有C#的好。后来看到java可以使用 jansi-1.11.jar包来打印有颜色的字符。所以抽空写了下这个骑士飞行棋的小游戏。其实主要是练习数组和循环的知识,在C#编程中也是为了巩固数组和循环知识而拿来练习的。

程序实现了部分功能,应该还有点小bug,有兴趣的可以继续完善。下图是程序效果图。
注:只能在cmd环境下运行,在eclipse下运行不出效果。程序就是用editplus写的。
附件有程序和jansi-1.11.jar包,把jansi包加入classpath中就可以用了。

主程序:KnightChess.java
[Java] 纯文本查看 复制代码
/**[/size]
[size=4]1.先将jansi-1.11.jar文件的路径加入classpath中,里面包含可以改变控制台打印字符颜色的方法.[/size]
[size=4]2.导入需要用到的包[/size]
[size=4]*/[/size]
[size=4]import org.fusesource.jansi.AnsiConsole;[/size]
[size=4]import static org.fusesource.jansi.Ansi.*;[/size]
[size=4]import java.io.IOException;[/size]
[size=4]import java.util.Scanner;[/size]

[size=4]public class KnightChess {[/size]
[size=4]	//游戏只有两个玩家,定义两个玩家对象[/size]
[size=4]	public static Player p1;[/size]
[size=4]	public static Player p2;[/size]
[size=4]	//定义一个二维数组来保存地图[/size]
[size=4]	public static String[][] map;[/size]
[size=4]	//定义一个获取键盘输入的对象[/size]
[size=4]	public static Scanner sc = new Scanner(System.in);[/size]
[size=4]	//主函数[/size]
[size=4]	public static void main(String[] args) throws Exception{[/size]
[size=4]		System.out.println("---------------------------------------------------------------------------");[/size]
[size=4]		System.out.println("-----------------------------骑士飞行棋------------------------------------");[/size]
[size=4]		System.out.println("---------------------------------------------------------------------------");[/size]
[size=4]		System.out.println("---------------------------------------------------------------------------");[/size]
[size=4]		System.out.println("游戏规则:有两名玩家,已定义成甲和乙。甲、乙玩家轮流"[/size]
[size=4]		+ "掷骰子,谁先到终点就赢得比赛。\r\n甲和乙掷骰子都只需要按enter键.");[/size]
[size=4]		//创建两个玩家甲 乙[/size]
[size=4]		p1 = new Player("甲");[/size]
[size=4]		p2 = new Player("乙");[/size]
[size=4]		//初始化地图[/size]
[size=4]		initMap();[/size]
[size=4]		//开始游戏[/size]
[size=4]		GameBegin();[/size]
[size=4]		//为了线程阻塞,停留在结束画面	[/size]
[size=4]		System.out.println("-----------游戏结束-----------");[/size]
[size=4]	}[/size]
[size=4]	//初始化地图[/size]
[size=4]	public static void initMap(){[/size]
[size=4]		//地图是一个21行30列的二维数组[/size]
[size=4]		//给二维数组的每个位置赋值,使打印时显示迂回前进的地图[/size]
[size=4]		map = new String[21][30];[/size]
[size=4]		for(int i = 0; i < map.length; i++){	[/size]
[size=4]			for(int j = 0; j < 30; j++){[/size]
[size=4]				map[i][j] = "□";[/size]
[size=4]			}[/size]
[size=4]			if(i % 4 == 1){[/size]
[size=4]				for(int j = 0; j < 29; j++){[/size]
[size=4]					map[i][j] = "我";[/size]
[size=4]				}[/size]
[size=4]			}[/size]
[size=4]			if(i % 4 == 3){[/size]
[size=4]				for(int j = 1; j < 30; j++){[/size]
[size=4]					map[i][j] = "我";[/size]
[size=4]				}[/size]
[size=4]			}[/size]
[size=4]		}[/size]
[size=4]		//初始化有魔法功能的特殊位置[/size]
[size=4]		magicMap();[/size]
[size=4]		//甲在数组中的位置[/size]
[size=4]		map[p1.posY][p1.posX] = p1.getName();[/size]
[size=4]		//乙在数组中的位置[/size]
[size=4]		map[p2.posY][p2.posX] = p2.getName();[/size]
[size=4]	}[/size]
[size=4]	[/size]
[size=4]	public static void display()throws Exception{[/size]
[size=4]		//产生一个进程调用控制台的命令用来清屏[/size]
[size=4]		new ProcessBuilder("cmd", "/C", "cls").inheritIO().start();[/size]
[size=4]		//因为这里不加这个线程睡眠的语句,打印出的地图有问题,所以加了[/size]
[size=4]		//应该是上面进程与下面打印的并行进行,前面打印出的字符都被清屏的进程给清掉了.[/size]
[size=4]		Thread.sleep(30);[/size]
[size=4]		AnsiConsole.systemInstall();[/size]
[size=4]		//根据数组中存储的不同字符打印出不同的字符[/size]
[size=4]		for(int i = 0; i < map.length; i++){[/size]
[size=4]			for(int j = 0; j < map[0].length; j++){[/size]
[size=4]				String shape = map[i][j];[/size]
[size=4]				switch (shape) {[/size]
[size=4]				case "□":[/size]
[size=4]					System.out.print(ansi().render("@|white " + shape +"|@"));[/size]
[size=4]					break;[/size]
[size=4]				case "○":[/size]
[size=4]					System.out.print(ansi().render("@|red " + shape +"|@"));[/size]
[size=4]					break;[/size]
[size=4]				case "▽":[/size]
[size=4]					System.out.print(ansi().render("@|blue " + shape +"|@"));[/size]
[size=4]					break;[/size]
[size=4]				case "△":[/size]
[size=4]					System.out.print(ansi().render("@|yellow " + shape +"|@"));[/size]
[size=4]					break;[/size]
[size=4]				case "☆":[/size]
[size=4]					System.out.print(ansi().render("@|cyan " + shape +"|@"));[/size]
[size=4]					break;[/size]
[size=4]				case "◇":[/size]
[size=4]					System.out.print(ansi().render("@|white " + shape +"|@"));[/size]
[size=4]					break;[/size]
[size=4]				case "甲":[/size]
[size=4]					System.out.print(ansi().render("@|magenta " + shape +"|@"));[/size]
[size=4]					break;[/size]
[size=4]				case "乙":[/size]
[size=4]					System.out.print(ansi().render("@|yellow " + shape +"|@"));[/size]
[size=4]					break;[/size]
[size=4]				default:[/size]
[size=4]					System.out.print("  ");[/size]
[size=4]					break;[/size]
[size=4]				}		[/size]
[size=4]			}[/size]
[size=4]			System.out.println();[/size]
[size=4]		}[/size]
[size=4]	}[/size]
[size=4]	//游戏开始[/size]
[size=4]	public static void GameBegin() throws Exception{[/size]
[size=4]		while(true){[/size]
[size=4]			if(Player.flag == "结")[/size]
[size=4]				break;[/size]
[size=4]			System.out.println("请甲开始掷骰子");[/size]
[size=4]			//接收键盘输入,按回车后,执行下一条语句.[/size]
[size=4]			sc.nextLine();[/size]
[size=4]			//甲玩游戏[/size]
[size=4]			p1.play();[/size]
[size=4]			if(Player.flag == "结")[/size]
[size=4]				break;[/size]
[size=4]			System.out.println("请乙开始掷骰子");[/size]
[size=4]			sc.nextLine();[/size]
[size=4]			//乙玩游戏[/size]
[size=4]			p2.play();[/size]
[size=4]		}[/size]
[size=4]	}[/size]
[size=4]	//自定义了不同魔法功能特殊地点的位置[/size]
[size=4]	public static void magicMap(){[/size]

[size=4]		int[][] mine = {{0,4},{2,9},{4,20},{6,29},{8,10},{10,17},{12,0},{20,5}};[/size]
[size=4]		int[][] luckplace = {{0,5},{4,10},{8,13},{10,20},{16,16},{18,20},{20,11},{14,15}};[/size]
[size=4]		int[][] back = {{0,7},{2,8},{6,10},{8,7},{10,7},{16,20},{12,8},{14,19}};[/size]
[size=4]		int[][] forword = {{14,7},{16,2},{18,13},{20,26},{10,7},{8,0},{6,20},{20,10}};[/size]
[size=4]		foreach(luckplace,"☆",map);[/size]
[size=4]		foreach(forword,"△",map);[/size]
[size=4]		foreach(back,"▽",map);[/size]
[size=4]		foreach(mine,"○",map);[/size]
[size=4]	}[/size]
[size=4]	//给地图设置特殊地点符号[/size]
[size=4]	public static void foreach (int[][] arr, String symbol, String[][] map) {[/size]
[size=4]		for (int i = 0; i < arr.length; i++) {[/size]
[size=4]			int x = arr[i][0];[/size]
[size=4]			int y = arr[i][1];[/size]
[size=4]			map[x][y] = symbol;[/size]
[size=4]		}[/size]
[size=4]	}[/size]
[size=4]}[/size]



[size=4]

Play类:Player.java
[Java] 纯文本查看 复制代码
public class Player {[/size]
[size=4]	//玩家的姓名[/size]
[size=4]	private String name;[/size]
[size=4]	//玩家在地图中的位置,posX代表玩家所在的列数,posY代表玩家所在的行数.[/size]
[size=4]	public int posX;[/size]
[size=4]	public int posY;[/size]
[size=4]	//定义一个长度为2的数组来存储玩家的位置[/size]
[size=4]	public int[] point = new int[2];[/size]
[size=4]	//一个判断玩家所在位置魔法功能的旗标[/size]
[size=4]	public static String flag;[/size]
[size=4]	public String getName(){[/size]
[size=4]		return name;[/size]
[size=4]	}[/size]
[size=4]	//初始化玩家姓名的构造方法[/size]
[size=4]	public Player(String name){[/size]
[size=4]		this.name = name;[/size]
[size=4]	}[/size]
[size=4]	/**[/size]
[size=4]	玩家玩游戏的方法[/size]
[size=4]	*/[/size]
[size=4]	public void play() throws Exception{[/size]
[size=4]		//随机生成1-6之间的数,模拟掷骰子[/size]
[size=4]		int temp = Dice.getNum();	[/size]
[size=4]		//玩家前进temp步数,并返回前进后位置,此处只算好玩家前进后位置,并没有将玩家移动到该位置[/size]
[size=4]		point = forwordLogic(posX,posY,temp);[/size]
[size=4]		//获得玩家所在列数[/size]
[size=4]		posX = point[0];[/size]
[size=4]		//获得玩家所在行数[/size]
[size=4]		posY = point[1];[/size]
[size=4]		//假如得到自己定义的结束信息,将flag赋值为结[/size]
[size=4]		if(posY == 1 && posX == 1)[/size]
[size=4]		{[/size]
[size=4]			KnightChess.map[1][1] = "结";[/size]
[size=4]			flag = "结";[/size]
[size=4]		}[/size]
[size=4]		//判断玩家是否到达终点,获取玩家所在位置的符号[/size]
[size=4]		else if(posY < 21 && posX < 30){[/size]
[size=4]			flag = KnightChess.map[posY][posX];[/size]
[size=4]		}[/size]
[size=4]		[/size]
[size=4]		//根据前面算出的玩家位置,得到将要到达位置的字符类型,并执行相应的操作,得到最终的地址[/size]
[size=4]		point = magicExecute(posX,posY);[/size]
[size=4]		//获得玩家最终所在列数[/size]
[size=4]		posX = point[0];[/size]
[size=4]		//获得玩家最终所在行数[/size]
[size=4]		posY = point[1];[/size]
[size=4]		//初始化地图,为了消除前面对地图数组赋值产生的改变[/size]
[size=4]		KnightChess.initMap();[/size]
[size=4]		//显示地图[/size]
[size=4]		KnightChess.display();[/size]
[size=4]		//输出掷骰子的结果[/size]
[size=4]		System.out.print(name + "投掷出了数字:" + temp + "\t");[/size]

[size=4]		//通过switch case语句,根据玩家所处位置输出相应的语句[/size]
[size=4]		switch (flag) {[/size]
[size=4]		case "☆":[/size]
[size=4]			System.out.println(name + "搭上火箭了,前进10格!!!!");[/size]
[size=4]			break;[/size]
[size=4]		case "△":[/size]
[size=4]			System.out.println(name + "龙卷风!!前进5格");[/size]
[size=4]			break;[/size]
[size=4]		case "○":[/size]
[size=4]			System.out.println(name + "踩到地雷了,给我直接回到原点!!!!");[/size]
[size=4]			break;[/size]
[size=4]		case "▽":[/size]
[size=4]			System.out.println(name + "脚底打滑,后退5格!!!!");[/size]
[size=4]			break;	[/size]
[size=4]		case "结":[/size]
[size=4]			System.out.println(name + "恭喜你!!赢得了比赛!!");[/size]
[size=4]		default:[/size]
[size=4]			break;	[/size]
[size=4]		}[/size]

[size=4]	}[/size]
[size=4]	/**[/size]
[size=4]	判断所处位置的符号,根据不同符号执行不同的动作[/size]
[size=4]	*/[/size]
[size=4]	public int[] magicExecute(int posX, int posY){[/size]
[size=4]		if(flag == "☆"){[/size]
[size=4]			point = forwordLogic(posX,posY,10);				//前进10格[/size]
[size=4]		}[/size]
[size=4]		if(flag == "△"){[/size]
[size=4]			point = forwordLogic(posX,posY,5);				//前进5格[/size]
[size=4]		}[/size]
[size=4]		if(flag == "○"){[/size]
[size=4]			point = new int[]{0,0};							//回到原点[/size]
[size=4]		}[/size]
[size=4]		if(flag == "▽"){[/size]
[size=4]			point = backLogic(posX,posY);					//后退5格,后退步数方法内写死了[/size]
[size=4]		}[/size]
[size=4]		return point;[/size]
[size=4]	}[/size]
[size=4]	/**[/size]
[size=4]	实现棋子前进的方法[/size]
[size=4]	*/[/size]
[size=4]	public int[] forwordLogic(int posX, int posY, int step){[/size]
[size=4]		[/size]
[size=4]		if(posY % 4 == 0){						//玩家位于第0 4 8 12 16 20行[/size]
[size=4]			if(posX + step < 30){				//玩家前进step步后依然在本行[/size]
[size=4]				posX += step;[/size]
[size=4]			}[/size]
[size=4]			else if(posX + step == 30){			//玩家前进step步后推进1行,刚好位于转弯点[/size]
[size=4]				posX = 29;[/size]
[size=4]				posY += 1;[/size]
[size=4]			}[/size]
[size=4]			else{								//玩家前进step步后推进了2行[/size]
[size=4]				posY += 2;[/size]
[size=4]				posX = 60 - posX - step;[/size]
[size=4]			}[/size]
[size=4]		}[/size]
[size=4]		else if(posY % 4 == 1){					//玩家位于第1 5 9 13 17行,也就是在转折点,所以肯定进入下一行[/size]
[size=4]			posY += 1;[/size]
[size=4]			posX = 30 - step;[/size]

[size=4]		}[/size]
[size=4]		else if(posY % 4 == 2){					//玩家位于第2 6 10 14 18行,前进时列数posX的值减去step[/size]
[size=4]			if(posX - step > -1){				//依然有三种情况,分析和前面相同[/size]
[size=4]				posX -= step;[/size]
[size=4]			}else if(posX - step == -1){[/size]
[size=4]				posY += 1;[/size]
[size=4]				posX = 0;[/size]
[size=4]			}else{[/size]
[size=4]				posY += 2;[/size]
[size=4]				posX = step - posX - 2;[/size]
[size=4]			}[/size]
[size=4]		}[/size]
[size=4]		else if(posY % 4 == 3){					//玩家位于第3 7 11 15 19行,前进后行数一定加1,并且列数posX的变化方向改变[/size]
[size=4]			posY += 1;[/size]
[size=4]			posX = posX + step - 1;[/size]
[size=4]		}[/size]
[size=4]		if(posY < 21 && posX < 30){				//当玩家没有到达终点,返回point数组,存储了玩家位置信息[/size]
[size=4]			point[0] = posX;[/size]
[size=4]			point[1] = posY;		[/size]
[size=4]		}else{									//当玩家到达终点,将玩家的位置设置到点(1,1),并返回数组point[/size]
[size=4]			point[0] = 1;[/size]
[size=4]			point[1] = 1;[/size]
[size=4]		}[/size]
[size=4]		return point;[/size]
[size=4]	}[/size]
[size=4]	/**[/size]
[size=4]	实现棋子后退的方法[/size]
[size=4]	逻辑刚好与前进的相反[/size]
[size=4]	*/[/size]
[size=4]	public int[] backLogic(int posX, int posY){[/size]
[size=4]		int backStep = 5;[/size]
[size=4]		if(posY % 4 == 0){[/size]
[size=4]			if(posX - backStep > -1){[/size]
[size=4]				posX -= backStep;[/size]
[size=4]			}else if(posX - backStep == -1){[/size]
[size=4]				posY -= 1;[/size]
[size=4]				posX = 0;[/size]
[size=4]			}else{[/size]
[size=4]				posY += 2;[/size]
[size=4]				posX = backStep - posX - 2;[/size]
[size=4]			}[/size]
[size=4]		}[/size]
[size=4]		else if(posY % 4 == 1){[/size]
[size=4]			posY += 1;[/size]
[size=4]			posX = posX - backStep + 1;[/size]
[size=4]		}[/size]
[size=4]		else if(posY % 4 == 2){[/size]
[size=4]			if(posX + backStep < 30){[/size]
[size=4]				posX += backStep;[/size]
[size=4]			}else if(posX + backStep == 30){[/size]
[size=4]				posX = 29;[/size]
[size=4]				posY += 1;[/size]
[size=4]			}else{[/size]
[size=4]				posY += 2;[/size]
[size=4]				posX = 60 - posX - backStep; [/size]
[size=4]			}[/size]
[size=4]		}[/size]
[size=4]		else if(posY % 4 == 3){[/size]
[size=4]			posY += 1;[/size]
[size=4]			posX = posX + backStep - 1;[/size]
[size=4]		}[/size]
[size=4]		point[0] = posX;[/size]
[size=4]		point[1] = posY;[/size]
[size=4]		return point;[/size]
[size=4]	}[/size]
[size=4]}[/size]



[size=4]

骰子类:Dice.java
[Java] 纯文本查看 复制代码
/**[/size]
[size=4]1.骰子类,里面方法定义成static当成工具类[/size]
[size=4]2.产生1-6的随机数[/size]
[size=4]*/[/size]
[size=4]public class Dice {[/size]
[size=4]	public static int getNum(){[/size]
[size=4]		return (int)(Math.random() * 6 + 1);[/size]
[size=4]	}[/size]
[size=4]}[/size]
[size=4]

图片.png (83.07 KB, 下载次数: 6)

骑士飞行棋

骑士飞行棋

jansi-1.11.rar

101.32 KB, 下载次数: 50

可以在控制台打印有颜色字符的jar包

骑士飞行棋.rar

8.58 KB, 下载次数: 34

源码

1 个回复

倒序浏览
迷糊
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马