global variable

ok so to mkae a wariable global in a class you just declar it outside of and method. so I have this code. the prints are so that I can know if it is working before I write gui for that part.


import java.io.*;
public class Enemy
{
    boolean survive = true;
    String enemy;
    int[] enemyInfo = new int[5];
    String line;
    int x;
    int health;
    public void subHealth(int i){System.out.println(enemyInfo[0]);health = health - i;System.out.println(health);}//and then over here is 0
    public void setEnemy(String i){
        enemy = i;
    }
    public boolean checkAlive()
    {
        if(health<1){survive = false;}
        return survive;
    }
    public void getEnemyInfo()
    {
        try{
            File inFile = new File("resources/enemies/"+enemy+".txt");
            BufferedReader reader = new BufferedReader(new FileReader("resources/enemies/"+enemy+".txt"));
            line = null;
            while ((line=reader.readLine()) != null)
            {
                enemyInfo[x] = Integer.parseInt(line);
                x++;
            }
        }catch(FileNotFoundException e){System.err.println("Library not complete");}
        catch(IOException e){}
        catch(NumberFormatException e){}
        health = enemyInfo[0];//over here it is ten
    }
}

  • What is the question(if any)
  • What your describing is a class variable, java doesn’t have global’ variables in the ‘traditional’ sense.

oh i am sorry I forgot to ask :-.

[quote]health = enemyInfo[0];//over here it is ten
[/quote]

[quote]public void subHealth(int i){System.out.println(enemyInfo[0]);health = health - i;System.out.println(health);}//and then over here is 0
[/quote]
in one place it is ten and in another it is 0.

Heh hence they are called variables. :wink:

Depending on how your code gets called this makes sense.

So if subHealth(10); would get called some where or subHealth(5); subHealth(5); etc.

so are they in defferent instances of the class

here is where it is called from


import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.net.URL;
import javax.swing.AbstractButton;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Dimension;
import javax.swing.JLabel;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
public class battle extends JPanel implements ActionListener {
    int time = 1;
    Enemy enemy = new Enemy();
    String created;
    JFrame frame;
    String enemyType;
    boolean survive;
    protected static JButton attack, jbnMiddle, jbnRight;
    public battle() {
        attack = new JButton("attack");
        attack.setMnemonic(KeyEvent.VK_A);
        attack.setActionCommand("attack");
        jbnMiddle = new JButton("Centre button");
        jbnMiddle.setVerticalTextPosition(AbstractButton.BOTTOM);
        jbnMiddle.setHorizontalTextPosition(AbstractButton.CENTER);
        jbnMiddle.setMnemonic(KeyEvent.VK_M);
        jbnMiddle.setActionCommand("center");
        jbnMiddle.setLayout(new GridLayout(1,2,2,2));
        jbnMiddle.setToolTipText("Centre button");
        jbnRight = new JButton("Enable centre button");
        jbnRight.setMnemonic(KeyEvent.VK_E);
        jbnRight.setActionCommand("enable");
        jbnRight.setEnabled(false);
        attack.addActionListener(this);
        jbnMiddle.addActionListener(this);
        jbnRight.addActionListener(this);
        jbnRight.setToolTipText("Enable the Centre button.");
        add(attack);
        //add(jbnMiddle);
        //add(jbnRight);
    }
    public void actionPerformed(ActionEvent e) {
        if ("attack".equals(e.getActionCommand())) {
            //damage = enemy.getDmg(15);
            enemy.subHealth(10);//damage);
            survive = enemy.checkAlive();
            if(survive == false)
            {
                System.out.println("dead");
                frame.setVisible(false);
            }
        }
        if ("enable".equals(e.getActionCommand())){
        }
        if ("center".equals(e.getActionCommand())){
        }
    }
    public void setEnemy(String i){
        enemyType = i;
        enemy.setEnemy(enemyType);
    }
    public void createGUI()
    {
                JFrame.setDefaultLookAndFeelDecorated(true);
        JFrame frame = new JFrame("combat");
        frame.setPreferredSize(new Dimension(200,75));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        battle buttonContentPane = new battle();
        buttonContentPane.setOpaque(true);
        frame.getRootPane().setDefaultButton(attack);
        frame.setContentPane(buttonContentPane);
        frame.pack();
        frame.setVisible(true);
    }
    protected static ImageIcon createImageIcon(String path) {
        URL imgURL = battle.class.getResource(path);
        if (imgURL != null) {
            return new ImageIcon(imgURL);
        } else {
            System.err.println("Couldn't find image in system: " + path);
            return null;
        }
    }
    public static void main(String[] args)
    {
        battle bat = new battle();
        bat.createGUI();
        bat.setEnemy("imp");
    }
}

is it 0 after pressing the buttom?

the subhealth works fine. it is in the enemy class. the getEnemyInfo method goes into a text file to get the info for that enemy. int he metho where it gets it, health = 10. but in the suhealth method health = 0. do you understand?

you make an instance of the enemy class.
you load the settings from the textfile
health=10

then subHealth(10); gets called:

public void subHealth(int i){
  System.out.println(enemyInfo[0]);
  health = health - i;
  System.out.println(health);//and then over here is 0
}

System.out.println(enemyInfo[0]); should print 10.
health = health - i; -> health = 10 - 10 -> health = 0;
System.out.println(health); -> prints 0.

Sounds like everything is happening as specified.

here is what appears in the console:

0
-10
dead

it does not go as it should.

Read here.

I changed it to


import java.io.*;
public class Enemy
{
    boolean survive = true;
    String enemy;
    int[] enemyInfo = new int[5];
    String line;
    int x;
    int health;
    public void subHealth(int i){System.out.println(enemyInfo[0]);health = health - i;System.out.println(health);}//and then over here is 0
    public void setEnemy(String i){
        enemy = i;
        [u][b]getEnemyInfo();[/b][/u]
    }
    public boolean checkAlive()
    {
        if(health<1){survive = false;}
        return survive;
    }
    public void getEnemyInfo()
    {
        try{
            File inFile = new File("resources/enemies/"+enemy+".txt");
            BufferedReader reader = new BufferedReader(new FileReader("resources/enemies/"+enemy+".txt"));
            line = null;
            while ((line=reader.readLine()) != null)
            {
                enemyInfo[x] = Integer.parseInt(line);
                x++;
            }
        }catch(FileNotFoundException e){System.err.println("Library not complete");}
        catch(IOException e){}
        catch(NumberFormatException e){}
        health = enemyInfo[0];//over here it is ten
    }
}

end I still get the same in the console.

I don’t know, if you reuse your Enemy instance on purpose, but I think you have problems to grasp the concepts of classes and instances. Take a look at http://java.sun.com/docs/books/tutorial/java/javaOO/classvars.html.

I think you want something like this:


public class Enemy
{
    private boolean survive = true;
    private String name;
    private int health;

    /**
     * This constructs an Enemy with a name and loads the initial data from it's info file
     */
    public Enemy(String name)
    {
        this.name = name;
        loadEnemyInfo(name);
    }

    /**
     * Gets the name of this Enemy instance
     */
    public int getName()
    {
        return name;
    }

    /**
     * Gets the current health of this Enemy instance
     */
    public int getHealth()
    {
        return health;
    }

    /**
     * Hits the Enemy instance and does a certain damage
     */
    public void hit(int damage)
    {
        health = health - damage;
    }

    /**
     * Returns, if this Enemy instance is still alive
     */
    public boolean isAlive()
    {
        if(health<1){survive = false;}
        return survive;
    }

    /**
     * Loads this Enemy instances inital values from an info file
     * This is protected to be callable from this or derived classes, but not from the outside.
     */
    protected void loadEnemyInfo()
    {
        int[] enemyInfo = new int[5];
        String line;
        BufferedReader reader = null;
        try
        {
            File inFile = new File("resources/enemies/"+enemy+".txt");
            reader = new BufferedReader(new FileReader("resources/enemies/"+enemy+".txt"));
            line = null;
            int x = 0;
            while ((line=reader.readLine()) != null)
            {
              enemyInfo[x] = Integer.parseInt(line);
              x++;
            }
        }
        catch(FileNotFoundException e)
        {
            System.err.println("Library not complete");
        }
        finally // always close streams in a finally block!!!
        {
            if(reader!=null)
            {
                try { reader.close() }
                catch(IOException ignore){}
            }
        }
        catch(IOException e){}
        catch(NumberFormatException e){}
        health = enemyInfo[0];//over here it is ten
    }
}

So you can use it like


public class Battle extends JPanel implements ActionListener {
    // (...)
    private Enemy[] enemies = null;
    // (...)
    public Battle() {
        // (...)
        enemies = new Enemy[]{
             new Enemy("Ogre"),
             new Enemy("Ogre"),
             new Enemy("Ogre"),
             new Enemy("Ogre"),
             new Enemy("Gimp"),
             new Enemy("Gimp"),
             new Enemy("Rat"),
             new Enemy("Rat"),
             new Enemy("Rat"),
             new Enemy("Rat"),
             new Enemy("Rat"),
             new Enemy("Overlord")
        };
        // (...)
    }
     // (...)
}

This way you create an array of enemies that consists of 4 instance with initial values loaded from the “Orge.txt” file, 2 instances from the “Gimp.txt” file, 5 instance loaded from the “Rat.txt” file and one from the “Overlord.txt”.

Some additional notes on common java code style:

  • Use uppercase classes (Battle instead of battle) - lowercase names are usually used as variable names
  • Use loadEnemyInfo is better than getEnemyInfo, because getXXX usually describes the accessor of a “Property”
  • Make every member variable of a class private and provide get/is/set Methods to expose them to the outside only if desired
  • I changes checkAlive to isAlive, since the status to be alive is a “Property” of the Enemy. (isXXX describes the accessor of a boolean “Property”

Edit: missed the “String” type for the “name” variable and the “enemy[]” declaration was not correct.

thank you for enlightening me. I will try and change my code to this way. If I have troubles I will post.

why did you make it an array? there is only one enemy at a time so far.

I didn’t know that. It was an example of how to use the Enemy class to create multiple Enemy instances based on different data files. If you want to create a Battle screen with a single enemy, you can just hand in the current Enemy instance:


public class Battle extends JPanel implements ActionListener {
    // (...)
    private Enemy currentEnemy = null;
    // (...)
    public Battle(Enemy enemy) {
        // (...)
        this.currentEnemy = enemy;
        // (...)
    }
     // (...)
}

So you can call the Battle window from you main game window like this:


public class GameWindow extends JFrame implements ActionListener {
    // (...)
    private Enemy[] enemies = null;
    // (...)
    public GameWindow() {
        // (...)
        enemies = new Enemy[]{
             new Enemy("Ogre"),
             new Enemy("Ogre"),
             new Enemy("Ogre"),
             new Enemy("Ogre"),
             new Enemy("Gimp"),
             new Enemy("Gimp"),
             new Enemy("Rat"),
             new Enemy("Rat"),
             new Enemy("Rat"),
             new Enemy("Rat"),
             new Enemy("Rat"),
             new Enemy("Overlord")
        };
        // (...)
    }
     // (...)
     public void battleEnemy(int enemyIndex)
     {
           JFrame battleWindow = new JFrame();
           Battle battle = new Battle(enemies[enemyIndex]);
           battleWindow.setContentPane(battle);
           battleWindow.setVisible(true);
     }
}

That’s just a quick example. How exactly you code this depends on what you want to achieve…

If you need assistance in windowing, take a look at the swing tutorials over at sun: http://java.sun.com/docs/books/tutorial/uiswing/

umm


        enemies = new Enemy[]{
             new Enemy("Ogre"),
             new Enemy("Ogre"),
             new Enemy("Ogre"),
             new Enemy("Ogre"),
             new Enemy("Gimp"),
             new Enemy("Gimp"),
             new Enemy("Rat"),
             new Enemy("Rat"),
             new Enemy("Rat"),
             new Enemy("Rat"),
             new Enemy("Rat"),
             new Enemy("Overlord")
        };

should be


        Enemy[] enemies = {
             new Enemy("Ogre"),
             new Enemy("Ogre"),
             new Enemy("Ogre"),
             new Enemy("Ogre"),
             new Enemy("Gimp"),
             new Enemy("Gimp"),
             new Enemy("Rat"),
             new Enemy("Rat"),
             new Enemy("Rat"),
             new Enemy("Rat"),
             new Enemy("Rat"),
             new Enemy("Overlord")
        };

Nope. :wink: The enemies Array is already defined as a member variable to make it available to other methods of the same class. If you redeclare it locally, the class member called enemies would remain unset. Also in java you can’t use a short form for array initialization, it has to be = new []{ new (), new (), …}

err…int[] arr = new int[5] is shorter, unless your talking about a short-form to give the array locations starting values.

On a side note I may just seen the way to pass an array that is created in the method call. I always had a syntax problem.

It’s about array initialization, not declaration.