Change a variable in another class based on a variable string.

I hope the subject made sense, but essentially what I want to be able to do is have a string that I can change which refers to a variable in another class which I can then change.

Something like this.


String variable = "speed";

public void method(Object ob){
    ob.getVariable(variable) = 3;
}

This of course is not how it would look but I hope it helps in understanding what it does.

That is definitely do-able via reflection. http://docs.oracle.com/javase/tutorial/reflect/member/fieldValues.html

Honestly though, reflection is generally a bad idea - not always. Why do you need it? If it is to expose an interface to scripts I would consider using ScriptEngine.

Well it is more of just the sort of thing that if I could do it, it would make me happy rather than actually be very effective.

I am making a game where there are loads of items which will affect the player in different ways and I just wanted to have it so that I could just have the two strings, the variable to change and the value to change it to.

Actually, there are two routes you can take that I think you’d like over that one. If you think they’re too much work and the project isn’t serious than your can probably skip them and just use raw reflection.

The first (easier to do, but poorer design IMO) is to use ScriptEngine, you can expose your entire player object to the script and let it do whatever it wants to your character object. ScriptEngine will let you use tons of different scripting language implementations - but it makes most sense to use javascript. You can than write something like (in your item’s script file):


function onConsumed(player)
{
    if(player.health <= 5)
        player.speed-=5;

    game.say("omnomnom speed");
}

You could expose other variables to the script (like game) which might have a function called ‘say’ to expose a message on the screen.

The more complex but proper solution would be to expose a inner class that accurately represents your character object providing access to members (like speed) which should be protected so that you can limit access to those members to just the script. - I thoroughly implemented scripting into my engine and it is relatively easy to do.

http://content.gpwiki.org/index.php/Java:Tutorials:Scripting
http://docs.oracle.com/javase/6/docs/api/javax/script/ScriptEngine.html

Java is a strongly statically typed language, so it is no good practise to do something like this.

Of course you can use HashMaps all over the place, like:


Map playerSkills = new HashMap<String, Integer>();

...
playerSkille.set("fireBall", 3);

Or pass only Object.class objects around with a lot of instanceOf , but than what is the point to use Java. If you like to code like this perhaps give javascript(browser games) or phyton a try.

When you code in Java you always have to think about types. So you have an item which can be applied to what?
Only the player or also humans, monsters, a table??

When you have this figured out, you normally build up an inheritance tree.

Thing: has a position
Table is a Thing
LivingThing is a Thing, but also has healt
Monster is a LivingThing, has loot
Zombie is a Monster
Human is a LivingThing, has a name
Player is a Human, has items

And in the and you do something like this


class HealthPotion extends Item
{
  void applyTo(LivingThing someon);
}

If you’re going for a casual game, that’s a good idea. For most casual games that would work fine.

However, you can’t have concrete classes like HealthPotion if you are developing a flexible game engine as it would require someone to write and compile java code to the library just to add an item like potion, poison (insert any other consumable here.)

Having a single class, Item, and then an enumeration of the general type of item it is (weapon, consumable, armor, general) you can act on the item appropriately and invoke script routines appropriately when it is equip, or consumed or attacked with.

OP is clearly a beginner and my response was directed at his capabilities.
I think it is imported to just give him a general idea and not confuse him with implementations details as you are doing.

As mentioned countless times on this board, do NOT over complicate what you want to achieve.

Your suggestion to use scripts or other ways for configuration does not cover OPs problem very well. Using a scripting in a game-framework is a whole other topic.

PS: I my humble opinion a scripting has no really a place in a Java game. Before you implement your hot-reload, script loading and connection framework, I would already have written 100s of different Item classes. Second point: no need to use scripting to have an extendable framework. Third point: if you are concerned about turn-around times while development(change-compile-run) use something industrie-tested like JRebel.

Another possibility is to use the Properties Pattern.

A long but interesting article explaining the Properties pattern as implemented in an RPG. This article talks about a Java implementation.

This approach would allow you to stick with plain Java code while skipping the overhead of reflection and gaining the additional flexibility. You will still lose the nice features of static typing and compiler checking, however.