【问题标题】:Creating a "shadow" layer for the canvas in JavaFX?在 JavaFX 中为画布创建“阴影”层?
【发布时间】:2023-03-16 00:56:01
【问题描述】:

我目前正在重新制作几年前使用 Swing/AWT 制作的游戏,这次使用的是 JavaFX。我目前的困境是原始游戏有一个“手电筒”,我首先在其中创建了一个空白黑色图层,然后我将在该图层上创建一个多边形并使用混合模式从该图层中减去它。从那里开始,图层被绘制成透明的,看起来一切都是黑暗的,玩家有一个手电筒。

我无法弄清楚如何在 JavaFX 中实现这一点。我想我可以创建一个空白的黑色图像,并且有办法从中创建一个 GraphicsContext,我可以设置一个混合模式来从图像中减去,但是图像不支持 JavaFX 中的这种类型的渲染,并且在事实上,WritableImage 是一个单独的类,它只允许使用 PixelWriter,我必须手动设置每个像素。

我知道关于 JavaFX 可能还有很多我不了解的地方,因为我之前只用它制作了几个应用程序。有人对如何实施此功能有任何建议吗?要是能比原版好看就好了。

这是旧游戏中的图片供参考。

【问题讨论】:

    标签: java javafx graphics


    【解决方案1】:

    通过在绘制所有游戏实体和绘制 HUD 之间绘制黑色层,我能够实现类似于我正在寻找的东西。我以 80% 的不透明度绘制它,然后以 5% 的不透明度和混合模式 SRC_OVER 绘制我的手电筒多边形。尝试了很多不同的混合模式,但 MULTIPLY 绝对不是要走的路。

    【讨论】:

    • 我真的希望有更好的方法来使用 JavaFX 实现这种效果,但我想我应该很高兴它是可能的。我知道 JavaFX 不适合用于游戏。
    【解决方案2】:

    我创建了两个 Canvas,一个是“bright-world”-canvas,另一个是“night-overlay”-canvas,其中只有一个夜灰色矩形和浅色图像。 如果我想在我的游戏中使用夜晚,我会使用 Blendmode.MULTIPLY 添加夜间画布。

    在这里我创建了夜间叠加层:(简化)

    private void renderLightEffect()
    {
            ShadowMaskGc.setFill(shadowColor);
            ShadowMaskGc.fillRect(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
            for (Sprite sprite : passiveCollisionRelevantSpritesLayer)
               {
               Image lightImage = lightsImageMap.get(lightSpriteName);
               ShadowMaskGc.drawImage(lightImage, sprite.getPositionX() + sprite.getHitBoxOffsetX() + sprite.getHitBoxWidth() / 2 - lightImage.getWidth() / 2 - camX, sprite.getPositionY() + sprite.getHitBoxOffsetY() + sprite.getHitBoxHeight() / 2 - lightImage.getHeight() / 2 - camY);
               }
    
    }
    

    创建夜间图层后,在每个渲染周期将其添加到窗格中:

    root.getChildren().clear();//root-Pane
    root.getChildren().add(worldCanvas);//The world with all sprites
    //LightMap
    if (shadowColor != null) {//To switch on/off night
        renderLightEffect(currentNanoTime);//update of the positions of the light points
    root.getChildren().add(shadowMask);//grey Canvas with some light points
    shadowMask.setBlendMode(BlendMode.MULTIPLY);//Here is the magic merge the colors
        }
    

    编辑:后来我意识到,两画布方法不利于性能。我建议直接在世界画布上绘制阴影层。

    结果:

    【讨论】:

    • 感谢您的努力,但这个问题已经有将近 4 年的历史了,而且我不仅迁移到了 Slick2D,而且一年前我就停止了这款游戏。
    • 我知道这对你来说为时已晚,但我希望它会在未来对其他人有所帮助。
    猜你喜欢
    • 2019-07-22
    • 2013-08-08
    • 2019-01-05
    • 1970-01-01
    • 2020-09-26
    • 2012-05-25
    • 1970-01-01
    • 2016-04-15
    • 1970-01-01
    相关资源
    最近更新 更多