Our creatures need xp, a level, and a way to gain xp and levels. When the xp passes the next level threshold, the level should be incremented, the ai should get notified, and the creature should heal a bit.
private int xp; public int xp() { return xp; } public void modifyXp(int amount) { xp += amount; notify("You %s %d xp.", amount < 0 ? "lose" : "gain", amount); while (xp > (int)(Math.pow(level, 1.5) * 20)) { level++; doAction("advance to level %d", level); ai.onGainLevel(); modifyHp(level * 2); } } private int level; public int level() { return level; }
The starting level is initialized to 1 in the constructor. I'm using a formula to determine how much experience is needed for the next level but you can use a lookup table or some other formula. Many interesting things have been said about leveling and power curves so read up, try different things, and do what works for you.
We need to update the attack method to grant experience when a creature is killed. Add the following to the end of the attack method:
if (other.hp < 1) gainXp(other);
Now we can grant experience based on some experience value the creature has, or on it's level, or on the killers level, or by some combination. I'm using a simple formula for now.
public void gainXp(Creature other){ int amount = other.maxHp + other.attackValue() + other.defenseValue() - level * 2; if (amount > 0) modifyXp(amount); }
This ensures that tougher creatures are worth more and by subtracting the killer's level, easy creatures will soon be worth nothing. It's not perfect but it's simple to explain, understand, and code.
If you play it now (after creating an empty onGainLevel in CreatureAi) you should see notices about gaining levels. That's a good sign.
For this simple roguelike, when something gains a level it get's some stat bonus; increased hp, increased attack, etc. The player will be shown a list to chose from but other creatures will get one at random.
Let's create a class to represent a level up option's name and actual effect.
package rltut; public abstract class LevelUpOption { private String name; public String name() { return name; } public LevelUpOption(String name){ this.name = name; } public abstract void invoke(Creature creature); }
We need something to track all the possible options and enforce some of our level-up logic. We'll call it a LevelUpController — even though classes with Manager or Controller in the name are usually vague and messy and not the best way to do things.
package rltut; import java.util.ArrayList; import java.util.List; public class LevelUpController { private static LevelUpOption[] options = new LevelUpOption[]{ new LevelUpOption("Increased hit points"){ public void invoke(Creature creature) { creature.gainMaxHp(); } }, new LevelUpOption("Increased attack value"){ public void invoke(Creature creature) { creature.gainAttackValue(); } }, new LevelUpOption("Increased defense value"){ public void invoke(Creature creature) { creature.gainDefenseValue(); } }, new LevelUpOption("Increased vision"){ public void invoke(Creature creature) { creature.gainVision(); } } }; }I created a few simple options based on the stats we already have but I'm sure you can come up with more. These are anonymous classes - if you're not familiar with them you should check them out. Anonymous classes can make some things very clear and succinct - other things are best left to regular classes.
This LevelUpController should be able to select one option at random and apply it to a given creature.
public void autoLevelUp(Creature creature){ options[(int)(Math.random() * options.length)].invoke(creature); }
Now the CreatureAi can call this to automatically gain some benefit when a creature gains a level.
public void onGainLevel() { new LevelUpController().autoLevelUp(creature); }
Of course the Creature class needs to support these new options too. Here's what I came up with:
public void gainMaxHp() { maxHp += 10; hp += 10; doAction("look healthier"); } public void gainAttackValue() { attackValue += 2; doAction("look stronger"); } public void gainDefenseValue() { defenseValue += 2; doAction("look tougher"); } public void gainVision() { visionRadius += 1; doAction("look more aware"); }
If you try it now you should see that when you gain a level you look tougher or stronger etc. You may even notice something else looking stronger or more aware. That's why I think it's so cool to have a method like doAction; you can, if you're lucky, see the rare and subtle events like these.
Try it.
What about when the player gains a level? Shouldn't we show a list of options for the user to choose from? Let's start by making sure the player doesn't automatically get free bonuses.
Override the onGainLevel method in the PlayerAi class.
public void onGainLevel(){ }
Now we update the PlayScreen's respondToUserInput method. When we first enter the method, before the user does anything, we need to record the player's level.
int level = player.level();After responding to the player's input, we need to see if that resulted in a level up. If so, we jump into a LevelUpScreen and tell it how many bonuses the player get's to pick.
if (player.level() > level) subscreen = new LevelUpScreen(player, player.level() - level);
Now all we need is a LevelUpScreen that uses a LevelUpController to show what can be picked and applies that choice.
package rltut.screens; import java.awt.event.KeyEvent; import java.util.List; import rltut.Creature; import rltut.LevelUpController; import asciiPanel.AsciiPanel; public class LevelUpScreen implements Screen { private LevelUpController controller; private Creature player; private int picks; public LevelUpScreen(Creature player, int picks){ this.controller = new LevelUpController(); this.player = player; this.picks = picks; } @Override public void displayOutput(AsciiPanel terminal) { List<String> options = controller.getLevelUpOptions(); int y = 5; terminal.clear(' ', 5, y, 30, options.size() + 2); terminal.write(" Choose a level up bonus ", 5, y++); terminal.write("------------------------------", 5, y++); for (int i = 0; i < options.size(); i++){ terminal.write(String.format("[%d] %s", i+1, options.get(i)), 5, y++); } } @Override public Screen respondToUserInput(KeyEvent key) { List<String> options = controller.getLevelUpOptions(); String chars = ""; for (int i = 0; i < options.size(); i++){ chars = chars + Integer.toString(i+1); } int i = chars.indexOf(key.getKeyChar()); if (i < 0) return this; controller.getLevelUpOption(options.get(i)).invoke(player); if (--picks < 1) return null; else return this; } }
And there you go; a simple leveling system that lets the player decide how they want to progress their character. You could add different bonuses like special moves, critical hits, extra xp per kill, or special abilities. You could even make it so the player could chose a new item after leveling up.
download the code
public void gainDefenseValue() {
ReplyDeleteattackValue += 2; //This should say defenseValue += 2;
doAction("look tougher");
}
Fixed!
DeleteWe would further amount to better understanding of the various objects and reliable opinions as narrated here and hopefully for the future these would almost help students to bring every possible guides herewith.
ReplyDeleteYou didn't write getLevelUpOptions method, neither you wrote getLevelUpOption. They are easy to code yourself, so whatever.
ReplyDeleteIt is a beautiful blog,thanks for sharing.
ReplyDeletedata science training in Marathahalli
best data science courses in Marathahalli
data science institute in Marathahalli
data science certification Marathahalli
data analytics training in Marathahalli
data science training institute in Marathahalli
Thanks for sharing this nice informations.
ReplyDeleteartificial intelligence training in coimbatore
Blue prism training in coimbatore
RPA Course in coimbatore
C and C++ training in coimbatore
big data training in coimbatore
hadoop training in coimbatore
aws training in coimbatore
Buy weed online without medical card
ReplyDeleteBuy marijuana flowers online
Buy marijuana edibles online
Buy white ice moon rock
Buy vapes and carts online usa
Buy marathon og online
Buy dark star strain online
buy hawaiian skunk strain online
buy mr nice online
ReplyDeletebuy white ice moon rock
buy juicy fruit online
buy marathon og Strain online
exotic carts packaging
facewreck
legal psychedelics for sale
buying acdc strain online
backwoods wild n mild
buy liberty caps
buy marijuana-indica online
ReplyDeletebuy marijuana-hybrid online
buy marijuana-concentrates-cartridges-and-weed-concentrates online
buy marijuana-seeds online
buy marijuana-pre-rolls online
buy marijuana-accessories online
buy marijuana-accessories-and-vaporisers online
buy hemp-cbd-and-cbd-oils online
buy hemp-cbd-and-cbd-capsules-weed-concentrates online
"buy marijuana-grand-daddy-purple online
Good blog !!!
ReplyDeleteReally inspiring and helpful...
angular assignment help.