【发布时间】:2018-01-16 17:04:56
【问题描述】:
我正在开发一个独立游戏项目,当我将项目从我的 Windows 计算机移动到我的 macbook 时,我遇到了图形不显示的问题。我已经更新了我的 Java 版本和我的 Eclipse,但仍然有这个问题。以下是处理 JFrame 和 Panel 的两个主要文件:
主游戏循环
package hara;
import javax.swing.JFrame;
public class MainGameLoop {
public static final String gameName = "HARA v0.0";
public static void main(String[] args) {
JFrame f = new JFrame(gameName);
f.setContentPane(new MainWindow());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setResizable(false);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
和主窗口
package hara;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
import hara.gamestate.GameStateManager;
public class MainWindow extends JPanel implements Runnable, KeyListener{
public static final int WIDTH = 320;
public static final int HEIGHT = 240;
public static double wSCALE = 4;
public static double hSCALE = 4;
private Thread thread;
private boolean running;
private int FPS = 60;
private long targetTime = 1000/FPS;
private BufferedImage image;
private Graphics2D g;
private GameStateManager gsm;
public MainWindow(){
super();
setPreferredSize(new Dimension((int)(WIDTH * wSCALE), (int)(HEIGHT * hSCALE)));
setFocusable(true);
requestFocus();
}
public void addNotify(){
super.addNotify();
if(thread == null){
thread = new Thread(this);
addKeyListener(this);
thread.start();
}
}
public void init(){
image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_ARGB);
g = (Graphics2D) image.getGraphics();
running = true;
gsm = new GameStateManager();
gsm.setState(gsm.MENUSTATE);
}
public void run(){
init();
long start;
long elapsed;
long wait;
while(running){
start = System.nanoTime();
update();
draw();
drawToScreen();
elapsed = System.nanoTime() - start;
wait = targetTime - elapsed / 1000000;
if(wait < 0){
wait = 5;
}
try {
Thread.sleep(wait);
}catch(Exception e){
e.printStackTrace();
}
}
}
private void update(){
gsm.update();
}
private void draw(){
gsm.draw(g);
}
private void drawToScreen(){
Graphics g2 = getGraphics();
g2.drawImage(image, 0, 0, (int) (WIDTH * wSCALE), (int) (HEIGHT * hSCALE), null);
g2.dispose();
}
public void keyTyped(KeyEvent e) {}
public void keyPressed(KeyEvent key) {
gsm.keyPressed(key.getKeyCode());
}
public void keyReleased(KeyEvent key) {
gsm.keyReleased(key.getKeyCode());
}
}
它在我的 PC 上完美运行,绘图没有问题,但是一旦我将文件移动到我的 Macbook,它只会打开一个空白的 JFrame,什么也不做。我测试了这些方法是否被正确调用并且它们是正确的。绘制方法被调用,键盘输入有效,但没有任何显示。如果我将窗口设置为可调整大小,并调整它的大小,我可以非常简要地看到图形工作。我尝试了很多解决方案,但都没有奏效。我在这个网站上查看了很多问题,但似乎没有什么对我有用。会喜欢任何想法。谢谢!
【问题讨论】:
-
我看不到您的大部分代码是从哪里调用的?看起来
MainWindow应该作为线程启动 -
你有多个线程,没有任何同步,所以没有任何理由必须工作。例如,
gsm.keyPressed(...)可以合法地抛出NullPointerException,因为它是在没有同步/易失性的不同线程上分配的。您需要阅读concurrency tutorials 或just use a timer,因为可能没有特别的理由使用多线程。 -
@Radiodef 我不确定我看到哪里有多个线程,即便如此,当我在 Windows 桌面上运行程序时似乎没有引起任何问题
-
一个线程是 Swing 线程(event dispatch thread),另一个是您在
addNotify()中启动的线程。 (还有一个 3rd 是主线程。)它是否似乎在某些特定系统上工作并不重要,因为它没有必须而且你问为什么你的代码没有工作。实际上会发生的情况是您偶尔会遇到 NPE,或者您的控制会显得迟钝。 HotSpot 也可能将您的while(running)循环转换为while(true)循环。类似的东西。