1

I've been working on a Text RPG like game for a little bit now. I have it set up so that it displays in a Swing window with a non editable JTextPane and a JTextField. I used swing so I could have different colors for text. Now the way the game works is that a user is given multiple options linked to numbers and they choose a number and the game processes what option they chose.

Now the problem that I am encountering is relatively new . I have a method in the superclass that is supposed to be passed down to the subclasses. It starts a battle Sequence.

Now this method calls another method in the middle called Decision which gives the user choices that are passed in as parameters. This is the part that isn't working. Both Decision and Battle are in the super class, but they are used in the subclasses. Originally, decision wasn't working in the subclasses, unless copied into the subclass itself. Now, Battle only loops through once, in the second loop, it stops working just like decision did. When I copy Battle into the subclass, it doesn't work at all.

This is really confusing me of how where the method is in the heirarchy would matter as they are passed down anyway.

Here is the Decision Method

DECISION METHOD

public static int decision(String question, int length, String[] choices){
    int[] numbers = new int[length];
    int iterator = 1;
    for(int i = 0; i < length; i++){
        numbers[i] = iterator;
        iterator++;
    }
    boolean done = false;
    while(!done){
        print("");
        print(question);
        String options = "";
        for(int i = 0; i < numbers.length; i++){
            options = (options + numbers[i] + " - " + choices[i] + "  ");
        }
        print(options);
        boolean univSet = true;
        int temp = univInt;
        int entry = 1;
        while(univSet){
            if(univInt != 0){
                univSet = false;
                entry = univInt;
                univInt = 0;
            }
        }
        if(entry == 23){
            help();
        }else{
            for(int i = 0; i < numbers.length; i++){
                if(entry == numbers[i]){
                    done = true;
                    univInt = 0;
                    return entry;
                }
            }
            print("Invalid Number, Try again");
            print("");
            univInt = 0;
        }
    }
    return (Integer) null;
}

BATTLE Method

public static void battle(String name, int health, int power){
    //print("-----------");
    int iHealth = player.health;
    sPrint(name + " battle initiated!");
    print("You're pull out your " + player.curWeapon + "!");
    print(player.actionTexts[player.weaponPos]);
    int eHealth = health;
    boolean done = false;
    while(!done){
        sPrint("Equipped Weapon and Power: " + player.curWeapon + " - " + player.weaponPower[player.weaponPos] + "\nCurrent Health: " + player.health + "\nEnemy Health: " + eHealth);
        int move = decision("What will you do?", 3, new String[]{"Attack", "Block", "Cower In Fear"});
        if(move == 1){
            print("You attacked with the " + player.curWeapon + " for " + (int)(player.power * player.powerUp) + " damage!");
            eHealth -= (int)(player.power * player.powerUp);
            print("The " + name + " attacked for " + power + " damage!");
            player.health -= power;
        }else if(move == 2){
            int chance = (int) (Math.random()* 100);
            if(chance < 25){
                print("You successfully blocked!");
                print("The " + name + " attacked for 0 damage!");
            }else if(chance >= 75){
                print("You failed to block!");
                print("The " + name + " attacked for " + power + " damage!");
                player.health -= power;
            }else{
                print("You half blocked!");
                print("The " + name + " attacked for only " + (power/2) + " damage!");
                player.health -= (power/2);
            }
        }else{
            gameOver();
        }
        if(player.health <= 0){
            print("You ran out of health!");
            done = true;
            gameOver();
        }
        if(eHealth <= 0){
            sPrint("You won the battle!");
            print(""); 
            player.health = iHealth;
            done = true;
        }
    }
}

I know that the way I described this is probably very confusing. But I'd be glad to clear up all questions. I just want to know why this is acting up and how I can fix it.

Here's a link to a download of my game: http://wikisend.com/download/353028/src.rar

If you want to get to the site of the problem, enter 1, 'complete', 1, any text, 1, 2, 1, and then it sort of stops working. Alternatively you can just read through and play the game to the point. Thank you to anyone willing to help!

EDIT:

The thing that confuses me the most is this all worked before I implemented swing. Everything was the same in both methods before except for the addition of this part of decision

        boolean univSet = true;
    int temp = univInt;
    int entry = 1;
    while(univSet){
        if(univInt != 0){
            univSet = false;
            entry = univInt;
            univInt = 0;
        }
    }

univInt is a static integer that comes from the framework class and it is set to 0 when going through decision otherwise it is whatever number is entered into the swing display. The problem with decision is that sometimes, it randomly says that univInt == 0, when every test I give it says otherwise.

EDIT 2:

I've changed all of the static references to instance in the highest of the subclasses and then in the subclasses, they all showed up with an error in eclipse and the suggested fix was to change them to static. Why would this be occurring? Specifically the print method isn't working, which adds the text passed through to the JTextPane. Here is the print method:

public void print(String s){
    StyleConstants.setForeground(style, Color.black);
     try { 
         doc.insertString(doc.getLength(), s + "\n",style); 
     }
     catch (BadLocationException e){}
     output.select(doc.getLength(),doc.getLength());
}

the print function works in the same class it is in, but not the class below.

TheBrownCoder
  • 1,186
  • 1
  • 10
  • 18
  • I think the problem here is not with the method bodies but rather in how you defined the classes. Please post their definitions as well. – Reuben Tanner Mar 22 '14 at 19:45
  • possible duplicate of [Why doesn't Java allow overriding of static methods?](http://stackoverflow.com/questions/2223386/why-doesnt-java-allow-overriding-of-static-methods) – Jason C Mar 22 '14 at 19:55
  • @theSilentOne By definitions do you mean the very beginning of the class? there are 5 classes and I'm not sure which ones you want. – TheBrownCoder Mar 22 '14 at 20:30

1 Answers1

1

Your methods are declared as static. static methods are not part of the class hierarchy at all. Only instance (non-static) methods are.

Jason C
  • 38,729
  • 14
  • 126
  • 182
  • Hm, It won't let me take off the static because the integer where I'm storing decision's information is a static int that is available all throughout the class. I'll try changing it and seeing if thats the problem. Although before I implemented swing, this all worked fine. – TheBrownCoder Mar 22 '14 at 20:31
  • If the integer where you are storing this information is static, that is more likely a design problem, and unrelated to your use of swing. Declare and use instance fields, and pass instances of relevant objects around accordingly. – Jason C Mar 22 '14 at 20:42
  • Okay, I'll look over the design of it but what do you mean by instance fields? Can you explain a litte further – TheBrownCoder Mar 22 '14 at 20:45
  • I know my code is a little messy, I plan on fixing it now, but why is it that it'll work on one loop through but not the next? Is that some sort of memory issue or something? – TheBrownCoder Mar 22 '14 at 21:20
  • @TheBrownCoder Without seeing the rest of your code its hard to say, but again, `static` methods cannot be overridden (although they can be hidden), so if in one context you are calling the static method of the base and in another you are calling the static method of the subclass, incorrect behavior would result. Static fields are not inherited in the same way as non-static fields, either. By the way, an "instance" field is the name we give to non-static fields, as they are associated with instances of a class, rather than the class itself. – Jason C Mar 22 '14 at 21:43
  • In other words, if you have static fields and methods declared in the base, they're completely independent of static fields and methods declared in the subclass. It sounds like you are using static members inconsistently, and incorrect behavior is resulting. If you declare a `static int` in the base and that same `static int` in the subclass, the subclass declaration *hides* the base declaration, but they are still completely, 100% separate and independent variables. Changing one does not affect the other in any context. – Jason C Mar 22 '14 at 21:45
  • Ok, For now, I'll change everything that needs to be inherited to an instance and see if that changes it. Thanks for the help! once this sorts out, I'll mark this as the correct answer. Otherwise I'll state whats going wrong – TheBrownCoder Mar 22 '14 at 21:50
  • I changed a few of my methods to instance and my variables to instance as well and any calling of those methods in the sub classes instantly required them to be static. I'm assuming this is why I originally made them static. I'll add the framework class to the question and show you – TheBrownCoder Mar 22 '14 at 22:09
  • 1
    I got it, I wasn't even looking through properly. – TheBrownCoder Mar 22 '14 at 22:20