将JMonkey教程翻译为JRuby

3
我已经将所有教程翻译并放到了初学者#5,但是我不太懂Java,不知道如何移植这些代码行:
private ActionListener actionListener = new ActionListener() {
  public void onAction(String name, boolean keyPressed, float tpf) {
    if (name.equals("Pause") && !keyPressed) {
      isRunning = !isRunning;
    }
  }
};

private AnalogListener analogListener = new AnalogListener() {
  public void onAnalog(String name, float value, float tpf) {
    ...
  }
}

这个怎么实现呢?

把那些翻译好的教程公开发布岂不是一件好事? :) - Redoman
哦,那可能本来是有的;但我不确定它是否仍在我的电脑上,因为已经很久没有使用了…… - Jwosty
3个回答

1
从JRuby调用Java所述,您可以使用闭包转换,其中块可用于定义Java接口行为。以下类似的代码应该可以工作:
l = lambda { |name, pressed, tpf| running = !running if name == 'Pause' && !pressed }
input_managers.add_listener(l, ['Left', 'Right', 'Rotate'])

我仍然无法让它工作;你的方法会引发错误 org.jruby.exceptions.RaiseException: (TypeError) cannot convert instance of class org.jruby.RubyArray to class java.lang.String。如果我将其分开成单独的参数或调用 to_java,它就不会执行该块。我不知道出了什么问题。 - Jwosty
这是文件(它由另一个文件加载,设置类路径)。 - Jwosty
@Jwosty:你可以尝试在输入管理器中添加@,然后将数组转换为逗号分隔的形式:@input_manager.add_listener(l, 'Left', 'Right', 'Rotate')。这里可能是可变参数的问题。 - Sébastien Le Callonnec
这是我用来编写上面代码的简单示例:https://gist.github.com/2169349 - Sébastien Le Callonnec
无法将其转换为实例变量,因为它是一个方法(您是否意味着@input_manager = input_manager?),而将参数分开似乎也不起作用。 - Jwosty
差一点就成功了。我已经解决了,但还是谢谢你的帮助! :) - Jwosty

0

我将动作监听器包装在一个方法中,该方法使用JRuby的:impl方法返回一个包含ActionListener的对象

def isRunningActionListener
  return ActionListener.impl do
    |command, name, keyPressed, tpf|
      case command
        when :onAction
          if name.eql?("Pause") && !keyPressed
            isRunning = !isRunning;
          end
      end
   end
end

您还可以创建自己的ActionListener类,其中包括ActionListener ...

class YourActionListener
  include ActionListener
  def onAction command, name, keyPressed, tpf
    #your code here
  end
end

创建自己的类可能是更好的选择,因为它不那么冗长,更易于阅读和理解。

0
啊,找到答案了。原来它们是匿名内部类。在JRuby中,你可以创建一个实现了Java接口的类,就像这样:
class RBActionListener
  # This is how you implement Java interfaces from JRuby
  include com.jme3.input.controls.ActionListener

  def initialize(&on_action)
    @on_action = on_action
  end

  def onAction(*args)
    @on_action.call(*args)
  end
end

class HelloJME3
  # blah blah blah code blah blah blah

  def register_keys
    # ...
    ac = RBActionListener.new {|name, pressed, tpf @running = !@running if name == "Pause" and !pressed}
    input_manager.add_listener(ac, "Pause")
  end
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接