Установка фоновой картинки за контентом JFrame в Java - PullRequest
0 голосов
/ 01 марта 2019

Итак, я создаю игру в пинбол.Я хочу, чтобы фоновая картинка появлялась за системой меню.На данный момент моя система меню выглядит следующим образом (без фоновой картинки)

Меню

и код для него:

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