Me and my friend are working on a game where we want to have layered images in the background, and buttons to navigate through them on top of those images. One image could stay the same, while the other is constantly changing. To do this, I thought the render and tick philosophy would be great.
For those of you that have seen those cheesy visual novel games from japan, that is basically what we are working on.
Update: So I used many of your suggestions below. My new problem is my JButton will disappear underneath the picture before I scroll over it. When I add the super.paintComponent(g) as suggested, everything disappears immediately as it appears.
The code of my main method looks like this currently:
package Urban.Blade.Package;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
import Urban.Blade.Package.gfx.*;
import javax.swing.*;
public class MainGame extends JPanel{
private static final long serialVersionUID = 1L;
public static final int WIDTH = 300, HEIGHT = 300, SCALE = 2, PICSCALE = 0;
public BufferedImage background1;
public BufferedImage testCharacter1;
static JButton b1 = new JButton();
static JButton b2 = new JButton();
static JPanel j1 = new JPanel();
static JPanel j2 = new JPanel();
static JFrame frame = new JFrame("Urban Blade");
static MainGame mGame = new MainGame();
static JLayeredPane lJ = new JLayeredPane();
static JLayeredPane lJ2 = new JLayeredPane();
public static void main(String[] args){
lJ.setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
lJ.setMaximumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
lJ.setMinimumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
lJ.setBounds(0, 0, WIDTH * SCALE, HEIGHT * SCALE);
mGame.setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
mGame.setMaximumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
mGame.setMinimumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
mGame.setBounds(0, 0, WIDTH * SCALE, HEIGHT * SCALE);
frame.setSize(WIDTH * SCALE, HEIGHT * SCALE);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
lJ.setLayout(null);
frame.add(mGame);
frame.add(lJ);
j2.setLayout(new GridLayout());
j2.setSize(WIDTH * SCALE, HEIGHT * SCALE);
j2.setLocation(0, 0);
j1.setLayout(new GridLayout());
j1.setSize(100, 25);
j1.setLocation(225*SCALE, 250*SCALE);
j1.add(b1);
b1.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent me) {
System.out.println("CLICKED");
}
});
frame.setVisible(true);
lJ.add(j2);
lJ.add(j1);
lJ.setComponentZOrder(j2, 1);
lJ.setComponentZOrder(j1, 0);
mGame.init();
mGame.paintComponent();
}
public void init(){
ImageLoader loader = new ImageLoader();
background1 = loader.load(new File("res/testBackground.png"));
testCharacter1 = loader.load(new File("res/testForeground.png"));
}
public void paintComponent(){
Graphics g = j2.getGraphics();
g.drawImage(background1, 0, 0, WIDTH * SCALE, HEIGHT * SCALE, null);
g.drawImage(testCharacter1, 0, 0, WIDTH * SCALE, HEIGHT * SCALE, null);
super.paintComponent(g);
g.dispose();
}
}
Your problem is you are trying to mix normal GUI drawing with custom drawing in a BufferStrategy. If you are using a BufferStrategy, then update/paint operations don't work. One option is to use normal paint/paintComponent overrides with a null layout manager so you can position the button wherever you want and draw your images behind them.
If you want to continue to use BufferStrategy you can try to manually call paint passing in your Graphics object. Not sure if this will work since I have never tried it.
If you use the first option you have to make sure that the JPanel has a transparent background instead of opaque. You also have to call super.paint() after you draw your images so the JDK drawing will occur after your custom drawing and the buttons will appear on top.