摇摆简单叠加

Tou*_*own 5 java graphics swing

我正在制作一个2D游戏,其中玩家在迷宫中漫游。 GUI的屏幕截图

我想实现某种“黑暗度”,甚至像被黑色包围的玩家周围的透明形状一样简单,例如: 模拟屏幕截图

我发现使用Swing的问题是,尽管这是可能的,但它意味着必须重新绘制所有内容,这会在每次发生时产生令人讨厌的“闪烁”效果。有没有一种方法可以进行某种形式的叠加,或者只是在Swing中进行叠加的一种好方法?我现在对GUI /可视化工具还没有足够的经验,所以如果可能的话,我想坚持使用Swing。

编辑:这是我的方法来绘制背景,即地板,墙壁和出口:

    public final void paintBG(Graphics g){
    g.setColor(Color.LIGHT_GRAY); // Screen background
    g.fillRect(0, 0, getWidth(), getHeight());
    // Draw the Walls of the maze
    // scalex and y are for scaling images/walls within the maze since I let users specify how big they want the maze
    for (int j = 0; j < this.height; j++, y += scaley) {
        x = 20;
        for (int i = 0; i < this.width; i++, x += scalex) {
            if (!(maze[j][i].northwall.isBroken())) // If the north wall isn't broken
            {
                g.drawImage(walltile, x, y, scalex, scaley / 5, null); // Draw a wall there (image, xpos, ypos, width, height, observer)
            }
            if (!(maze[j][i].eastwall.isBroken())) // etc
            {
                g.drawImage(walltile, x + scalex, y, scalex / 5, scaley, null);
            }
            if (!(maze[j][i].southwall.isBroken())) {
                g.drawImage(walltile, x, y + scaley, scalex, scaley / 5, null);
            }
            if (!(maze[j][i].westwall.isBroken())) {
                g.drawImage(walltile, x, y, scalex / 5, scaley, null);
            }

            if ((j == mazeinfo.getTargetM()) && (i == mazeinfo.getTargetN())) {
                // Draw the exit
                g.drawImage(jeep, x + (scalex / 2), y + (scaley / 2), cx, cy, null);
                g.setColor(Color.LIGHT_GRAY);
                if (maze[j][i].northwall.isEdge()) {
                    // Paint over the edge creating a 'way out'
                    g.fillRect(x, y, scalex, scaley / 4);
                } else if (maze[j][i].eastwall.isEdge()) {
                    g.fillRect(x + scalex, y, scalex / 4, scaley);
                } else if (maze[j][i].southwall.isEdge()) {
                    g.fillRect(x, y + scaley, scalex, scaley / 4);
                } else if (maze[j][i].westwall.isEdge()) {
                    g.fillRect(x, y, scalex / 4, scaley);
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,我有了“ paintPlayer”和“ paintEnemy”方法来在每次移动时绘制这些精灵。一开始,背景仅绘制一次。

Hov*_*els 4

可能性:

  • 您可以直接在顶级窗口(例如 JFrame)中绘图。如果是这样,请不要在 JPanel 的 PaintComonent 方法中进行绘制,以便使用可用的自动双缓冲。
  • 您可能正在从绘画方法中读取图像,如果是这样,请不要这样做。这些方法只能不断地绘画,而且速度必须快得令人眼花缭乱。
  • 您可能没有在绘画方法中使用 BufferedImage,而是从头创建图像,如果是这样,请不要使用。使用 绘制 BufferedImage Graphics#drawImage(...)
  • 也许您的动画代码已关闭。您可能repaint()从paint或paintComponent内部调用,这是永远不应该做的事情。
  • 可能的猜测还可以继续下去……

编辑

您的代码显示您可能会在每次绘制迭代时重新绘制迷宫 - 不要这样做。相反,将上面的内容绘制到 BufferedImage 中,并在您的 PaintComponent 方法中绘制该图像。如果墙壁结构发生变化,则更改 BufferedImage。

请注意,迷宫的逻辑结构(告诉哪堵墙打开、哪堵墙关闭的非可视数据)应该是程序数据的一部分,而不是其代码的一部分。