开发基于java的游戏,使用AI的javax.script;
public class AI implements Runnable {
private boolean alive = true;
String scriptStr;
ScriptEngine scriptEngine;
ScriptContext scriptContext;
Bindings engineScope;
public AI() {
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
scriptEngine = scriptEngineManager.getEngineByName("JavaScript");
scriptContext = new SimpleScriptContext();
engineScope = scriptContext.getBindings(ScriptContext.ENGINE_SCOPE);
engineScope.put("scene", Scene.instance);
try {
scriptStr = new Scanner(new File(getClass().getResource("ai.js").getPath())).useDelimiter("\\Z").next();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (alive) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Iterable<IUnit> units = Scene.instance.getUnits();
for (IUnit unit : units) {
if (unit.isAlive()) {
engineScope.put("unit", unit);
try {
scriptEngine.eval(scriptStr, scriptContext);
} catch (ScriptException e) {
e.printStackTrace();
}
}
}
}
}
}在上面的代码中,我有一个场景,它提供了迭代的单位。我想为所有的单元调用完全相同的js代码("ai.js"),在这些单元中,单元将决定要做什么。
问题是我希望每个单元都有自己的上下文数据。因此,每次我评估一个单元的ai.js时,它们不会是无状态和无记忆的。
正确的方法是什么?
我应该显式地为每个单元使用类似于SpringContext的东西吗?
或者,是否可以像运行单元类上下文中的函数一样运行ai.js?
发布于 2016-05-25 05:03:48
我使用单个ScriptEngine实现了这一点,每次执行都有一个SimpleScriptContext -尽管它可能是针对每个线程的。
创建上下文后,必须在该上下文中执行它,然后它才能供您的scriptlet使用。
为了优化库的重复包含,我在创建ScriptEngine时将其编译为CompiledScript。
我编译每个scriptlets对象,然后使用eval(context)方法执行它们。
在我的测试中,这足以创建线程安全性。
https://stackoverflow.com/questions/18211724
复制相似问题