首页 > 解决方案 > 在Java中设置JFrame内容后面的背景图片

问题描述

所以我正在创建一个弹球游戏。我希望背景图片出现在菜单系统的后面。截至目前,我的菜单系统看起来像这样(没有任何背景图片)

菜单

及其代码:

public class Game extends Canvas implements Runnable {

JFrame frame;

public static final int WIDTH = 640, HEIGHT = WIDTH / 12 * 9;
private Thread thread;
private boolean running = false;
private Handler handler;
private Random r;
private HUD hud;
private Spawn spawner;
private Menu menu;


public enum STATE {
  Menu,
  Help,
  Game

};

public STATE gameState = STATE.Menu;

public Game(){

    //All game objects
    handler = new Handler();
    menu = new Menu(this, handler);
    this.addKeyListener(new KeyInput(handler));
    this.addMouseListener(menu);

    AudioPlayer.load();
    AudioPlayer.getMusic("music").loop();

    new Window(WIDTH, HEIGHT, "Pinball", this);

    hud = new HUD();
    spawner = new Spawn(handler,hud);
    r = new Random();

    if(gameState == STATE.Game){

    handler.addObject(new Player(WIDTH/2-32, HEIGHT/2-32, ID.Player, handler));        
    //for(int i = 0; i < 20; i++){
    handler.addObject(new BasicEnemy(r.nextInt(WIDTH),r.nextInt(HEIGHT), ID.BasicEnemy,handler));     
    }         
}

public synchronized void start(){
    thread = new Thread(this); //"this" is where the thread is going to be ran
    thread.start();
    running = true;
}
//Killing of the thead
public synchronized void stop(){
try {
    thread.join();
    running = false;
}catch(Exception e){
            e.printStackTrace();
            }
}

public void run(){
//Setting up the game loop, every game needs a loop!
this.requestFocus(); //Don't need to click on window to activate key control
long lastTime = System.nanoTime();
double amountOfTicks = 60.0;
double ns = 1000000000 / amountOfTicks;
double delta = 0;
long timer = System.currentTimeMillis();
int frames = 0;
while(running){
    long now = System.nanoTime();
    delta += (now - lastTime) / ns;
    lastTime = now;
    while(delta >= 1){
        tick();
        delta--;
    }
    if(running)
        try {
            render();
    } catch (IOException ex) {
        Logger.getLogger(Game.class.getName()).log(Level.SEVERE, null, ex);
    }
    frames++;

    if(System.currentTimeMillis() - timer > 1000){
        timer += 1000;
        //System.out.println("FPS: " + frames);
        frames = 0;
        }
    }
    stop();
}

private void tick(){
    handler.tick();

    if(gameState == STATE.Game){
    hud.tick();
    spawner.tick();

    }else if(gameState == STATE.Menu){
        menu.tick();   
    }


}
private void render() throws IOException{

    BufferStrategy bs = this.getBufferStrategy();
    if(bs == null){
        this.createBufferStrategy(3);
        return;
    }


    Graphics g = bs.getDrawGraphics();


    //-------------------------------------
    //Background color
    g.setColor(Color.black);
    g.fillRect(0,0, WIDTH, HEIGHT);
    //-------------------------------------


    handler.render(g);

    if(gameState == STATE.Game){

    hud.render(g);

    }else if(gameState == STATE.Menu){
        menu.render(g);


    }else if(gameState == STATE.Menu.Help || gameState == STATE.Help){
        menu.render(g);

    }

    g.dispose();
    bs.show();
}

public static int clamp(int var, int min, int max){
    if(var >= max)
        return var = max;
    else if (var <= min)
        return var = min;
    else 
        return var;
}

public static void main(String[] args) {
   new Game();  
   }  
}

我还有另一个名为 Window.java 的类

public class Window extends Canvas {


public Window(int width, int height, String title, Game game){

    JFrame frame = new JFrame(title);

    frame.setPreferredSize(new Dimension(width, height));
    frame.setMaximumSize  (new Dimension(width, height));
    frame.setMinimumSize  (new Dimension(width, height));

    frame.pack();
    frame.setVisible(true);


    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setResizable(false);
    frame.setLocationRelativeTo(null);

    //Adding game class into the frame
    frame.add(game);
    game.start();
    }

} 

所以,如果我尝试在 Window 类中放入显示背景图片的代码,背景图片就会出现在整个菜单系统的前面。

Window 类中的“背景图片”代码如下所示:

public class Window extends Canvas {


public Window(int width, int height, String title, Game game){

    JFrame frame = new JFrame(title);

    try {
    frame.setContentPane(new JLabel(new ImageIcon(ImageIO.read(new File("C:/res/pinball.png")))));

    } catch (IOException e) {
    e.printStackTrace();
    }

    frame.setPreferredSize(new Dimension(width, height));
    frame.setMaximumSize  (new Dimension(width, height));
    frame.setMinimumSize  (new Dimension(width, height));

    frame.pack();
    frame.setVisible(true);


    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setResizable(false);
    frame.setLocationRelativeTo(null);

    //Adding game class into the frame
    frame.add(game);


    game.start();
    }

} 

结果是这样的:

框架中的背景图片

如何让图片出现在实际菜单系统的后面?

我的菜单(系统)类代码如下所示:

public class Menu extends MouseAdapter {

//JFrame frame;
private Game game;
private Handler handler;
private Random r = new Random();
public static final int WIDTH = 640, HEIGHT = WIDTH / 12 * 9;

public Menu(Game game, Handler handler){
    this.game = game;
    this.handler = handler;

}
//When you click play it takes you over to the game
public void mousePressed(MouseEvent e){
    int mx = e.getX();
    int my = e.getY();




    if(game.gameState == STATE.Menu){

         //Play button
    if(mouseOver(mx, my, 210, 150, 200, 64)){
        game.gameState = STATE.Game;
        handler.addObject(new Player(Game.WIDTH/2-32, Game.HEIGHT/2-32, ID.Player, handler));
        handler.addObject(new BasicEnemy(r.nextInt(WIDTH),r.nextInt(HEIGHT), ID.BasicEnemy,handler));

    }
    //Help button
    if(mouseOver(mx, my, 210, 250,200,64)){
        game.gameState = STATE.Help;

    }



    //Quit button
    if(mouseOver(mx, my, 210, 350, 200, 63)){
        System.exit(1);
        }

     }

           //Back button for help
    if(game.gameState == STATE.Help){
        if(mouseOver(mx, my, 210, 350, 200, 64)){
            game.gameState = STATE.Menu;

        }
    }
}

public void mouseReleased(MouseEvent e){

}

//Method for checking if mouse is over a button in the menu
private boolean mouseOver(int mx, int my, int x, int y, int width, int height){
    if(mx > x && mx < x + width){
        if(my > y && my < y + height){
            return true;
        }else return false;

    }else return false;




public void tick() {

}

public void render(Graphics g){

    if(game.gameState == STATE.Menu){   

    Font fnt = new Font("Arial", 1, 50);
    Font fnt2 = new Font("Arial", 1, 30);


    g.setFont(fnt);
    g.setColor(Color.green);
    g.drawString("Menu", 240, 70);

    g.setFont(fnt);
    g.setColor(Color.green);
    g.drawRect(210,150, 200, 64);
    g.drawString("Play", 265, 200);

    g.setColor(Color.green);
    g.drawRect(210,250, 200, 64);
    g.drawString("Help", 265, 300);

    g.setColor(Color.green);
    g.drawRect(210,350, 200, 64);
    g.drawString("Quit", 265, 400);  

    }else if(game.gameState == STATE.Help) {
        Font fnt = new Font("Arial", 1, 50);
        Font fnt2 = new Font("Arial", 1, 30);
        Font fnt3 = new Font("Arial", 1, 20);

        g.setFont(fnt);
        g.setColor(Color.green);
        g.drawString("Help", 240, 70);

        g.setFont(fnt3);
        g.drawString("Use WASD keys to move player and dodge enemies", 60,200);
        g.drawRect(210,350, 200, 64);
        g.drawString("Back", 265, 400);        
    }

标签: javaswingcanvasjframe

解决方案


推荐阅读