GWT编译错误:子类上缺少接口方法(PlayN HTML)

6

免责声明:我对GWT/PlayN还不熟悉,所以我可能会犯一些显而易见的错误。

当我有一个基本(入门级)的PlayN项目时,我的BlahGame类方法实现了Game接口,该接口需要三个方法:initpaintupdate。起始类大致如下:

public class BlahGame implements Game { 
  public void init() { ... }
  public void paint(float alpha) { ... }
  public void update(float alpha) { ... }
}

我创建了一个`BaseGame`类来实现游戏,代码如下:
public class BaseGame implements Game { 
  public void init() { ... }
  public void paint(float alpha) { ... }
  public void update(float alpha) { ... }
}

我的主游戏类现在成为了 BaseGame 的子类,代码如下:
public class BlahGame extends BaseGame {
  public void init() { ... base.init(); ... }
}

所有Java代码都能够编译并正常工作。但是当我尝试将游戏的HTML版本进行GWT编译时,出现了以下错误:

com.google.gwt.dev.jjs.InternalCompilerException: Failed to get JNode
    at com.google.gwt.dev.jjs.impl.TypeMap.get(TypeMap.java:140)
    at com.google.gwt.dev.jjs.impl.TypeMap.get(TypeMap.java:71)
    at com.google.gwt.dev.jjs.impl.BuildTypeMap.getType(BuildTypeMap.java:730)

...


      [ERROR] <no source info>: public class com.deengames.BaseGame
    extends java.lang.Object
    implements : playn.core.Game
/*   methods   */
public void <init>() 
public void init() 
[unresolved] public void paint(float) 
[unresolved] public void update(float) 
[unresolved] public int updateRate() 

我不确定我在这里缺少什么。是一些GWT类需要更新吗?还是其他什么原因?我原本期望HTML版本能够编译,因为Java版本可以编译;类的签名不应该因为子类而改变。
编辑:我正在使用一个全新的、样板式的PlayN项目。在这个类中,如果我扩展基类并实现接口,它仍然无法编译;只有删除基类扩展才能正常工作。
2个回答

7
这就是你的问题所在:
  [ERROR] <no source info>: public class com.deengames.BaseGame

你把代码放在了顶层包 com.deengames 中。我猜你的 GWT 模块文件也在同一目录下,可能是类似于 com/deengames/MyGame.gwt.xml。GWT 模块文件必须为 GWT 将看到的所有代码指定包目录。
当你使用 PlayN Maven 原型生成项目时,它具有以下结构:
core/src/main/java/com/foozle/core/Barzle.java
core/src/main/java/com/foozle/resources/images/bg.png
html/src/main/java/com/foozle/Barzle.gwt.xml
html/src/main/java/com/foozle/html/BarzleHtml.java

所有游戏代码都在com.foozle.core包中,资源文件在com.foozle.resources包中。如果您查看生成的Barzle.gwt.xml文件,您会看到:

<module rename-to='barzle'>
  <inherits name='playn.PlayN'/>
  <source path='core'/>
  <source path='html'/>
  <public path="resources" />
  <entry-point class='com.foozle.html.BarzleHtml'/>
</module>

这两个<source>标记把com.foozle.corecom.foozle.html子包明确地添加到了GWT项目中。在GWT模块文件中没有被明确列出的任何内容都将被忽略。由于GWT指定这些包的方式,无法将顶层包添加到GWT项目中。因此不能使用:

<source path=""/>

或者:

<source path="."/>

您需要将所有代码放在子包中,并在 GWT 模块文件中明确列出这些子包。


好的。两个后续问题:1)有什么适合我们这些 GWT 新手的好教程吗?2)我该如何创建一个新模块?(通常我会将一些辅助/“框架”类分离到一个单独的模块中) - ashes999
1
该页面提供了一个很好的GWT项目解剖概述。一般情况下,您不会直接使用GWT,所以标准教程对您并没有太大帮助。创建模块很简单,只需在想要向GWT / PlayN公开的源目录中创建一个SomeName.gwt.xml文件,并为要由GWT / PlayN使用的子包添加<source path =" pkg "/>条目。如果您将这些代码打包成用于游戏的jar文件,则需要包含.java文件(及.gwt.xml文件)。 - samskivert

1
我猜测在 BlahGame.gwt.xml 文件中可能存在问题。确保所有的目录都作为源文件被包含在该文件中。其结构应该类似于:
<module rename-to='blah'>
  <inherits name='playn.PlayN' />

    <source path='core'/>
    <source path='common'/>
     ... etc ...
    <source path='html'/>

    <public path="resources" />

    <entry-point class='full.namespace.BlahGameHtml' />

</module>

此外,你的BlahGameHtml.java类应该长这样:
public class BlahGameHtml extends HtmlGame
{

    @Override
    public void start()
    {
        HtmlAssetManager assets = HtmlPlatform.register().assetManager();
        assets.setPathPrefix("blah/");
        PlayN.run(new BlahGame());
    }

}

还要确保gwt.xml文件在classes的上一级目录中,这样classes就在子目录中。这将允许您在gwt.xml文件中的“source”标签中包含源目录名称。根据您提供的错误消息,GWT编译器无法看到Java类的源文件。GWT需要源代码才能将代码转换为JavaScript。希望这可以帮助您。 - prageeths
不知道你是否已经把这个搞定了,还是希望我去看看? 我接下来几天比较空闲,如果你需要的话,我可以帮你看一下。 - prageeths
如果您能够看一下,那将不胜感激。我在这个问题上遇到了难题。 - ashes999
顺便说一下,这适用于扩展任何游戏基类。 - ashes999
我猜samskivert的解释比我的更清楚。 :P 我在早些时候的评论中提到过,但更像是一行答案(哈哈)- (还要确保gwt.xml文件位于类的上级目录;这样类就在子目录中。这将允许您在gwt.xml文件中的“source”标记中包含源目录名称。) 无论如何,很高兴你解决了它! 干杯! :) - prageeths
显示剩余4条评论

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