城堡游戏练习

和浙大翁恺老师学习的城堡游戏写法,加入了一些自己的内容,应该会有后续内容的添加。

代码部分

1.主程序

​import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;

public class Game {
    private Room currentRoom;
    private HashMap<String,Handler>handlers=new HashMap<String,Handler>();    
    protected ArrayList<String>cmds=new ArrayList<String>();
    public Game() 
    {
    	handlers.put("go",new HandlerGo(this));//这三句决定了handler在被调用时,不同字符串会调用不同子类对象
        handlers.put("bye",new Handlerbye(this));
        handlers.put("help",new HandlerHelp(this));//这个很厉害
    	createRooms();//构造函数直接完成房间和方向的初始化
    	for(String s:handlers.keySet())
    	{ 
    		cmds.add(s);
    	}
    }
   

      在Game类中定义了Room类对象和两个容器对象,然后编写构造函数,handler对象的主要目的是把输入的字符串命令和调用的类对应起来,对应的几个类会在后面解释。cmds对象的目的是把handler的关键字存入数组,目的是令后面的帮助命令可根据关键字多少输出。

 public void play()
    {
    	Scanner in = new Scanner(System.in);
        while ( true ) {
        		String line = in.nextLine();
        		String[] words = line.split(" ");//以空格分割单词,放入words数组
        		Handler handler=handlers.get(words[0]);//这句决定调用的是handler的哪个子类
        		String value="";
        		if(words.length>1)
        			value=words[1];
        		if ( handler!=null) 
        		{
        			handler.doDmc(value);//不用words1因为可能没有
        		} 
        		if(handler.isbye())//此时内存中是handlerbye的对象
        		{
        			break;
        		}
        }
        System.out.println("感谢您的光临。再见!");
        in.close();
      }

    Game类的play方法是根据用户输入的命令调用handler类的不同子类和函数,这里包含了代表结束的isbye函数和得到输入方向的doDmc函数。这里这样写的好处是如果想添加新的字符串命令,如我们要添加一个return命令,回到上一个房间,就可以在构造函数中把return和handle的对应子类(如handlerreturn)关联起来,然后在play里输入return,调用添加的handler.isreturn函数即可。这里还涉及了子类父类继承和向上造型的知识,后面再说。

    private void createRooms()
    {
        Room outside, lobby, pub, study, bedroom;
      
        //	制造房间
        outside = new Room("城堡外");
        lobby = new Room("大堂");
        pub = new Room("小酒吧");
        study = new Room("书房");
        bedroom = new Room("卧室");//定义不同的房间名,利用toString直接输出对应房间名        
        //	初始化房间的出口
        outside.setExit("east",lobby);
        outside.setExit("south",study);
        outside.setExit("west",pub);
        lobby.setExit("west", outside);
        pub.setExit("east", outside);
        study.setExit("north",outside);
        study.setExit("east",bedroom);
        bedroom.setExit("west", study);//设置每个房间能走通的方向和对应的房间
        lobby.setExit("up",pub);
        pub.setExit("down", lobby);
        currentRoom = outside;  //	从城堡门外开始
        //制造道具
        Item gold,monster,box,exp;
        gold=new Item("金币");
       	monster=new Item("怪物");
        box=new Item("宝箱");
        exp=new Item("经验");
        //把房间和道具对应
        outside.setItem(outside, monster);
       	lobby.setItem(lobby,gold);
       	pub.setItem(pub, box);
       	bedroom.setItem(bedroom, exp);
    }
    

    createRoom方法是在初始化房间和对应的方向出口,调用的是Room类中的setExit函数,可以看出来同样利用了HashMap容器把方向和出口进行关联。下面的道具类(额外写的)同理。这里的代码应该可以继续简化,等我再学学。

//欢迎函数,没必要改
    private void printWelcome() {
        System.out.println();
        System.out.println("欢迎来到城堡!");
        System.out.println("这是一个超级无聊的游戏。");
        System.out.println("如果需要帮助,请输入 'help'。");
        System.out.println();
        showprompt();
    }
    // 以下为用户命令
    //根据输入方向得到下次的房间名
    public void goRoom(String direction)//唯一指定调用函数 
    {
        Room nextRoom = null;
        nextRoom=currentRoom.getExit(direction);
        if (nextRoom == null) {
            System.out.println("那里没有门!");
        }
        else {
            currentRoom = nextRoom;//房间交替
            showprompt();
        Item item=null;
        item=currentRoom.getItem(currentRoom);
        if(item!=null)
        	{
        		System.out.println("你发现了:"+item);
        	}
        else
        	{
        		System.out.println("什么也没有");
        	}
        }
    }
	public void showprompt()
	{
		System.out.println("现在你在" + currentRoom);
		System.out.println("出口有:");
		System.out.print(currentRoom.getExitdesc());
		System.out.println();
	}
	public static void main(String[] args) {
		Game game = new Game();//Game调用Currentroom,初始化房间位置还有最初位置
		game.printWelcome();
		game.play();

	}

}​

    主类中剩的方法都放在这吧,printWelcome方法就是输出各种字符串,没什么好说的,goRoom类则是根据用户输入的方向判断该方向是否有门,有的话将令当前房间为下一个房间,从而实现移动,然后利用item类对象判断当前房间是否有道具(自己额外加的),并输出结果。然后showprompt方法输出当前房间的可用出口。

 2.Room类

import java.util.HashMap;

public class Room {
    private String description;
    private HashMap<String,Room> exist=new HashMap<String,Room>();
	private HashMap<Room,Item>items=new HashMap<Room,Item>();
    public Room(String description) 
    {
        this.description = description;
    }

    public void setExit(String dir,Room room)
    {
    	exist.put(dir,room);
    }
	//设置房间和对应事件
	public void setItem(Room room,Item item)
	{
		items.put(room,item);
	}
    public String getExitdesc()
    {
    	StringBuffer sb=new StringBuffer();
    	for(String s:exist.keySet())
    	{ 
    		sb.append(s);
    		sb.append(" ");
    	}
    		return sb.toString();
    }
	public Item getItem(Room room)
	{
		return items.get(room);
	}
    public Room getExit(String direction)
    {
    	return exist.get(direction);//返回对应方向的房间对象
    }
    @Override
    public String toString()
    {
        return description;
    }
}

    Room类里用的都是HashMap容器的对应,包括我后面加的Item类也是以Room类对象为关键字得到对应房间的物品,这里不解释了(懒得打字了)。

3.Item类

package castle;

public class Item {
	private String description;
	//构造函数
	public Item(String des)
{
	this.description=des;
}
	//toString输出
	public String toString()
	{
		return description;
	}
}

    Item类写的很简单,只包含构造函数和返回字符串的操作,保证和Room类的相同输出方法。

4.Handler类及子类

public class Handler {
	protected Game game;
	public Handler(Game game)
	{
		this.game=game;
	}
	public void doDmc(String string)
	{	
	}
	public boolean isbye()
	{
		
		return false;
	}
}

Handler父类,主要包含的是doDme方法和isbye方法,都是留给子类重写的,先定义好放在这里。至于构造函数包含对game对象的调用,因为Game类里的Goroom方法调用了Game类的私有成员,在不改变权限的前提下,只能先用这个方法。

package castle;

public class HandlerGo extends Handler {
	public HandlerGo(Game game)
	{
		super(game);
	}
	@Override
	public void doDmc(String string) {
	game.goRoom(string);
	}

}
package castle;

public class Handlerbye extends Handler
{
	public Handlerbye(Game game)
	{
		super(game);
	}
	public boolean isbye()
	{
		
		return true;
}
}
package castle;

public class HandlerHelp extends Handler{
public HandlerHelp(Game game)
{
	super(game);
}
	@Override
	public void doDmc(String string) {
        System.out.println("迷路了吗?你可以做的命令有:"+game.cmds);
        System.out.println("如:\tgo east");
	}

}

    这里把Handler的子类都列出来,根据Game类中handlers容器对象把字符串和这几个子类对应起来。

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值