我对java很新,但我怀疑我的问题是由与this post
相同的原因引起的因为这让我觉得我在将组件添加到容器之前尝试渲染,所以我只需要帮助找出发生这种情况的方法。我评论了抛出IllegalStateException的行。
public void run() {
init();
long lastTime = System.nanoTime();
final double amountOfTicks = 60D;
double ns = 1000000000/amountOfTicks;
double delta = 0;
long now = System.nanoTime();
while(running)
{
delta += (now - lastTime)/ns;
lastTime = now;
if(delta >= 1)
{
tick();
delta--;
}
render(); //ISSUE HERE AND
}
stop();
}
public void tick() {
player.tick();
}
public void render() {
BufferStrategy bs = this.getBufferStrategy();
if(bs == null)
{
createBufferStrategy(3); //ISSUE HERE, TOO
return;
}
Graphics g = bs.getDrawGraphics();
//RENDER HERE
//g.fillRect(0, 0, 1200, 600);
player.render(g);
//END RENDER
g.dispose();
bs.show();
}
public static void main(String[] args)
{
Game game = new Game();
game.setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
game.setMaximumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
game.setMinimumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
Gui go = new Gui();
game.start();
//Program seems to continue running after ESC
}
错误消息
Exception in thread "Thread-0" java.lang.IllegalStateException: Component must have a valid peer
at java.awt.Component$FlipBufferStrategy.createBuffers(Unknown Source)
at java.awt.Component$FlipBufferStrategy.<init>(Unknown Source)
at java.awt.Component$FlipSubRegionBufferStrategy.<init>(Unknown Source)
at java.awt.Component.createBufferStrategy(Unknown Source)
at java.awt.Canvas.createBufferStrategy(Unknown Source)
at java.awt.Component.createBufferStrategy(Unknown Source)
at java.awt.Canvas.createBufferStrategy(Unknown Source)
at msa.devillegame.main.Game.render(Game.java:81)
at msa.devillegame.main.Game.run(Game.java:68)
at java.lang.Thread.run(Unknown Source)
答案 0 :(得分:1)
我设置了像这样的自定义渲染
public class FrameTest { //not a subclass from frame
public static void main(String[] args) {
//FIXME look at SwingUtilities invokeLater
new FrameTest().createAndShow(); //because it's just a starter
}
private JFrame frame;
private BufferStrategy bufferStrategy;
private Rectangle screenBounds;
private GraphicsDevice myScreen;
private boolean isRunning = false;
private void createAndShow() {
try {
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
myScreen = env.getDefaultScreenDevice(); //maybe select a certain device
GraphicsConfiguration gConf = myScreen.getDefaultConfiguration(); //maybe setup a different configuration
screenBounds = gConf.getBounds();
frame = new JFrame(gConf);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setUndecorated(true);
frame.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
super.keyPressed(e);
goExit();
}
});
frame.setVisible(true);
myScreen.setFullScreenWindow(frame);
bufferStrategy = null;
BufferCapabilities bcaps = gConf.getBufferCapabilities();
int amountBuffer = 0;
if (bcaps.isMultiBufferAvailable() ){
amountBuffer = 3;
}else {
amountBuffer = 2;
}
frame.createBufferStrategy(amountBuffer, bcaps);
bufferStrategy = frame.getBufferStrategy();
isRunning = true;
startRendering(); //starts a render loop
startUniverse(); //starts the physic calculations
System.out.println("created a buffer with "+amountBuffer+" pages");
} catch (HeadlessException e) {
} catch (AWTException e) {
}
}
//this is an example caluclation
private double xpos = 0;
private double ypos = 0;
private double xCenter = 0;
private double yCenter = 0;
private double radius = 100;
private double dAngle = 0;
private double angle = (2d * Math.PI / 360d);
private void startUniverse() {
Runnable r = new Runnable() {
@Override
public void run() {
while(isRunning){
//this is the example calculation
xCenter = screenBounds.getCenterX();
yCenter = screenBounds.getCenterY();
dAngle = dAngle + angle;
xpos = xCenter + radius*(Math.sin(dAngle) );
ypos = yCenter + radius*(Math.cos(dAngle) );
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread t = new Thread(r); //create and...
t.setDaemon(true);
t.start(); //...start the thread
}
//this method starts the rendering thread
//look at the full screen tutorial
private void startRendering() {
Runnable r = new Runnable() {
@Override
public void run() {
while(isRunning){ //an endless loop
Graphics g = null;
try {
g = bufferStrategy.getDrawGraphics();
render(g); //render the graphics
} finally {
if (g != null){
g.dispose(); //IMPORTANT - dispose the graphics - MemeoryLeak
}
}
bufferStrategy.show(); //bring it to the front
//i strongly recommend to let the render thread sleep a little
//this reduces cpu power - without it it uses
//one of my cpus for 100% (having 8 cpus this means 12.5%)
//but when it sleeps 10ms my cpu is down to 1% !!!
//try {
// Thread.sleep(10);
//} catch (InterruptedException e) {
//}
}
}
};
Thread t = new Thread(r);
t.setDaemon(true);
t.start();
}
//the render method draws the calculated stuff
protected void render(Graphics g) {
//fist, fill with white
g.setColor(Color.WHITE);
int x = 0;
int y = 0;
int width = screenBounds.width;
int height = screenBounds.width;
g.fillRect(x, y, width, height);
//xpos and ypos was calulated in the other thread
g.setColor(Color.BLACK);
int x_a = (int)xpos;
int y_a = (int)ypos;
int x_b = (int)xCenter;
int y_b = (int)yCenter;
g.drawLine(x_a, y_a, x_b, y_b);
}
//simple method to quit
protected void goExit() {
isRunning = false;
frame.setVisible(false);
frame.dispose();
myScreen.setFullScreenWindow(null);
}
}
将本教程作为帮助表...
答案 1 :(得分:0)
问题在于,当您尝试创建Game
时,BufferStrategy
对象不属于窗口。
在Game
构造函数中,您需要添加
frame.add(this)
将其添加到窗口并为createBufferStrategy()
方法提供对等