【问题标题】:How to create interactive graphic with Vaadin?如何使用 Vaadin 创建交互式图形?
【发布时间】:2014-11-06 12:02:41
【问题描述】:

我想开发一个简单的互动游戏(比如 arcanoid)。我已经实现了一个菜单和不同的视图,现在我需要开发实际的游戏(画飞球,一些可移动的平台),我不知道该怎么做。我需要像画布这样的东西,我可以在其中每帧绘制我的图形。

我尝试使用Canvas 和计时器来实现这一点。但它不想更新图形本身,而只是当用户点击屏幕或类似内容时。我还看到了 com.google.gwt.canvas.client.Canvas,但我不明白如何在 Vaadin 应用程序中使用它。

接下来我的问题是:是否可以以任何方式以高帧率在每一帧绘制一些图形?如果可能,我该怎么做?

附:我用的是 Vaadin 7.3.3。

【问题讨论】:

  • “高帧率”将很难实现,因为我们在这里讨论的是全 HTML。 Vaadin 将封装所有这些,但正因为如此,您在某些时候遇到性能问题。您最好的建议是:忘记纯 HTML (JS) 网站中的“游戏”,除非您使用的元素可以保证加速 - vaadin 中的画布支持是 BETA,因此不会总是按预期工作。您使用了错误的语言,HTML 不是为游戏制作的。
  • 好的,但是我看到了很多关于 HTML 和 JS 的简单游戏。我知道我无法用 3D 实现 AAA 游戏,但我只想要一个会飞的 2d 球 =)。是否无法使用 Vaadin,也许需要一些自定义?
  • 而且我使用“不稳定”画布没有任何问题,它不是商业产品,仅供学习。
  • 试图通过最困难的方法(游戏)“学习”任何东西肯定会导致失败。暂时不要试图接管世界,从简单的网站开始,在这些网站上继续使用简单的 JS,最后开始学习真正的编程语言,如 Java 或类似的东西。您可以使用 Java 创建 2D/3D 游戏,甚至可以在浏览器中访问它们...
  • 感谢您的建议。但我仍在寻找我的问题的答案。我不太了解 Vaadin(也不太了解 Java),但据我所知,它根据 Java 代码(通过使用 GWT)生成 JS+HTML。所以我在寻找一种使用客户端 Canvas 来绘制一些简单的交互式图形的方法。

标签: java canvas vaadin


【解决方案1】:

稍后添加:

Here is a link to my educational project with implementation below. 如果它对某人有帮助,我会很高兴。

原始答案

嗯...我自己找到了解决方案。首先,我创建了自己的小部件——“客户端”组件(根据这个article)。

客户端部分:

public class GWTMyCanvasWidget extends Composite {

public static final String CLASSNAME = "mycomponent";
private static final int FRAMERATE = 30;

public GWTMyCanvasWidget() {
    canvas = Canvas.createIfSupported();
    initWidget(canvas);
    setStyleName(CLASSNAME);
}

连接器:

@Connect(MyCanvas.class)
public class MyCanvasConnector extends AbstractComponentConnector {    

    @Override
    public Widget getWidget() {
        return (GWTMyCanvasWidget) super.getWidget();
    }

    @Override
    protected Widget createWidget() {
        return GWT.create(GWTMyCanvasWidget.class);
    }
}

服务器端部分:

public class MyCanvas extends AbstractComponent {

    @Override
    public MyCanvasState getState() {
        return (MyCanvasState) super.getState();
    }
}

然后我只需在我的视图上添加MyCanvas 组件:

private void createCanvas() {
    MyCanvas canvas = new MyCanvas();
    addComponent(canvas);
    canvas.setSizeFull();
}

现在我可以在 Canvas 上绘制任何东西(在 GWTMyCanvasWidget 的客户端),性能非常好 =)。示例:

public class GWTMyCanvasWidget extends Composite {

    public static final String CLASSNAME = "mycomponent";
    private static final int FRAMERATE = 30;
    private Canvas canvas;
    private Platform platform;
    private int textX;

    public GWTMyCanvasWidget() {
        canvas = Canvas.createIfSupported();
        canvas.addMouseMoveHandler(new MouseMoveHandler() {
            @Override
            public void onMouseMove(MouseMoveEvent event) {
                if (platform != null) {
                    platform.setCenterX(event.getX());
                }
            }
        });
        initWidget(canvas);
        Window.addResizeHandler(new ResizeHandler() {
            @Override
            public void onResize(ResizeEvent resizeEvent) {
                resizeCanvas(resizeEvent.getWidth(), resizeEvent.getHeight());
            }
        });
        initGameTimer();
        resizeCanvas(Window.getClientWidth(), Window.getClientHeight());
        setStyleName(CLASSNAME);
        platform = createPlatform();
    }

    private void resizeCanvas(int width, int height) {
        canvas.setWidth(width + "px");
        canvas.setCoordinateSpaceWidth(width);
        canvas.setHeight(height + "px");
        canvas.setCoordinateSpaceHeight(height);
    }

    private void initGameTimer() {
        Timer timer = new Timer() {
            @Override
            public void run() {
                drawCanvas();
            }
        };

        timer.scheduleRepeating(1000 / FRAMERATE);
    }

    private void drawCanvas() {
        canvas.getContext2d().clearRect(0, 0, canvas.getCoordinateSpaceWidth(), canvas.getCoordinateSpaceHeight());
        drawPlatform();
    }

    private Platform createPlatform() {
        Platform platform = new Platform();
        platform.setY(Window.getClientHeight());
        return platform;
    }

    private void drawPlatform() {
        canvas.getContext2d().fillRect(platform.getCenterX() - platform.getWidth() / 2, platform.getY() - 100, platform.getWidth(), platform.getHeight());
    }
}

【讨论】:

  • 我建议您通过 BitBucket 或 GitHub 等服务共享您的项目。这对其他人会很有帮助和教育意义。
  • 当然,我可以分享这个项目。特别是,如果有人觉得它有用:)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-16
  • 2023-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多