We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I am developing a game for helping people to learn coding. Processing 3 in Java mode.
There is a Player class in my code, with functions like player.moveForward(2)
, player.turnRight()
and etc. When these are called, the player object recalculates it's position and in the next draw()
cycle it shows in the new place. So far so good.
I would like to let the user move the player in the map using code. So, if I read user input and store "player.moveForward(5);" in a string
, how do I make this arbitrary piece of code to be executed during runtime?
I can't parse the code myself because I want people to be able to write more complex things, such as for (int i = 0 ; i < 3; i++) { player.moveForward(); }
.
I tried to use the ScriptEngine
to dynamically create an script, inject my player
object (which handles the calculations), run the user commands, then read the final position to apply changes on the GUI. But it didn't work, the player object doesn't seem to be properly injected, properties and method are not available in the javascript context. If that's really the way to go, what am I doing wrong here?
println(player.colour); // this works fine
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("javascript");
engine.put("player", player);
String instruction = "print(player.colour);"; // this doesn't work as expected
try {
engine.eval(instruction);
} catch (Exception ex) {
println (ex.getMessage());
}
Output for the piece of code above:
white
undefined
The Player
class has a public String colour;
. In the example above I get "undefined" as output. How should I implement my classes to be able to see their properties and methods in the javascript side?
Answers
That's fairly complex. Java has to be compiled before its run (it's Object Oriented). So I doubt if it's even possible.
Based on the features you want, you may as well just write code to run strings yourself. See this excellent example by @Chrisir which has many features - https://forum.processing.org/two/discussion/20706/how-3d-turtle-like-in-logo-but-3d-math-problem#latest
public
for us behind the scene if they don't have 1 already for ".pde" tab files. :bzpublic
if something needs them that way in order to access them. :-\"public
. :>Quite a few examples are included as textfiles and you can load and execute them (hit # or click mouse on play button)
@paulera -- re:
For a related project you might be interested in checking out @quark 's QScript -- and, in particular, the example "Scripting Game Objects" part 1/2. The runtime-reprogrammable scripting control of game objects is done through a G4P code editor built into the sketch itself.
As @GoToLoop said, classes must be declared as public.
Just changing my class declaration to
public class Player {
allowed them to be shared on the fly with the script. And solved my problem.EXAMPLE
Output:
Glad it's working now! <:-P
Remember, methods don't need an explicit
public
b/c PDE's pre-processor already prefix them for us.Also we can use
'
instead of"
in JS.So
"obj.message = \"Hello World!\";"
can be written like this:"obj.message = 'Hello World!';"
. :DYou should also consider loadStrings() your Nashorn ".js" scripts.
Visit this forum thread for some utility functions I did for ScriptEngine: :bz
https://forum.Processing.org/two/discussion/17161/eval-js-with-power-general-help-on-eval-js-eval
Thanks @GoToLoop, very much appreciated.