Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to store global/static variables in an advanced java game?

I am a self-taught java programmer, so i don't know the proper way to do a great deal of things.

I have written a few simple games (such as Asteroids, Snake, ect.) so i know how to do the basics. Now i am working on a more complicated game, a role-playing game with zombies. I started writing it without putting much thought into how i will structure it. First, I made an 'item' class to hold the data for a simple item (value, weight, damage). Then I made a class to hold the variables for the player (Health, armor, items). I eventually made the menu, which on it's own needed variables to hold what menu item is currently being selected.

I soon realized that i have a great deal of global variables that i would need to store somehow. I would need to use the variables in separate classes (such as the class that prints to the screen must know the locations of everything).

So what would be the best way to write a big amount of global variables? Like i said, i do not know the proper way to do things, and i cannot find a good site that explains variable declaration on a large scale. Would i make a class that holds all the variables, and make the 'Main' class have a static declaration of that 'VariableStorage' class?

Thanks in advance!

P.S. Please supply links if you can! :D

like image 900
Steven Rogers Avatar asked Dec 27 '22 23:12

Steven Rogers


1 Answers

There is a reason frequent use of static fields is frowned upon, and that reason is that static fields are less flexible than non-static ones, because there can only be one copy of a static field, but a non-static field can hold a different value for each object instance.

By using static fields, you are restricting yourself to only ever have one player. If you ever want to do multiplayer mode, you can't - without rewriting a lot that is.

The way this is typically done is something like this:

class Player {
    String name;
    Location loc;
    List<Item> inventory;

    void pickup() {
        if (itemsOnGround.isEmpty()) {
            throw new InvalidActionException("There appears to be nothing to pick up here");
        }
        inventory.add(loc.itemsOnGround.get(0));
        loc.itemsOnGround.remove(0);
    }
}

class Location {
    List<Items> itemsOnGround;

    /** null if there isn't a monster here */
    Monster monster;
}

class Game {
    Player player;
}

class Ui {
    Game game;

    void keypressed(char key) {
        try {
            if (key == 'p') {
                game.player.pickup();
            } else {
                showKeyboardHelp();
            }
        } catch (InvalidActionException e) {
            showErrorMessage(e.getMessage());
        }
    }
}

As you can see, nary a static field to be found. This allows you to switch games without restarting your application (just overwriting all static fields is error prone - what if you forget one? Should the player having acquired the amulet of yendor in a previous game really carry over?), while allowing you to create additional items, player (or player-like characters, commonly called NPCs in RPG lingo) at your discretion, and still allows you to logically group related fields into classes, so you can find them again when you look at your code again months from now.

If your game gets non-trivial you should also look into encapsulation. A policy I usually use in small projects is that fields may only be written to by code in the class that declares them, but read throughout the entire program. In a larger project, particularly if it involves several people, you will probably want the compiler to enforce that by making the fields private, and accessing their state through public methods (often called "getters") written for that purpose.

like image 160
meriton Avatar answered Jan 25 '23 23:01

meriton