城堡游戏的任意门。实现过程很简单,但是我想了一天,操作步骤就是扩展一个Handler类,在Game类里面加一个函数,在Handler里面调用。其实怎么加上去的不重要,重要的是,读懂函数与函数之间的关系,这个代码关系非常复杂,要看关系图才能看懂。这个关系图只能在纸上写,如果不想画关系图,另一个看懂代码的办法就是把每一行都写上注释。
三个主类:
game类:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;
public class Game {
//定义变量
private Room currentRoom;//当前房间,默认为null
private HashMap<String, Handler> handlers=new HashMap<String, Handler>();//用来储存命令的哈希表
ArrayList<Room> rooms = new ArrayList<Room>();//用ArrarList储存创建的进去的房间
//构造函数
public Game()
{
//向命令行里添加元素,key是命令,value是继承Handler的子类
handlers.put("go",new HandlerGo(this));
handlers.put("bye", new HandlerBye(this));
handlers.put("help", new HandlerHelp(this));
handlers.put("random", new HandlerRandom(this));//这里的this可以看做是Game的一个对象
createRooms();//创建对象的时候构造房间
}
//制造房间函数
private void createRooms()
{
//写这个方便复制粘贴
String[] dir= {"north","east","south","west"};
// 制造房间
Room outside, lobby, pub, study, bedroom;
outside = new Room("城堡外");
lobby = new Room("大堂");
pub = new Room("小酒吧");
study = new Room("书房");
bedroom = new Room("卧室");
// 初始化房间的出口
outside.setExit(dir[1], lobby);
outside.setExit(dir[2], study);
outside.setExit(dir[3], pub);
pub.setExit(dir[1], outside);
lobby.setExit(dir[3], outside);
study.setExit(dir[0], outside);
study.setExit(dir[1], bedroom);
bedroom.setExit(dir[3], study);
//把创建的房间加入容器rooms
rooms.add(lobby);
rooms.add(study);
rooms.add(pub);
rooms.add(outside);
rooms.add(bedroom);
//当前位置
currentRoom=outside;
}
//任意门1,一个房间的四个门,每次进入到随机的门
public void goRandom()
{
String[] dir= {"north","east","south","west"};//定义四个方向
int a=(int)(Math.random()*4);//产生随机数0~3
Room nextRoom=currentRoom.getExit(dir[a]);//随机传入一个方向
if (nextRoom == null) {
System.out.println("那里没有门!");
}
else {
currentRoom = nextRoom;
showPrompt();
}
}
//任意门2,从outside出发,每次进入到一个随机房间
// public void goRandom()
// {
// int a=(int) (Math.random()*5);//产生随机数0~4
// currentRoom = rooms.get(a);//进入任意一个房间
// showPrompt();
// }
private void printWelcome() {
System.out.println();
System.out.println("欢迎来到城堡!");
System.out.println("这是一个超级无聊的游戏。");
System.out.println("如果需要帮助,请输入 'help' 。");
System.out.println();
showPrompt();
}
// 进入房间
protected void goRoom(String direction)
{
Room nextRoom=currentRoom.getExit(direction);//获取输入的方向
if (nextRoom == null) {
System.out.println("那里没有门!");
}
else {
currentRoom = nextRoom;
showPrompt();
}
}
//提示信息
public void showPrompt()
{
System.out.println("你在" + currentRoom);
System.out.print("出口有: ");
System.out.print(currentRoom.getExitDesc());
System.out.println();
}
//运行主程序,最主要的程序,读懂这段代码对理解整个程序事半功倍
public void play() {
Scanner in = new Scanner(System.in);
while ( true ) {
String line = in.nextLine();
String[] words = line.split(" ");//以空格为间隔,返回字符数组
Handler handler=handlers.get(words[0]);//根据当前输入判断让handler管理哪个Handler对象
String value="";
if(words.length>1)//如果不只是一个单词,value等于输入的方向
{
value=words[1];
}
// else//增加的判断,为了适应任意门
// {
// value=words[0];
// }
if(handler!=null)
{
handler.doCmd(value);//根据管理的类,调用相应的函数
if(handler.isBye())//管理了HandlerBye的对象,调用isBye()函数
{
break;//跳出循环
}
}
}
in.close();
}
public static void main(String[] args) {
Game game = new Game();
game.printWelcome();
game.play();//这里是程序运行的核心,出问题要在这里找
System.out.println("感谢您的光临。再见!");
}
}
Room类
import java.util.HashMap;
public class Room {
private String description;
private HashMap<String, Room> exits=new HashMap<String, Room>();
//构造函数,初始化房间位置描述
public Room(String description)
{
this.description = description;
}
//设置方向函数
public void setExit(String dir,Room room) {
exits.put(dir, room);//利用函数向容器里面添加key(方向)和value(房间)
}
//获取当前房间的出口方向
public String getExitDesc()
{
StringBuffer sb=new StringBuffer();
for(String dir:exits.keySet())
{
sb.append(dir);//append方法,将后面的字符加入到该对象里面
sb.append(" ");
}
return sb.toString();
}
//传入一个方向,获取对应的房间
public Room getExit(String direction)
{
Room ret=null;
ret=exits.get(direction);
return ret;
}
//来自Object类的函数,输出对象的时候,输出该对象的返回值
@Override
public String toString()
{
return description;
}
}
Handle类
//命令类
public class Handler {
public Game game;
public Handler(Game game)
{
this.game=game;//初始化的时候构造一个Game对象,传给子类,用于调用Game的函数
}
public void doCmd(String word)//让子类重写该方法
{
}
public boolean isBye() {//HandlerBye的判断条件
return false;
}
}
四个子类:
//离开命令
public class HandlerBye extends Handler {
public HandlerBye(Game game) {
super(game);
// TODO Auto-generated constructor stub
}
public boolean isBye()
{
return true;
}
}
//进入房间命令
public class HandlerGo extends Handler {
public HandlerGo(Game game) {
super(game);
}
public void doCmd(String word) {
game.goRoom(word);
}
}
//帮助命令
public class HandlerHelp extends Handler {
public HandlerHelp(Game game) {
super(game);
// TODO Auto-generated constructor stub
}
public void doCmd(String word)
{
System.out.println("迷路了吗?你可以做的命令有:go bye help random");
System.out.println("如:\tgo east");
}
}
//进入随机的房间,任意门命令
public class HandlerRandom extends Handler {
public HandlerRandom(Game game) {
super(game);
// TODO Auto-generated constructor stub
}
@Override
public void doCmd(String word) {
// TODO Auto-generated method stub
game.goRandom();
}
}
代码看不懂,一定要多看几遍课程,第一次听得时候晕晕乎乎的。