I am making a game, and I can't seem to exit the doLoop();
method from within the options();
method. here is my code:
package classes;
import classes.attackRelated.Attack;
import classes.attackRelated.AttackEffect;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Random;
import java.util.Scanner;
public class GameLoop {
public int scene=0;
public boolean quit=false;
public ArrayList<BattleMach> machStorage =new ArrayList<>();
public ArrayList<BattleMach> team=new ArrayList<>();
transient public String []types=new String[]{"Water","Electric","Fire","Tech","Steel","Energy"};
transient public float[][]typeWeak=new float[][]{
{1,2,0.5f,1,1,1},
{0.5f,0.5f,2,1,0.5f,2},
{2,1,0.5f,1,0.5f,1.5f},
{1,1,1,1,1,1},//tech type is only for attacks; it's to power up/down user/target
{1.5f,2,1,1,0.5f,1},
{1,1,1,1,1,1}//energy type
};
transient Scanner scan=new Scanner(System.in);
transient Random rand=new Random();
public void addMach(BattleMach toAdd){
if (5 > team.size())//5 is max team size
team.add(toAdd);
else
machStorage.add(toAdd);
}
public String name;
public String rival;
public boolean arrayContain(Object[]arr,Object put){
for (Object i:arr) {
if (i.equals(put))
return true;
}
return false;
}
public void options() {//this is called when user inputs 'o'
print("""
You are in the options screen.""");
String put=askO(new String[]{"1","2","3"}, """
1 - Save game
2 - Save and quit
3 - Set text speed
""");
switch (put){
case "1":{
return;
}
}
}
/**this method replaces {@code ask} when user is in options (only in the {@code options} method)
*
* @param wanted the correct user input array
* @param print the prompt to ask
* @return the first correct user input
*/
public String askO(String [] wanted,String print) {
while (true){
print(print);String out=scan.nextLine().toLowerCase();
if(arrayContain(wanted,out))
return out;
if(out.equals("o"))
print("You are already in the options screen!");
print();
}
}
public String ask(String [] wanted,String print) {
while (true){
print(print);String out=scan.nextLine().toLowerCase();
if(arrayContain(wanted,out))
return out;
if(out.equals("o"))
options();
print();
}
}
float delay=1f/35f;
public static void pause(int ms)
{
try
{
Thread.sleep(ms);
}
catch(InterruptedException ex)
{
Thread.currentThread().interrupt();
}
}
public void print(String toPrint,float delay){
for (char i:toPrint.toCharArray()) {
System.out.print(i);
pause((int) (1000*delay));
}
System.out.println();
}
public void print(String toPrint){
for (char i:toPrint.toCharArray()) {
System.out.print(i);
pause((int) (1000*delay));
}
System.out.println();
}
public void print(){
System.out.println();
}
public void doLoop() {//THIS IS THE GAME LOOP NOT MAIN METHOD
// print("""
// hello my name is summed. how are you???
// dodo do this and that then print all of this including this and this""", 1f /30f);
while (true){
switch (scene) {
case 0:{//beginning of story
nameLabel: while (true) {
print("Enter your name:");
name = scan.nextLine();
while (true) {
String yn = ask(new String[]{"yes","no"},"Are you sure that you want " + name + " to be your name? (Enter yes or no):");
if (yn.equalsIgnoreCase("yes"))
break nameLabel;
else if (yn.equalsIgnoreCase("no")) {
break;
}
print();
}
}
rivalLabel:
while(true){
print("Enter your rival & brother's name:");
rival=scan.nextLine();
while (true){
String yn = ask(new String[]{"yes","no"},"Are you sure that you want " + rival + " to be your rival & brother's name? (Enter yes or no):");
if (yn.equalsIgnoreCase("yes"))
break rivalLabel;
else if (yn.equalsIgnoreCase("no")) {
break ;
}print();
}
}//got name
start:
while (true){
print("""
Choose starter Mach type
1. Water
2. Electric
3. Fire
4. Steel
5. Neutral:""");
int machType=scan.nextInt();
switch (machType){
case 1:
addMach(new BattleMach(0,new Attack[]{new Attack(0,30,1,
new AttackEffect(0,0,0,
0,0,0,0,0,0))},new int[]{40,40,40,40},null));
break start;
case 2:
addMach(new BattleMach(1,new Attack[]{new Attack(1,30,1,
new AttackEffect(0,0,0,
0,0,0,0,0,0))},new int[]{40,40,40,40},null));break start;
case 3:
addMach(new BattleMach(2,/*attacks*/new Attack[]{new Attack(2,30,1,
new AttackEffect(0,0,0,
0,0,0,0,0,0))},new int[]{40,40,40,40},null));break start;
case 4:
addMach(new BattleMach(4,new Attack[]{new Attack(4,30,1,
new AttackEffect(0,0,0,
0,0,0,0,0,0))},new int[]{40,40,40,40},null));break start;
case 5:
addMach(new BattleMach(5,new Attack[]{new Attack(5,30,1,
new AttackEffect(0,0,0,
0,0,0,0,0,0))},new int[]{40,40,40,40},null));break start;
}}//end of switch and got starter
//rival has neutral mach
print("You got the "+types[team.getFirst().type]+" mach!\n" +
"You need to name your new mach!");
while (true) {
print("What will you call your mach?:");
team.getFirst().name = scan.nextLine();
String x=ask(new String[]{"yes","no"},"Are you sure that you want "+team.getFirst().name+" to be your mach's name?");
if(Objects.equals(x, "yes"))
break;
}
}
}
}
}
}
and
package classes;
import classes.data.DataLoader;
import classes.data.DataSaver;
import java.util.Scanner;
public class Main {
public static GameLoop loop;
public static void main(String []args) {//THE GAME LOOP IS IN loop AS doLoop(); NOT THIS
DataSaver saver=new DataSaver();
Scanner scan=new Scanner(System.in);
System.out.println("""
BattleMachs!
1. New game
2. Load game
Enter your choice:""");
byte titleChoice=scan.nextByte();
DataLoader loader=new DataLoader();
if (titleChoice==1){
loop=new GameLoop();
} else if (titleChoice == 2) {
System.out.println("Enter save code:");
loop=loader.loadGame(scan.next());
}
System.out.println("Press 'O' for options\n");
boolean q=false;
while (true){
loop.doLoop();//this method ends when user wants to save or/and quit
System.out.println("Copy line below (it is a save code):");
if (loop.quit){
loop.quit=false;
q=true;}
System.out.println(saver.saveGame(loop)+"\n\n\n");
if(q)
System.exit(0);
}
}
}
and the other classes are not needed here
i tried to put a label before the doLoop();
method as loop:
and making options();
do return loop;
, hoping that it might work, but it did not
You have a forever loop (a while(true)
) from which you never exit, inside of which you have a switch
-case
for scene
which you never change inside the loop, therefore its value remains immutable and you intend to stop this method from another method.
But methods don't work like that.
Instead, you will need to think about when you want to exit the outer loop and formulate that into a logical criteria, which will be used as the end-sign of the loop, that is, the criteria when the loop should end.
Then, change your while(true)
to some other manner, like while(). true
will always be true
, therefore your while
will never end its work. You will need a falsifiable criteria instead and you will need to make sure that inside the loop (either block-wise or through some methods that are called) the criteria will properly change when needed so the next time your while
condition is evaluated, the loop will exit and your other method will resume its work.