为什么我无法调用重绘方法?

时间:2019-01-05 21:26:18

标签: java swing jpanel loading repaint

我正在开发游戏的启动画面,尝试重绘游戏时出现问题。我有3个班级,分别是1个主要班级,1个游戏管理员和1个用于启动画面和加载的类,但是当我尝试重新绘制屏幕以设置显示当前加载的纹理量时,它什么也没做。我已经尝试了更多方法来调用repaint函数,但是它不起作用,我也不明白为什么。这是我的主班:

package basics;
import java.awt.Toolkit;
import javax.imageio.ImageIO;
import javax.swing.JFrame;

public class Main extends JFrame {

private static final long serialVersionUID = -2321072791006153371L;

public static void main(String[] args) {
    System.out.println("Booting...");
    try {
        new Main();
    } catch (Exception e) {
        e.printStackTrace();
    }
}   

public Main() throws Exception {
    this.setIconImage(ImageIO.read(Main.class.getResourceAsStream("/res/character.png")));
    this.setSize((int)Toolkit.getDefaultToolkit().getScreenSize().getWidth(), (int)Toolkit.getDefaultToolkit().getScreenSize().getHeight());
    System.out.println("manager");
    GameManager manager = new GameManager(this);
    this.add(manager);
    this.setUndecorated(true);
    this.setVisible(true);
    this.setTitle("Gem Hunt");
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    this.setResizable(false);
    manager.startLoading();
}

}

然后是游戏管理员的代码:

package basics;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

import states.Credits;
import states.InGame;
import states.MainMenu;
import states.Splashscreen;


public class GameManager extends JPanel implements KeyListener, ActionListener {

private static final long serialVersionUID = -2781472756180639288L;
long lastLoopTime = System.currentTimeMillis();

public enum GameState {
    SPLASH_SCREEN, MAIN_MENU, LEVEL_SELECTOR, IN_GAME, CREDITS;
}

private JFrame frame;
private Timer timer;
private static GameState state;

private Splashscreen splashscreen;
private InGame game;
private MainMenu mainMenu;

private Credits credits;

/*
 * scale = iwidth/iheight
 * scale = i2width/x
 * i2width/x = scale
 * scale*x = i2width
 * x = i2width/scale
 * 
 */

public GameManager(JFrame frame) throws Exception {
    System.out.println("Loading splashscreen");
    this.frame = frame;
    frame.requestFocus();
    this.splashscreen = new Splashscreen(frame, this);
    state = GameState.SPLASH_SCREEN;
    timer = new Timer(30, this);
}

public void startLoading() {
    timer.start();
}

/**
 * @throws Exception
 */

public void startGame(BufferedImage[][][] textures) throws Exception {
    /* 
     * textures[0] - MainMenu
     * textures[1] - Game
     * textures[2] - LevelSelector
     * 
     * textures[0][0] - Backgrounds
     * textures[0][1-textures.length()-1] - Buttons
     * 
     * textures[1][0] - Background
     * textures[1][1] - Player
     * textures[1][2] - Objects
     * textures[1][3] - Gems
     * textures[1][4] - BackgroundObjects
     * textures[1][5] - Letters
     */
    this.mainMenu = new MainMenu(textures[0], frame);
    this.game = new InGame(frame, textures[1]);
    this.credits = new Credits(frame);

    state = GameState.IN_GAME;//TODO: Set it to MAIN_MENU when Main Menu is ready
    frame.addKeyListener(this);
    frame.addMouseListener(mainMenu);
    timer.start();
}

@Override
public void paint(Graphics g) {
    System.out.println("paint");
    switch(state) {
        case IN_GAME:
            game.draw(g);
            break;
        case MAIN_MENU:
            mainMenu.draw(g);
            break;
        case SPLASH_SCREEN:
            splashscreen.paint(g);
            break;
        case CREDITS:
            credits.paint(g);
            break;
        case LEVEL_SELECTOR:
            break;
        default:
            break;
    }
     long delta = System.currentTimeMillis() - lastLoopTime;
     lastLoopTime = System.currentTimeMillis();
     g.setColor(Color.yellow);
     g.drawString("FPS: " + delta, 0, 20);
     g.dispose();
}

@Override
public void actionPerformed(ActionEvent a) {
    timer.start();
    switch (state) {
    case IN_GAME:
        game.runAction();
        break;
    case MAIN_MENU:
        mainMenu.update();
        break;
    case CREDITS:
        credits.update();
        break;
    case LEVEL_SELECTOR:
        break;
    case SPLASH_SCREEN:
        splashscreen.update();
        break;
    default:
        break;
    }
    repaint();
}


@Override
public void keyPressed(KeyEvent e) {
    if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
        System.exit(-1);
    } else {
        if (!game.isRunning()) {
            game.startGame();
        }
        switch (state) {
        case IN_GAME:
            game.keyPressed(e);
            break;

        default:
            break;
        }
    }
}

@Override
public void keyReleased(KeyEvent e) {
    switch (state) {
    case IN_GAME:
        game.keyReleased(e);
        break;

    default:
        break;
    }
}

@Override
public void keyTyped(KeyEvent e) {}

public static void setState(GameState inGame) {
    state = GameState.IN_GAME;
}

public void updateDisplay(Graphics g) {
    timer.start();
    repaint();
}

}

最后是SplashScreen类,在该类中,我尝试在加载了每个纹理之后重新绘制窗口,因为它并不是单独重新绘制,而是仅在它加载所有内容之后重新绘制:

package states;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;

import javax.imageio.ImageIO;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.FloatControl;
import javax.swing.JFrame;

import basics.GameManager;

public class Splashscreen {

    private static final int ALL_TO_LOAD = 25;

    private JFrame frame;
    private GameManager manager;

    private int loaded;
    private boolean loading;

    public Splashscreen(JFrame frame, GameManager manager) throws Exception {
        this.frame = frame;
        this.manager = manager;
        this.loaded = 0;
        this.loading = false;
    }

    private Graphics g;

    public void paint(Graphics g) {
        this.g= g;
        g.setColor(Color.black);
        g.fillRect(0, 0, frame.getWidth(), frame.getHeight());
        g.setColor(Color.green);
        centerString(g, new Rectangle(0,0,frame.getWidth(),frame.getHeight()), loaded + " / " + ALL_TO_LOAD, new Font("Times New Roman", Font.BOLD, 20));
    }

    public void update() {
        if (!loading) {
            try {
                doLoading();
            } catch (Exception e) {
                e.printStackTrace();
                System.exit(-1);
            }
        }
    }



    private void doLoading() throws Exception {
        BufferedImage[][][] textures = new BufferedImage[3][6][5];
        /* 
         * textures[0] - MainMenu
         * textures[1] - Game
         * textures[2] - LevelSelector
         * 
         * textures[0][0] - Backgrounds
         * textures[0][1] -textures.length()-1] - Buttons
         * 
         * textures[1][0] - Background
         * textures[1][1] - Player
         * textures[1][2] - Objects
         * textures[1][3] - Gems
         * textures[1][4] - BackgroundObjects
         * textures[1][5] - Letters
         */
        System.out.println("Loading some cool music");
        AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new BufferedInputStream(GameManager.class.getResourceAsStream("/res/Dead Or Alive - You Spin Me Round (Like a Record).wav")));
        loaded++; manager.updateDisplay(g);
        Clip clip = AudioSystem.getClip();
        clip.open(audioInputStream);
        FloatControl volume = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
        volume.setValue(-20);
        clip.start();
        clip.loop(Clip.LOOP_CONTINUOUSLY);
        System.out.println("Loading the textures");

        textures[1][0][0] = ImageIO.read(GameManager.class.getResourceAsStream("/res/backgroundAboveFloor.jpg")); loaded++; manager.updateDisplay(g);
        textures[1][0][1] = ImageIO.read(GameManager.class.getResourceAsStream("/res/SkyBackground.jpg")); loaded++; manager.updateDisplay(g);

        textures[1][1][0] = ImageIO.read(GameManager.class.getResourceAsStream("/res/character.png")); loaded++; manager.updateDisplay(g);

        textures[1][2][0] = ImageIO.read(GameManager.class.getResourceAsStream("/res/backgroundFloor.jpg")); loaded++; manager.updateDisplay(g);
        textures[1][2][1] = ImageIO.read(GameManager.class.getResourceAsStream("/res/floor original.png")); loaded++; manager.updateDisplay(g);

        textures[1][3][0] = ImageIO.read(GameManager.class.getResourceAsStream("/res/coin.png")); loaded++; manager.updateDisplay(g);

        textures[1][4][0] = ImageIO.read(GameManager.class.getResourceAsStream("/res/cloud1.png")); loaded++; manager.updateDisplay(g);
        textures[1][4][1] = ImageIO.read(GameManager.class.getResourceAsStream("/res/cloud2.png")); loaded++; manager.updateDisplay(g);
        textures[1][4][2] = ImageIO.read(GameManager.class.getResourceAsStream("/res/cloud3.png")); loaded++; manager.updateDisplay(g);
        textures[1][4][3] = ImageIO.read(GameManager.class.getResourceAsStream("/res/cloud4.png")); loaded++; manager.updateDisplay(g);
        textures[1][4][4] = ImageIO.read(GameManager.class.getResourceAsStream("/res/cloud5.png")); loaded++; manager.updateDisplay(g);

        textures[1][5][0] = ImageIO.read(GameManager.class.getResourceAsStream("/res/S.png")); loaded++; manager.updateDisplay(g);
        textures[1][5][1] = ImageIO.read(GameManager.class.getResourceAsStream("/res/c.png")); loaded++; manager.updateDisplay(g); 
        textures[1][5][2] = ImageIO.read(GameManager.class.getResourceAsStream("/res/o.png")); loaded++; manager.updateDisplay(g);
        textures[1][5][3] = ImageIO.read(GameManager.class.getResourceAsStream("/res/r.png")); loaded++; manager.updateDisplay(g);
        textures[1][5][4] = ImageIO.read(GameManager.class.getResourceAsStream("/res/e.png")); loaded++; manager.updateDisplay(g);

        System.out.println("Setting rescaling the textures");

        double scale = (double)textures[1][2][1].getWidth()/textures[1][2][1].getHeight();
        int height = (int) (((frame.getWidth()/4)*2)/6/scale);

        Image img = textures[1][2][1].getScaledInstance(((frame.getWidth()/4)*2)/6, height, Image.SCALE_AREA_AVERAGING);
        BufferedImage bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
        Graphics2D bGr = bimage.createGraphics();
        bGr.drawImage(img, 0, 0, null);
        bGr.dispose();

        textures[1][2][1] = bimage; loaded++; manager.updateDisplay(g);

        scale = textures[1][1][0].getWidth()/(double)textures[1][1][0].getHeight();
        height = (int)(textures[1][2][1].getWidth()/scale);

        img = textures[1][1][0].getScaledInstance(textures[1][2][1].getWidth(), height, Image.SCALE_AREA_AVERAGING);
        bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
        bGr = bimage.createGraphics();
        bGr.drawImage(img, 0, 0, null);
        bGr.dispose();

        textures[1][1][0] = bimage; loaded++; manager.updateDisplay(g);

        scale = (double)textures[1][4][0].getWidth()/textures[1][4][0].getHeight();
        height = (int) (((frame.getWidth()/4)*2)/3/scale);

        img = textures[1][4][0].getScaledInstance(((frame.getWidth()/4)*2)/3, height, Image.SCALE_AREA_AVERAGING);
        bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
        bGr = bimage.createGraphics();
        bGr.drawImage(img, 0, 0, null);
        bGr.dispose();

        textures[1][4][0] = bimage; loaded++; manager.updateDisplay(g);

        scale = (double)textures[1][4][1].getWidth()/textures[1][4][1].getHeight();
        height = (int) (((frame.getWidth()/4)*2)/3/scale);

        img = textures[1][4][1].getScaledInstance(((frame.getWidth()/4)*2)/3, height, Image.SCALE_AREA_AVERAGING);
        bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
        bGr = bimage.createGraphics();
        bGr.drawImage(img, 0, 0, null);
        bGr.dispose();

        textures[1][4][1] = bimage; loaded++; manager.updateDisplay(g);

        scale = (double)textures[1][4][2].getWidth()/textures[1][4][2].getHeight();
        height = (int) (((frame.getWidth()/4)*2)/3/scale);

        img = textures[1][4][2].getScaledInstance(((frame.getWidth()/4)*2)/3, height, Image.SCALE_AREA_AVERAGING);
        bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
        bGr = bimage.createGraphics();
        bGr.drawImage(img, 0, 0, null);
        bGr.dispose();

        textures[1][4][2] = bimage; loaded++; manager.updateDisplay(g);

        scale = (double)textures[1][4][3].getWidth()/textures[1][4][3].getHeight();
        height = (int) (((frame.getWidth()/4)*2)/3/scale);

        img = textures[1][4][3].getScaledInstance(((frame.getWidth()/4)*2)/3, height, Image.SCALE_AREA_AVERAGING);
        bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
        bGr = bimage.createGraphics();
        bGr.drawImage(img, 0, 0, null);
        bGr.dispose();

        textures[1][4][3] = bimage; loaded++; manager.updateDisplay(g);

        scale = (double)textures[1][4][4].getWidth()/textures[1][4][4].getHeight();
        height = (int) (((frame.getWidth()/4)*2)/3/scale);

        img = textures[1][4][4].getScaledInstance(((frame.getWidth()/4)*2)/3, height, Image.SCALE_AREA_AVERAGING);
        bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
        bGr = bimage.createGraphics();
        bGr.drawImage(img, 0, 0, null);
        bGr.dispose();

        textures[1][4][4] = bimage; loaded++; manager.updateDisplay(g);
        manager.startGame(textures);
    }

    public void centerString(Graphics g, Rectangle r, String s, Font font) {
        FontRenderContext frc = new FontRenderContext(null, true, true);

        Rectangle2D r2D = font.getStringBounds(s, frc);
        int rWidth = (int) Math.round(r2D.getWidth());
        int rHeight = (int) Math.round(r2D.getHeight());
        int rX = (int) Math.round(r2D.getX());
        int rY = (int) Math.round(r2D.getY());

        int a = (r.width / 2) - (rWidth / 2) - rX;
        int b = (r.height/ 2) - (rHeight / 2) - rY;
        g.setFont(font);
        g.drawString(s, r.x + a, r.y + b);
    }
}

我试图在updateWindow方法中没有使用timer.start方法来进行重画,我也尝试直接从Splashscreen类中调用重画。

0 个答案:

没有答案