我决定创建一个帐户,以便提出一个我似乎无法弄清楚自己的问题,或通过一些谷歌搜索,希望我没有忽略它。
基本上我正在尝试用Java创建一个文本冒险游戏,并且在看到我应该如何将对象的概念联系起来时遇到一些麻烦。我已成功使用XML stax并将文件发送到程序,并使用属性和不使用属性,使用户可以输入与选项关联的整数,并查看选项是否需要"项目&# 34;或给他们一个项目。然而,我没有对此采取OOP。
我希望我的新程序能够接受一串用户输入,而不是只有一个整数,并且如果它存在则检查数组列表。这更接近大多数人可能熟悉的经典MUD。
我想以模块化的方式设计它,所以我可以慢慢添加想法,并且更加复杂,所以我不想要#34;它很有效,所以让我们独自一人# 34;接近。
目前我只想要接近这个:
一个Room对象,它具有:ID,描述和可交互 一个选择对象(这个我不确定)我想要制作一个对象来保持每个房间可能的选择,既可以退出,也可以用于互动 -
如果是这样,房间对象可能需要一个选择对象。
我已经考虑过了,尝试了一些代码,再考虑一遍,每次,我都会比我认为的更多地编写硬编码,并且制作比我认为必要更多的变量,让我觉得我错过了一些至关重要的想法。
我还希望通过输入的文件创建这些房间,而不是在代码中生成(所以基本上代码是任何类型的故事读者/工匠,而不是一个)
我也一直在尝试这个问题,而且我的解决方案正在变得更糟,但下面是我最近尝试的一个粗略的想法:
一个GameManager类,它接受userInput并在传递之前对其进行检查。我没有传递任何数据,因为我不确定这种方法。我也不习惯正则表达式,所以其中一些可能也是错的,如果是的话,或许可以指出来,但这不是我的重点
import java.util.Scanner;
public class GameManager {
private static final String EXIT_PHRASE = "exit";
public static void main(String[] args) {
Scanner userInput = new Scanner(System.in);
String userStringVal = "";
while(!userStringVal.equals(EXIT_PHRASE)){
userStringVal= userInput.nextLine();
if(checkKeywords(userStringVal)){
System.out.println("matches keyword");
}
else System.out.println("didnt match a keyword");
}
userInput.close();
}
public static boolean checkKeywords(String string){
boolean isKeyword = false;
string.toLowerCase();
if(string.matches("travel.*") || string.matches("search.*")){
System.out.println("passed first check");
String substring = string.substring(6);
if(matchDirection(substring)){
isKeyword = true;
}
}
return isKeyword;
}
public static boolean matchDirection(String string){
boolean hasDirection = false;
if(string.matches(".*\\bnorth|south|east|west|northeast|northwest|southeast| southwest|up|down")){
hasDirection = true;
}
return hasDirection;
}
}
我想到的Room对象:
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
public class Room {
private String roomDescription = "";
private int roomID=0;
private int northExit=0;
private int southExit=0;
private int eastExit=0;
private int westExit=0;
private int northeastExit=0;
private int northwestExit=0;
private int southeastExit=0;
private int southwestExit=0;
private int upExit=0;
private int downExit=0;
private String[] interactables = new String[10];
private Options options = new Options();
public Room(XMLStreamReader reader) throws XMLStreamException{
setAttValues(reader);
setRoomDescription(reader);
setUpOptions();
}
public void setinteractables(XMLStreamReader reader){
int count = reader.getAttributeCount();
for(int i = 0; i < count; i++){
interactables[i] = reader.getAttributeValue(i);
}
}
public void setAttValues(XMLStreamReader reader){
int count = reader.getAttributeCount();
for(int i = 0; i < count; i++){
String att = reader.getAttributeLocalName(i);
if(att !=""){
switch(att){
case "North": northExit=Integer.parseInt(att);
case "South": southExit=Integer.parseInt(att);
case "East": eastExit=Integer.parseInt(att);
case "West": westExit=Integer.parseInt(att);
case "NorthEast": northeastExit=Integer.parseInt(att);
case "NorthWest": northwestExit=Integer.parseInt(att);
case "SouthEast": southeastExit=Integer.parseInt(att);
case "SouthWest": southwestExit=Integer.parseInt(att);
case "Up": upExit=Integer.parseInt(att);
case "Down": downExit=Integer.parseInt(att);
case "ID": roomID=Integer.parseInt(att);
}
}
}
}
public void setRoomDescription(XMLStreamReader reader) throws XMLStreamException{
roomDescription = reader.getElementText();
}
public void setUpOptions(){
options.setCardinalPointers(northExit, southExit, eastExit, westExit);
options.setIntercardinalPointers(northeastExit, northwestExit, southeastExit, southwestExit);
options.setElevationPointers(upExit, downExit);
}
}
我该怎样做才能确保我不必用如此多的变量来说明这么多方向?
这里有一个我想到的Option类的快速而粗略的概念,但我还没有完成决定我已经走错了方向
public class Options {
private int northPointer = 0;
private int southPointer= 0;
private int eastPointer = 0;
private int westPointer = 0;
private int northeastPointer= 0;
private int northwestPointer = 0;
private int southeastPointer = 0;
private int southwestPointer = 0;
private int upPointer = 0;
private int downPointer = 0;
private String northInteractable = "";
private String southInteractable = "";
private String eastInteractable = "";
private String westInteractable = "";
private String northeastInteractable ="";
private String northwestInteractable = "";
private String southeastInteractable = "";
private String southwestInteractable = "";
private String upInteractable = "";
private String downInteractable = "";
public Options(){
}
public void setCardinalPointers(int north, int south, int east, int west){
northPointer = north;
southPointer = south;
eastPointer = east;
westPointer = west;
}
public void setIntercardinalPointers(int northeast, int northwest, int southeast, int southwest){
northeastPointer = northeast;
northwestPointer=northwest;
southeastPointer=southeast;
southwestPointer=southwest;
}
public void setElevationPointers(int up, int down){
upPointer = up;
downPointer = down;
}
public String whatToReturn(String string){
String importantPart = "";
if(string.matches("travel.*")){
String substring = string.substring(6);
}
else {
importantPart = "Interactable";
String substring = string.substring(6);
if (substring.matches("\\bnorth\\b")) {
if(northInteractable!=0){
}
}
else if (substring.matches("\\bsouth\\b"))
else if (substring.matches("\\beast\\b"))
else if (substring.matches("\\bwest\\b"))
else if (substring.contains("northeast"))
else if (substring.contains("northwest"))
else if (substring.contains("southeast"))
else if (substring.contains("southwest"))
else if (substring.contains("up"))
else if (substring.contains("down"))
}
return importantPart;
}
}
直到我输入这个之后我才看到冒险标签,所以我将开始在那里进行阅读,但仍会发布这个,所以我很抱歉,如果有一个很好的答案,我还没有找到它。 / p>
作为一个回顾:将几个对象关联起来创建房间对象(从文件中获取信息(XML是我习惯使用的))的好方法是具有退出,描述和交互。用户与这些基于关键字的关键词进行交互,这些关键词可以自由输入,而不仅限于数组保存关键词的索引值。
我在思考用户输入的内容如何&#34;向北旅行&#34;首先检查他们是否键入了关键字,在这种情况下是旅行,然后是方向。然后一些其他人检查它是否说明旅行,向北检查可能是北出口房间可能有也可能没有。然后,如果它的另一个关键字,比如检查,使其变得容易也有完全相同的方向,但检查不同的字符串。
然后,如果房间&#34; northExit&#34;存在,以某种方式获得一个选项,指向另一个roomID。虽然这个思考过程在考虑将来需要物品进入下一个房间的可能性时会引起我的问题。此外,存储/获取这些选项的位置也会造成一些困难。
答案 0 :(得分:0)
我想向您介绍两件事。第一个是enum
。您可以将此视为一种特殊类,其中所有可能的选项都是在类定义中使用 enum 。对于像你这样的方向来说,这非常适合。枚举可以很简单,只需列出所有可能的选项,以便在其他类中使用:
public enum Direction {
NORTH, NORTH_EAST, EAST, SOUTH_EAST, SOUTH, SOUTH_WEST, WEST, NOTH_WEST;
}
如果您希望它们拥有自己的方法和属性,它们可能会更复杂一些:
public enum Direction {
NORTH(true), NORTH_EAST(false), EAST(true), SOUTH_EAST(false), SOUTH(true), SOUTH_WEST(false), WEST(true), NOTH_WEST(false);
private final boolean isCardinal;
private Direction(boolean isCardinal){
this.isCardinal = isCardinal;
}
public boolean isCardinal(){
return isCardinal;
}
public static Collection<Direction> getCardinalDirections(){
return Arrays.asList(Direction.values()).stream().filter(Direction::isCardinal).collect(Collectors.toList());
}
public static Collection<Direction> getIncardinalDirections(){
return Arrays.asList(Direction.values()).stream().filter(x -> !x.isCardinal()).collect(Collectors.toList());
}
}
请详细了解Java enum
类型here。
我想向您介绍的第二件事是称为Map
的数据结构。地图也称为词典,通常可以帮助理解它们的工作方式。地图将采用一个对象并将地图发送到另一个对象,例如字典如何将单词映射到其定义,或者电话簿将人名称映射到他们的电话号码。我们可以使用Room
简化您的Map
课程。我不会重现您的所有代码,因为我现在专注于您的Room
存在:
public class Room {
private Map<Direction, Room> exits;
public Room(){
this.exits = new HashMap<>();
}
public void setExit(Direction direction, Room room){
this.exits.put(direction, room);
}
public Room getExit(Direction direction){
return this.exits.get(direction);
}
}
请阅读有关Java Map
界面here的更多信息。
当然,您需要调整从XML等中读取的方法。但是,现在,您的Room
类应该大大简化。
我希望这能为你指明一个有用的方向。