snippetjavaModerate
Implement "Upgrades" Feature for Game
Viewed 0 times
implementgameforupgradesfeature
Problem
I am building a simple adventure game that has "upgrades" feature.
In this game, user controls one player, that can be upgraded to increase things such as:
An "upgrade" has a max level cap, effects on each level of upgrade, and the cost for each upgrade.
Here's my current approach.
This is my
And this is the class that stores the current upgrades: (owned by
However, if I want to add a new upgrade, for example, I wanted to add a "Defense Upgrade". I should modify both
Is this efficient and acceptable?
Or is there any better approach?
In this game, user controls one player, that can be upgraded to increase things such as:
- Amount of gold earned
- Maximum health
- Attack power
- (more of this would be added later, for example: defense upgrade, experience, etc.)
An "upgrade" has a max level cap, effects on each level of upgrade, and the cost for each upgrade.
Here's my current approach.
This is my
Upgrades class, containing all possible upgrades:public class Upgrades {
public static final int GOLD_LEVEL_CAP = 10;
public static final float GOLD_EFFECT_PER_LEVEL = 0.01f;
public static final int[] GOLD_UPGRADE_COSTS = {
100, 200, 300, 400, 500,
600, 700, 800, 900, 1000
};
public static final int HEALTH_LEVEL_CAP = 10;
public static final int HEALTH_EFFECTS_PER_LEVEL = 100;
public static final int[] HEALTH_UPGRADE_COSTS = {
100, 200, 300, 400, 500,
600, 700, 800, 900, 1000
};
public static final int POWER_LEVEL_CAP = 5;
public static final float POWER_EFFECT_PER_LEVEL = 0.05f;
public static final int[] POWER_UPGRADE_COSTS = {
1000, 2000, 3000, 4000, 5000
};
}And this is the class that stores the current upgrades: (owned by
Player class)public class UpgradeProgress {
private int goldUpgradeLevel = 0;
private int healthUpgradeLevel = 0;
private int powerUpgradeLevel = 0;
public void upgradeGold() {
if (goldUpgradeLevel < Upgrades.GOLD_LEVEL_CAP) {
goldUpgradeLevel++;
}
}
// Getter
public int getGoldUpgradeLevel() {
return goldUpgradeLevel;
}
// and so on..
// same for Health and Power
}However, if I want to add a new upgrade, for example, I wanted to add a "Defense Upgrade". I should modify both
Upgrades and UpgradeProgress classes.Is this efficient and acceptable?
Or is there any better approach?
Solution
I don't know any Java, but I think I can give you some ideas that may help you refine this code and make it easier to extend. Take a look at my question about skill upgrades on this site, because I got some very good feedback on this and I think it is relevant to your situation.
Hard coding all of those values into the
What I suggest (which is also the suggestion made to me in the question I linked above) is to make a base
You may need a different base class for
This code may be wrong because I don't know Java but here is the basic idea I am suggesting (syntax improved by @Larethian):
The Player would either have a few of these upgrades and would call the necessary logic to increase their levels when appropriate, or the Player could have another class such as
Hard coding all of those values into the
Upgrades class limits you in many ways. It is nice that everything is in in one place for the sake of easily editing it all at once, but as you note it is forcing you to change data in multiple places if you want to extend the class at all, or even if you want to add new kinds of Upgrades to the game.What I suggest (which is also the suggestion made to me in the question I linked above) is to make a base
Upgrade class (though possibly with a different name), and then make one for each of the Upgrades that you want in your game. Give it all the values that you are assigning in the Upgrades class, and give it the logic that you have in the UpgradeProgress class. This way, all of your Upgrades will have the same underlying properties and functionality, and you can create a limitless number of them without having to change anything. Just instantiate them with the values you want.You may need a different base class for
DefenseUpgrade or any other Upgrade that has different logic inside. It may or may not be a good idea to have it inherit from the original class, it just depends on how many of the properties and methods are the same. In general though, I would recommend composition over inheritance whenever possible.This code may be wrong because I don't know Java but here is the basic idea I am suggesting (syntax improved by @Larethian):
public abstract class Upgrade {
private int LEVEL_CAP;
private float EFFECT_PER_LEVEL;
private int[] UPGRADE_COSTS;
private int currentUpgradeLevel = 0;
protected Upgrade(int levelCap, float effectPerLevel, int[] upgradeCosts){
LEVEL_CAP = levelCap;
EFFECT_PER_LEVEL = effectPerLevel;
UPGRADE_COSTS = upgradeCosts;
}
public void increaseUpgradeLevel() {
if (currentUpgradeLevel < LEVEL_CAP) {
currentUpgradeLevel++;
}
}
// Getter
public int getUpgradeLevel() {
return currentUpgradeLevel;
}
public int getTotalEffect() {
return effectPerLevel*currentUpgradeLevel;
}
//could have getters or setters for any properties necessary
}The Player would either have a few of these upgrades and would call the necessary logic to increase their levels when appropriate, or the Player could have another class such as
UpgradeCollection that could contain all of the Upgrades inside it.Code Snippets
public abstract class Upgrade {
private int LEVEL_CAP;
private float EFFECT_PER_LEVEL;
private int[] UPGRADE_COSTS;
private int currentUpgradeLevel = 0;
protected Upgrade(int levelCap, float effectPerLevel, int[] upgradeCosts){
LEVEL_CAP = levelCap;
EFFECT_PER_LEVEL = effectPerLevel;
UPGRADE_COSTS = upgradeCosts;
}
public void increaseUpgradeLevel() {
if (currentUpgradeLevel < LEVEL_CAP) {
currentUpgradeLevel++;
}
}
// Getter
public int getUpgradeLevel() {
return currentUpgradeLevel;
}
public int getTotalEffect() {
return effectPerLevel*currentUpgradeLevel;
}
//could have getters or setters for any properties necessary
}Context
StackExchange Code Review Q#58532, answer score: 17
Revisions (0)
No revisions yet.