当前位置: 首页 > 知识库问答 >
问题:

在JavaFX中为画布创建一个“阴影”层?

韩靖琪
2023-03-14

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

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

我知道我对JavaFX可能还有很多不了解的地方,因为我以前只做过一些应用程序。有人对如何实现此功能有任何建议吗?如果我能让它看起来比原版更好就好了。

下面是老游戏的一张图,供参考。

共有2个答案

赵正雅
2023-03-14

我创建了两个画布,一个是“明亮的世界”-画布,另一个是一个“夜晚叠加”-画布上只有一个夜晚灰色的矩形和灯光图像。如果我想在游戏中加入夜晚,我会使用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
    }

编辑:后来我意识到,双画布的方法对性能不好。我推荐直接在世界画布上画阴影层。

结果:

杨经武
2023-03-14

当所有的游戏实体和HUD被绘制时,我能够通过绘制中间的黑色层来实现类似于我正在寻找的东西。我用80%的不透明度画它,然后我用5%的不透明度和混合模式SRC_OVER画我的手电筒多边形。它花了很多时间来玩不同的混合模式,但乘肯定不是要走的路。

 类似资料:
  • 所有人都喜欢好看的阴影效果,它们可能是Adobe Photoshop中使用最广泛的效果了,并且也经常在Web和图形设计中使用。如果操作正确,它们实际上确实能够增加图像真实感。然而,如果操作不当,它们也可能完全毁掉一个图像。 在画布中创建阴影效果是相对较简单的,它可以通过4个全局属性进行控制。这些属性是shadowBlur、shadowOffsetX、shadowOffsetY和shadowColo

  • 这似乎不起作用...我试图制作一个具有多个依赖项的uber jar,One-Jar似乎过时了,我不能使用默认的gradle uberJar构建器或影子jar。

  • 问题内容: 我有一个带标签的导航栏,我希望在打开的标签上有一个阴影,以使其与其他标签区分开。我还希望整个选项卡部分上有一个阴影(请参阅底部的水平线),以阴影除打开的所有选项卡的底部。 我将使用CSS3的属性来执行此操作,但是我无法找出仅对所需部分进行着色的方法。 通常,我会用内容区域(较高)遮盖打开的选项卡的底部阴影,但是在这种情况下,内容区域本身会带有阴影,以便最终覆盖该选项卡。 标签布局 阴影

  • 问题内容: 有没有办法只在底部放阴影?我有一个菜单,彼此相邻有2张图像。我不想要正确的阴影,因为它会重叠正确的图像。我不喜欢为此使用图像,因此有一种方法可以将其仅放置在底部,例如: 或类似的? 问题答案: 更新4 与更新3相同,但具有现代的CSS(=较少的规则),因此不需要在伪元素上进行特殊定位。 更新3 我以前所有的答案都一直在使用额外的标记来创建此效果,而这并不是必需的。我认为这是一种 更 清

  • 阴影 Unity 的灯光可以将 阴影 从一个游戏对象投射到自身的其他部分或是附近的其他游戏对象上。阴影以『扁平』的方式体现游戏对象的尺寸和位置,因此可以为场景添加一定程度的深度和真实感。 场景视图中的游戏对象正在投射阴影 阴影如何工作? 考虑一种最简单的情况,在场景中只有单个光源。光线从光源出发并沿着直线传播,最终可能会碰撞到场景中的游戏对象。一旦光线碰撞到某个游戏对象,光线将无法继续传播和照亮前

  • 创建一个Canvas画布,用于显示WebGL的渲染结果,canvas元素和div等元素一样是HTML的一个元素,只是Canvas画布具有2D和3D绘图功能。 <!--canvas标签创建一个宽高均为500像素,背景为蓝色的矩形画布--> <canvas id="webgl" width="500" height="500" style="background-color: blue"></canv