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 开发者_如何学Goon 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
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.
There isn't a one answer that can be given. In general, "lots of global variables" is an anti-pattern - whoever doesn't need to know locations of everything shouldnt be able to - that way that part of your code can't screw it up. So take it case by case.
You need a way to know locations of all objects? Have a class called ObjectMap, for example, and put all the locations there.
Then again, you can always have something like
public class Everything {
public static HashMap<Object, Object> everythingHolder = new HashMap<Object, Object>();
}
but if you go along these lines, your code will become unmaintainable very soon.
Honestly, I would do a thorough check of the class structure to see if there was a better design than making everything global. Using paradigms like MVC can really simplify your code organization. I don't know what your specific needs are, but usually a good design allows you to access the needed data in a simple way.
//A possible heirarchy
PlayableCharacter
|-Stats
| |-int totalHealth
| |-int currentHealth
| |-int speed
| \-int strength
|
|-List<Equipment> inventory
|-Helmet head //Helmet would be a subclass of Equipment
|-HandEquipment leftHand
|-HandEquipment rightHand
|-ChestEquipment torso
\-LegEquipment legs
With an organization structure that both fits your needs and is a good abstraction of the game world, accessing your variables would be easy and meaningful.
public int getAttackLevel() {
return leftHand.getAttackPoints() +
rightHand.getAttackPoints() +
stats.getStrength();
}
If you do find that there are some global variables that are unavoidable, I would again try to organize them in a meaningful way.
GameVariables
|-LocationVariables
| |-int worldX
| |-int worldY
| \-int worldZ
|
|-QuestVariables
| |-String questName
| \-double questProgress
|
|-GameSettings
| |-int resolutionX
| |-int resolutionY
| \-Difficulty difficultyLevel
|
| //And so on....
精彩评论