以前有看过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] |