2

I started working on my first java project, which is a basic RPG, and I have a question regarding the spells. I have an abstract class named Character, which is extended by some subclasses (like Fighter, Mage etc.). Only spellcasters can cast spells. Regarding Spells - I have a class named Spell that describes a spell (it's name, it's effect, mana etc.). All the spells are stored in SpellsList class that has a spellsList list (objects of class Spell). I have an Effect class (very plausible that it will become an interface) that has some effects like "damage" and "heal", but I don't make use of that for the meanwhile, I just want to test that what I have works.

My problem is that Mage's methods addToSpellBook and showSpellBook give a compiler error: java can't find symbol: method addToSepllBook, location: variable hero of type Game.Character. also for showSpellBook. Why and how to fix it ? (The problem is probably in Mage/Spell/SpellsList class, and not Character which is long, so it's less intimidating :) )

public class Game {
public static void main(String[] args) throws IOException {

    CharacterCreator heroCreator = new CharacterCreator();
    CharacterCreator.showAllClasses();

    Scanner sc = new Scanner(System.in);
    int scan = sc.nextInt();
    String chosenClass = CharacterCreator.getCharacterClass(scan);
    Character hero = CharacterCreator.createCharacter(chosenClass);
    try {
        hero.displayCharacter();
    }catch (Exception e){
        System.out.println("Wrong input");
    }




    if (hero.getCharacterClass().equals("Mage")){
        hero.addToSpellBook("Fireball");
        hero.showSpellBook();
    }



}

   }

public class CharacterCreator {

public static Character createCharacter(String chosenClass) {

    Character hero = null;

    System.out.println("Choose Name:");
    Scanner nameIn = new Scanner(System.in);
    String name = nameIn.next();


        switch (chosenClass) {
            case "Fighter":
                return new Fighter(name);
            case "Rogue":
                return new Rogue(name);
            case "Mage":
                return new Mage(name);
            case "Cleric":
                return new Cleric(name);
            case "def":
                System.out.println("Wrong input");
                return null;
            default:
                return null;
        }


}

public static void  showAllClasses(){
    System.out.println("Choose a character: ");
    System.out.println("1. Fighter");
    System.out.println("2. Rogue");
    System.out.println("3. Mage");
    System.out.println("4. Cleric");
}


public static String getCharacterClass(int scan){

    String classIn;

    switch (scan) {
        case 1:
            classIn = "Fighter";
            break;
        case 2:
            classIn = "Rogue";
            break;
        case 3:
            classIn = "Mage";
            break;
        case 4:
            classIn = "Cleric";
            break;
        default:
            System.out.println("Enter again");
            classIn = "def";
    }

    return classIn;
}

}


abstract public class Character {

    private String name;
    private String characterClass;
    private int level;
    private int hp;
    private int currentHp;
    private int armorClass;

    private long xp;
    /*private int BAB; /*Base attack bonus*/

    private int strength;
    private int constitution;
    private int dexterity;
    private int intelligence;
    private int wisdom;
    private int charisma;


    protected Character(String name){

        setName(name);
        setCharacterClass("Class");
        setLevel(1);
        setStrength(10);
        setConstitution(10);
        setDexterity(10);
        setIntelligence(10);
        setWisdom(10);
        setCharisma(10);
        setHp(0);
        setCurrentHp(getHp());
        setArmorClass(10);
        setXp(0);

    }


    void displayCharacter() throws IOException{
        System.out.print("\n\n\n");
        System.out.println("Name: " + getName());
        System.out.println("Class: " + getCharacterClass());
        System.out.println("Level: " + getLevel());
        System.out.println("HP: " + getHp());
        System.out.println("Current HP: " + getCurrentHp());
        System.out.println("Armor Class: " + getArmorClass());

        System.out.println("***************");
        System.out.println("Attributes: ");
        System.out.println("Strength: " + getStrength());
        System.out.println("Constitution: " + getConstitution());
        System.out.println("Dexterity: " + getDexterity());
        System.out.println("Intelligence: " + getIntelligence());
        System.out.println("Wisdom: " + getWisdom());
        System.out.println("Charisma: " + getCharisma());
        System.out.println("***************");
        System.out.println("XP: " + getXp());

    }

    public int getModifier(int number){
        int mod = (int)((number -10)/2);
        return mod;
    }

    public String getName() { return name; }
    public String getCharacterClass() { return characterClass; }
    public int getLevel() { return level; }
    public int getHp() { return  hp; }
    public int getCurrentHp() { return  currentHp; }
    public int getArmorClass() { return  armorClass; }
    public int getStrength(){ return strength; }
    public int getConstitution(){ return constitution; }
    public int getDexterity(){ return dexterity; }
    public int getIntelligence(){ return intelligence; }
    public int getWisdom(){ return wisdom; }
    public int getCharisma(){ return charisma;}
    public long getXp(){ return xp;}


    protected void setName(String Name) { name = Name; }
    protected void setCharacterClass(String characterClass) { this.characterClass = characterClass; }
    protected void setLevel(int lvl){ level = lvl; }
    protected void setHp(int hitPoints){ hp = hitPoints; }
    protected void setCurrentHp(int curHp){ currentHp = curHp; }
    protected void setArmorClass(int ac){ armorClass = ac; }
    protected void setStrength(int str){ strength = str; }
    protected void setConstitution(int con){ constitution = con; }
    protected void setDexterity( int dex) { dexterity = dex; }
    protected void setIntelligence(int intel){ intelligence = intel; }
    protected void setWisdom(int wis){ wisdom = wis; }
    protected void setCharisma(int cha){charisma = cha; }
    protected void setXp(int XP){xp = XP; }

    }

public class Mage extends Character  {

private List<Spell> spellBook;

public Mage(String name){

    super(name);

    setName(name);
    setCharacterClass("Mage");
    setLevel(1);
    setStrength(10);
    setConstitution(10);
    setDexterity(14);
    setIntelligence(16);
    setWisdom(14);
    setCharisma(10);
    setHp((int) (4 + getModifier(getConstitution())));
    setCurrentHp(getHp());
    setArmorClass(10 + getModifier(getDexterity()));
    spellBook = null;

}

 void addToSpellBook(String spellName){

    Spell newSpell;
    newSpell = SpellsList.getSpell(spellName);
    spellBook.add(newSpell);

}

void showSpellBook(){

    for (Iterator<Spell> iter = spellBook.iterator(); iter.hasNext(); ) {
        Spell spell = iter.next();
        if (spellBook.equals(spell.getSpellName())) {
            System.out.println("Spell name: " + spell.getSpellName());
            System.out.println("Spell effect: " + spell.getEffect());
        }
        }
}

}



public class Spell {
private String name;
private int spellLevel;
private String effect;
private int manaCost;
private int duration;

Spell(String name, int spellLevel, String effect, int manaCost, int duration){
    this.name = name;
    this.spellLevel = spellLevel;
    this.effect = effect;
    this.manaCost = manaCost;
    this.duration= duration;
}


void castSpell(String spellName, Character hero, Character target){
    try {
        Spell spell = SpellsList.getSpell(spellName);
        System.out.println("You casted: " + spellName);
        System.out.println("Spell effect: " + spell.effect);
    }
    catch (Exception e){
        System.out.println("No such spell");
    }
}

String getSpellName(){ return name; }

int getSpellLevel() {return spellLevel; }

String getEffect(){ return effect; }

int getManaCost(){
    return manaCost;
}

int getDuration() { return  duration; }
}


public class SpellsList {
static List<Spell> spellsList = new ArrayList<Spell>();
static

{
    spellsList.add(new Spell("Fireball", 3, "damage", 5,0 ));
    spellsList.add(new Spell("Ice Storm", 4, "damage", 8, 0));
    spellsList.add(new Spell("Heal", 2, "heal", 4, 0));
}

static Spell getSpell(String spellName) {
    try {
        for (Iterator<Spell> iter = spellsList.iterator(); iter.hasNext(); ) {
            Spell spell = iter.next();
            if (spellName.equals(spell.getSpellName())) {
                return spell;
            }
        }

    } catch (Exception e){
        System.out.println(spellName + " haven't been found in spells-list");
        return null;
    }
    return null;

}

}
1
  • hero is of type Character which does not define nor declare addToSpellBook... Commented Oct 26, 2015 at 16:07

3 Answers 3

1

hero is of type Character. You should cast it to Mage. or add addToSpellBook in Character class and override it in Mage class. Something like:

if(hero instanceof Mage)
   ((Mage) hero).addToSpellBook();
Sign up to request clarification or add additional context in comments.

9 Comments

I don't want character to have this method in the abstract class Character. Would it be wise to cast the hero to Mage in the factory ?
You can verify that it is of Mage class and then cast it. using instanceof(Mage);
in the "if : line: illegal start of type, not a statement, and : expected
Mage is probably the problem... Though it's weird because it was created as a Mage
Yes but you should declare hero as a Mage. Sorry I missed it. Can you show your CharacterCreator class?, it should return a Mage object...
|
0

There is a difference between the type of variables when compiling and their class during execution. The problem is that your hero variable is not of type Mage but of type Character and only has access to methods available to any Character.

The compiler also doesn't notice your logic in attempting to make sure hero is an instance of Mage. To tell it you know you have Mage and want to use Mage methods you need to cast.

Your way of verifying is okay, but I would advise using theinstanceof keyword.

if(hero instanceof Mage) {
   ((Mage)hero).addToSpellBook("Fireball");
   ((Mage)hero).showSpellBook();
}

5 Comments

Now I have just one compilation error in the last } of Game. reached end of file while parsing.
Java isn't sure that it can use Mage's methods because it knows that it's Character, right. Now I understand exactly what caused it. Thanks ! . Though I still have one error...
@Niminim I'm sure you will find or add the appropriate }. Good luck.
spellBook in Mage's constructor or before the constructor is wrong, right ? probably the null pointer...
@Niminim. Well, spellBook being null may cause a run-time problems.
0

You call the methodes addToSpellBook and showSpellBook on the class Character, but you have no methodes with this names in your class Character.

4 Comments

I don't want character to have this method in the abstract class Character. What can I do ?
You can write in Character the methodes abstract and override them in the classes that extends your "Character".
it means that I have to add a black two methods in each sublass of Character. Is there any elegant solution ?
Thats why you normaly don't use an inheritance system for programming games. For programming games you can for example use an entity component system that is superior, but I think for your small game that would be overkill :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.