我正在开发游戏的启动画面,尝试重绘游戏时出现问题。我有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类中调用重画。