Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swing simple overlay [duplicate]

I'm in the process of making a 2D game in which a player roams around a maze. screenshot of the GUI

I want to implement some sort of "darkness", even something as simple as a transparent shape around the player surrounded by black, like this: mock-up screenshot

The problem I've found using Swing is that, while this is possible, it means having to redraw everything, which produces an annoying "flickering" effect every time it happens. Is there a way to make some sort of overlay, or just a good way of doing this in general in Swing? I'm not very experienced with GUI/visual stuff right now so I'd like to stick with Swing if possible.

EDIT: This is my method to paint the background, i.e. the floor, walls and exit:

    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);
                }
            }
        }
    }
}

I then have "paintPlayer" and "paintEnemy" methods to paint those sprites each time they move. The background only gets painted once, at the start.

like image 498
Touchdown Avatar asked Jan 20 '16 16:01

Touchdown


1 Answers

Possibilities:

  • You may be drawing directly in a top level window such as a JFrame. If so, don't draw in the paintComonent method of a JPanel so that you use the automatic double buffering availabe.
  • You may be reading in an image from within a painting method, and if so, don't. These methods must paint and paint only and must be blindingly fast.
  • You may not be using a BufferedImage in your painting method but creating an image de-novo, and if so, don't. Draw the BufferedImage using Graphics#drawImage(...).
  • Perhaps your animation code is off. You may be calling repaint() from within paint or paintComponent, something that should never be done.
  • And the possible guesses can go on and on...

Edit

Your code shows that you may be re-paint the maze with every painting iteration -- don't do this. Instead draw the above into a BufferedImage, and draw that image within your paintComponent method. Then change the BufferedImage if the walls structurally change.

Note that the maze's logical structure (the non-visual data that tells which wall is open, which is closed) should be part of your program's data, and not its code.

like image 105
Hovercraft Full Of Eels Avatar answered Oct 02 '22 23:10

Hovercraft Full Of Eels