最近在学习后台的一些功能,发现自己的基础不是很牢固,所以想写点小程序,巩固一下以前学的知识,融合一下。
之前在慕课上学的课程中就有一个这样的小程序,写一个简单的文字城堡游戏。当时由于学得很匆忙,所以一直都没做,这次想起这个,于是就想用这个练手了。
首先先说下需求:
1、每个房间都几个出口,然后玩家可以通过go命令去到与这个房间相连的其他房间。
2、房间里有一些物品,玩家可以使用之类的。(此项功能后面再添加,现在先写好接口)
3、每个房间都有自己描述。
再说下思路吧:
设计房间:
因为需要创建很多房间,所以我们可以写一个抽象类,然后让这些所有的房间去继承这个抽象类,然后我们只需要在每个特定的房间中添加自己不同的属性就行了。
然后又考虑到在主程序中不能直接访问实体类,所以我便想写一个接口。
所以各种房间的结构如下:
既然结构出来了,我们就先从顶层开始编写:
首先是接口,我们知道一个房间肯定有出口,还要对当前场景进行叙述。另外我们前面还有个需求是房间里要有物体,虽然不是现在实现,但是我们可以先把功能加上。
所以接口的代码便是:
public interface scene {
//设置出口
public void setExit(String name,scene room);
//获得出口
public String getExit();
//房间中的物体
public void res();
//对当前场景的叙述
public void narration();
}
接下来是抽象类:
抽象类中肯定要把所有房间的所有共性全部写完,所以我们需要在这实现所有房间的基本特性:
对于接口中的四个方法,物体和对场景的叙述是每个房间特有的,所以我们并不会对这两个方法进行细写。
那除此之外的四个方法,还有什么需要补充的么?
我们需要初始化房间的名字。
先设定一个变量用来存放对本房间的名字,然后通过toString的方法进行对房间名字的输出。
需要对当前房间的转换
我们对房间设定了出口,那么到底要怎么移动呢?
可以设定一个hashMap用来存放当前房间紧挨着的其他房间,房间名作为key,而变量就作为value,至于初始化房间的出口我们可以交给实体类自己来进行设计,即方法setExit。
而在对房间进行转换的时候,我们只需要通过传过来的key去寻找那个对应的value,然后将现在的房间替换成value就行了。即:
//取的房间的方向,并转移当前房间
public Room getDirect(String direction){
Room ret=(Room)roomList.get(direction);
return ret;
}
其他的功能基本上实现完了,现在来实现接口的方法:
setExit():
这个方法我们主要交给子类去实现,我们只是在这里写上将数据传入hashMap的方法就行了。
即HashMap.put(name,room)
getExit():
这个方法基本上每个子类都一样,所以我们只需要在父类中编写即可。
这个类的主要功能是将当前房间的的各个出口输出到屏幕上,所以我们只需要遍历一遍HashMap就行了。
res();
下面是具体的抽象类代码:
public abstract class Room implements scene{
private String description;
private HashMap roomList=new HashMap<>();
//房间初始化,输入描述
public Room(String description){
this.description=description;
}
//单个初始化房间的出口
public void setExit(String name,scene room){
roomList.put(name, room);
}
//获得出口
public String getExit(){
StringBuffer s=new StringBuffer();
for(String str:roomList.keySet()){
s.append(str);
s.append(roomList.get(str));
s.append(" ");
}
if(roomList.isEmpty()){
System.out.println("哈哈哈,这里没有出口,等死吧你!!!");
}
return s.toString();
}
//取的房间的方向,并转移当前房间
public Room getDirect(String direction){
Room ret=(Room)roomList.get(direction);
return ret;
}
//输入房间描述
@Override
public String toString(){
return this.description;
}
}
而在子类进行实现的时候,我们便只需要实现所有的接口和将参数在构造的时候传递给父类就行了。
下面就是构造卧室的一个实现类:BedRoom
public class BedRoom extends Room{
public BedRoom() {
super("主卧");
}
@Override
public void res() {
// TODO Auto-generated method stub
}
@Override
public void narration() {
System.out.println("这是最大的卧室,有一张很大的床");
}
}
在正式开始之前,我们需要一个类去初始化所有的房间,所以我们可以创建一个类Initialization,去初始化所有房间和显示欢迎信息以及获取当前所在的房间。代码如下:
public class Initialization {
//初始化当前房间
scene currentRoom;
//显示欢迎信息
public void welcome(){
System.out.println();
System.out.println("欢迎来到城堡!");
System.out.println("这是一个超级无聊的游戏。");
System.out.println("你可以输入'go+方向'去你想去的方向,如go main_bedroom");
System.out.println("你还可以输入'bye'结束游戏");
System.out.println("如果需要帮助,请记住输入 'help'");
}
//设定所有房间
public void setRoom(){
//初始化所有的房间
scene bedroom=new BedRoom();
scene lobby=new Lobby();
scene secBed=new secBedroom();
scene secBal=new secBalcony();
scene thBed=new thBedroom();
scene balcony=new Balcony();
scene bacground=new Background();
//大堂初始化
lobby.setExit("bacground", bacground);
lobby.setExit("thr_bed", thBed);
lobby.setExit("sec_bed", secBed);
lobby.setExit("main_bed", bedroom);
//主卧室初始化
bedroom.setExit("lobby", lobby);
bedroom.setExit("balcony", balcony);
//次卧1初始化
secBed.setExit("lobby", lobby);
secBed.setExit("sec_Bal", secBal);
//次卧2的初始化
thBed.setExit("lobby", lobby);
thBed.setExit("balcony", balcony);
//大阳台的初始化
balcony.setExit("main_bed", bedroom);
balcony.setExit("thr_room", thBed);
//次卧1的阳台初始化
secBal.setExit("bacground", bacground);
//设定起始房间
currentRoom=bedroom;
}
//获得当前房间
public scene getCurrentRoom(){
return currentRoom;
}
}
下面就可以写主类了,我们主要需要编写
首先,游戏的初始化,我们在构造函数里面编写,当此类被创建时就直接初始化游戏
Initialization init=new Initialization();
init.setRoom();
init.welcome();
currentRoom=init.getCurrentRoom();
然后是输出房间的出口,这只需要调用类当中的getExit();方法就行了,这里就不再叙述。
最后是转移房间,在父类中,我们写了getDirect这个方法,去返回一个Room类型的变量,如果这个房间为空,就表示此房间不存在,所以我们直接输出不存在。而如果这个变量不为空,就表示这个房间存在,于是就将当前房间转变为下一个传递回来的房间变量。
最后一步,在Main函数中编写一个循环便可以开始游戏。
主类中的代码具体如下:
public class Game {
//初始化当前房间
private scene currentRoom;
//游戏初始化
public Game(){
Initialization init=new Initialization();
init.setRoom();
init.welcome();
currentRoom=init.getCurrentRoom();
printRoom();
}
//输出当前房间的出口
private void printRoom(){
System.out.println("\n-----------------------------------------------");
System.out.println("现在你在 "+currentRoom);
System.out.println();
currentRoom.narration();
System.out.println("\n出口有:");
System.out.println(currentRoom.getExit());
}
//输出帮助命令
private void printHelp() {
System.out.println("\n迷路了吗?你可以做的命令有:go bye help");
System.out.println("如要去某个方向:\tgo main_bedroom\n");
}
//转移房间
public void goRoom(String direction){
Room nextRoom=((Room) currentRoom).getDirect(direction);
if(nextRoom==null){
System.out.println("这里没有这个房间!!!");
printRoom();
}else{
currentRoom=nextRoom;
}
printRoom();
}
public static void main(String[] args) {
Game game=new Game();
Scanner in=new Scanner(System.in);
//开始游戏
while(true){
String line=in.nextLine();
String[] command=line.split(" ");
if(command[0].equals("help")){
game.printHelp();
}else if(command[0].equals("go")){
game.goRoom(command[1]);
}else if(command[0].equals("bye")){
System.out.println("感谢使用...");
System.exit(0);
}
}
}
}
以上便是这个游戏所有的代码。因为本身也只是作为一个练习来进行制作的,所以在很多地方都有不足,例如:初始化房间。初始化太麻烦了,不是很方便。
再加上只是做个一个框架出来,需要修改的地方太多太多。如果有哪位同仁想提点意见或者是有其他见解,随时欢迎提出来,彼此学习。