我正在制作一个简单的基于文本的游戏。我的类中有一个方法引用同一个类中的另一个方法,但是如果满足某个条件,该方法引用引用它的方法。
所以基本上如果角色选择打开菜单,则会调用Character.mainMenu()方法,并根据所选内容引用Character.invMenu()或Character.statsMenu()。
如果用户选择从mainMenu()中选择Back,则调用另一个名为backSetter()的方法。此方法获取当前的x和y坐标并返回位置ID,以将用户返回到打开菜单的任何位置。
在子菜单方法(mainMenu()方法调用的方法)中,例如invMenu(),还有返回的选项:1。返回和2.主页。 Back选项将用户返回到主菜单,主菜单调用mainMenu()方法。 Home选项将用户返回到打开菜单的位置,调用backSetter()方法。但问题是,如果我从invMenu()方法调用这些方法,它们似乎什么都不做,我的程序冻结了。
这是我的Character类的基本模板(这里引用的其他类是MainClass,它包含setLocation()方法和引用gameText()方法的GameText类。)
class Character{
static Scanner userInput = new Scanner();
static String choice;
static int backChoice = 0;
public static void backSetter(){
if (xAxis == 0 && yAxis == 0){
backChoice = MainClass.setLocation(0,0);
GameText.gameText(backChoice);
}else if (xAxis == 0 && yAxis == 1){
.....
}
}
public static void mainMenu(){
//My menu options: 1. Inventory, 2. Stats, etc... 5. BACK <- important
choice = userInput.next();
if (choice.equals("1")){
invMenu();
}else if (choice.equals("5")){
backSetter();
}
public static void invMenu(){
// Determines current items in inventory and prints them out
//My menu options: 1. Back, 2. Home <- where the problem happens
choice = userInput.next();
if (choice.equals("1")){
mainMenu();
}else if (choice.equals("2")){
backSetter();
}
}
}
答案 0 :(得分:1)
是的,这是合法的 - 这就是方法recursive的含义。确保你没有无限递归的情况,即确保你的方法最终停止相互调用 - 如果递归最终终止,那么你就好了。
答案 1 :(得分:0)
是的,这几乎就是递归的一个例子。它不会产生任何错误。 但是,因为它是递归的,如果它们无法进入基本情况状态,它可能会导致无限循环。 在这样的情况下,方法相互调用并且乍一看递归不明显,无限循环的可能性更大。
以某种方式隔离该递归可能并不是一个坏主意,因此它更加明显,使代码更清晰,更易于维护。
答案 2 :(得分:0)
是的,这是合法的,但设计相当糟糕。递归菜单调用会让你遇到麻烦。我觉得好像返回会更好,但我不知道这段代码的上下文。
public static void invMenu(){
// Determines current items in inventory and prints them out
//My menu options: 1. Back, 2. Home <- where the problem happens
choice = userInput.next();
if (choice.equals("1")){
return;
}else if (choice.equals("2")){
backSetter();
}
}
如果您要这样做,则需要调整主菜单的代码来处理返回(即某种循环)。
答案 3 :(得分:0)
感谢您的帮助,我认为这可能会导致无限循环。是的,没有完整的代码,很难发现我哪里出错了。我想把它添加为评论,但是字符太多,所以我把它添加为答案。
我一直在看我的方法,我看不出它是如何陷入无限循环的。调用Method2的Method1必须在确定要执行的操作之前接受用户输入。因此,如果Methpd1调用Method2,它再次调用Method1,为什么它会卡住,因为用户可以选择在任一方法中返回正常游戏。这是我的方法,也许完全可以看出我出错的地方。
FantasyGameText.gameText方法只接受locID并输出该位置的对话选项。 FantasyGameText.setLocation方法是设置位置ID的实际方法,backSetter方法只是将它与gameText方法结合起来(基本上与我开始游戏的方式相同,xAxis = 0,yAxis = 0,所以locId = 0,这是我游戏的开始部分。)
public static void backSetter(){
if (xAxis == 2 && yAxis == 1){
backChoice = setLocation(2, 1);
FantasyGameText.gameText(backChoice);
}else if (xAxis == 4 && yAxis == 1){
backChoice = setLocation(4, 1);
FantasyGameText.gameText(backChoice);
}else if (xAxis == 2 && yAxis == 2){
backChoice = setLocation(2, 2);
FantasyGameText.gameText(backChoice);
}else if (xAxis == 3 && yAxis == 2){
backChoice = setLocation(3, 3);
FantasyGameText.gameText(backChoice);
}else if (xAxis == 4 && yAxis == 2){
backChoice = setLocation(4, 2);
FantasyGameText.gameText(backChoice);
}else if (xAxis == 5 && yAxis == 2){
backChoice = setLocation(5, 2);
FantasyGameText.gameText(backChoice);
}else if (xAxis == 1 && yAxis == 3){
backChoice = setLocation(1, 3);
FantasyGameText.gameText(backChoice);
}else if (xAxis == 2 && yAxis == 3){
backChoice = setLocation(2, 3);
FantasyGameText.gameText(backChoice);
}else if (xAxis == 3 && yAxis == 3){
backChoice = setLocation(3, 3);
FantasyGameText.gameText(backChoice);
}else if (xAxis == 4 && yAxis == 3){
backChoice = setLocation(4, 3);
FantasyGameText.gameText(backChoice);
}else if (xAxis == 2 && yAxis == 4){
backChoice = setLocation(2, 4);
FantasyGameText.gameText(backChoice);
}else if (xAxis == 3 && yAxis == 4){
backChoice = setLocation(3, 4);
FantasyGameText.gameText(backChoice);
}else if (xAxis == 4 && yAxis == 4){
backChoice = setLocation(4, 4);
FantasyGameText.gameText(backChoice);
}else if (xAxis == 5 && yAxis == 4){
backChoice = setLocation(5, 4);
FantasyGameText.gameText(backChoice);
}else if (xAxis == 3 && yAxis == 5){
backChoice = setLocation(3, 5);
FantasyGameText.gameText(backChoice);
}else if (xAxis == 4 && yAxis == 5){
backChoice = setLocation (4, 5);
FantasyGameText.gameText(backChoice);
}else if (xAxis == 30 && yAxis == 30){
backChoice = setLocation(30, 30);
FantasyGameText.gameText(backChoice);
}else if (xAxis == 31 && yAxis == 31){
backChoice = setLocation(31, 31);
FantasyGameText.gameText(backChoice);
}else if (xAxis == 50 && yAxis == 50){
backChoice = setLocation(50, 50);
FantasyGameText.gameText(backChoice);
}else if (xAxis == 51 && yAxis == 51){
backChoice = setLocation(51, 51);
FantasyGameText.gameText(backChoice);
}else if (xAxis == 52 && yAxis == 52){
backChoice = setLocation(52, 52);
FantasyGameText.gameText(backChoice);
}else if (xAxis == 53 && yAxis == 53){
backChoice = setLocation(53, 53);
FantasyGameText.gameText(backChoice);
}else if (xAxis == 54 && yAxis == 54){
backChoice = setLocation(54, 54);
FantasyGameText.gameText(backChoice);
}else if (xAxis == 55 & yAxis == 55){
backChoice = setLocation(55, 55);
FantasyGameText.gameText(backChoice);
}else{
FantasyGameText.gameText(100);
}
}
public static void menuHome(){
boolean correctAnswer = false;
System.out.println("");
System.out.println("-------- CHARACTER --------");
System.out.println("1. Inventory");
System.out.println("2. Equip");
System.out.println("3. Stats");
System.out.println("4. Quests");
System.out.println("5. Back");
while (correctAnswer == false){
menuChoice = userInput.next();
System.out.println("");
if (menuChoice.equals("1") || menuChoice.equalsIgnoreCase("inventory") || menuChoice.equalsIgnoreCase("inv")){
correctAnswer = true;
invMenu();
}else if (menuChoice.equals("2") || menuChoice.equalsIgnoreCase("equip")){
correctAnswer = true;
equipMenu();
}else if (menuChoice.equals("3") || menuChoice.equalsIgnoreCase("stats") || menuChoice.equalsIgnoreCase("statistics")){
correctAnswer = true;
statsMenu();
}else if (menuChoice.equals("4") || menuChoice.equalsIgnoreCase("quests") || menuChoice.equalsIgnoreCase("quest")){
correctAnswer = true;
questMenu();
}else if (menuChoice.equals("5") || menuChoice.equalsIgnoreCase("back") || menuChoice.equalsIgnoreCase("home")){
correctAnswer = true;
backSetter();
}else{
System.out.println("That is not a valid option, choose again,");
menuChoice = userInput.next();
System.out.println("");
}
}
return;
}
public static void invMenu(){
boolean correctAnswer = false;
int invList[] = new int[50];
int itemAmount[] = new int[50];
for (int i = 0; i <= 3; i++){
if (healthPotionAmount > 0){
invList[0] = 1;
itemTempName[0] = "Health Potion x ";
itemAmount[0] = healthPotionAmount;
}else{
invList[0] = 0;
}
if (rustySwordAmount > 0){
invList[1] = 1;
itemTempName[1] = "Rusty Sword x ";
itemAmount[1] = rustySwordAmount;
}else{
invList[1] = 0;
}
if (ragsBodyAmount > 0){
invList[2] = 1;
itemTempName[2] = "Rags x ";
itemAmount[2] = ragsBodyAmount;
}else{
invList[2] = 0;
}
if (chainBodyAmount > 0){
invList[3] = 1;
itemTempName[3] = "Chainmail Armor x ";
itemAmount[3] = chainBodyAmount;
}else{
invList[3] = 0;
}
}
for (int i = 0; i <= 3; i++){
if (invList[i] > 0){
System.out.println(itemTempName[i] + itemAmount[i]);
}else if (invList[0] == 0 && invList[1] == 0 && invList[2] == 0 && invList[3] == 0){
System.out.println("You have no items.");
}
}
System.out.println("");
System.out.println("1. Back");
System.out.println("2. Home");
menuChoice = userInput.next();
System.out.println("");
while (correctAnswer == false);
if (menuChoice.equals("1") || menuChoice.equalsIgnoreCase("back") || menuChoice.equalsIgnoreCase("b")){
correctAnswer = true;
menuHome();
}else if (menuChoice.equals("2") || menuChoice.equalsIgnoreCase("home") || menuChoice.equalsIgnoreCase("h")){
correctAnswer = true;
backSetter();
}else{
System.out.println("That is not a valid option, choose again.");
menuChoice = userInput.next();
System.out.println("");
}
}