Java窗口滞后于Ubuntu,但是当代码不滞后时,窗口不会停止

时间:2015-10-21 10:58:21

标签: java swing

编辑:只有在我的Ubuntu 14.04笔记本电脑上运行游戏时才会出现此错误。当我在Windows学校计算机上运行它时,它可以正常工作。

正常运行时窗口滞后,但在用鼠标调整窗口大小时停止滞后

我试图在java中制作一个简单的游戏,但是当我运行它时,它就像疯了一样,我查看了代码,并使用System.out.println进行了一些检查。 System.currentTimeMillis和代码在不到一毫秒的时间内运行,因此不是问题。

当我拖动以调整窗口大小并不断更改窗口大小(可能强制重新绘制屏幕)时程序停止,当我这样做时它会有很好的平滑动画。

当我的程序运行时,它以平滑的动画开始,然后大约1秒后它会变为大约2 FPS,然后又过了一​​秒后变为1 FPS,然后大约0.5FPS并保持在那里直到我强制重新绘制通过调整窗口大小

我的代码是:

public class WindowSetup extends JPanel{
private static final long serialVersionUID = 6486212988269469205L;
static JFrame frame;
static JPanel panel;
protected void paintComponent(Graphics g){
    super.paintComponent(g);
    GameClass.draw(g);
}
public static void main(String[] args) {
    frame = new JFrame("Evolver");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(800, 600);
    panel = new WindowSetup();
    frame.add(panel);
    panel.setVisible(true);
    frame.setVisible(true);

    GameClass.init();
    ActionListener al = new ActionListener() {

        public void actionPerformed(ActionEvent e) {
            // TODO Auto-generated method stub
            GameClass.tick();
            panel.repaint();
        }
    };
    Timer timer = new Timer(50,al); // lower numbers here make it run faster, but it still ends up slowing down to 1FPS
    timer.start();
}
}

我的GameClass:

public class GameClass {
static Random random;
static ArrayList<Enemy> enemies = new ArrayList<Enemy>();
static Wall wall;
static void init(){
    random = new Random();
    wall=new Wall();
    for(int i=0;i<5;i++){
        enemies.add(new Enemy(random.nextInt(200)+100,random.nextInt(200)+100,10,10,(float) (random.nextFloat()*(Math.PI*2)),1));
    }
}
static void tick(){
    for(Enemy d:enemies){
        d.tick();
    }
}
static void draw(Graphics g){
    for(Enemy d:enemies){
        d.draw(g);
    }
    wall.draw(g);
}
}

敌人类:

public class Enemy {
float x;
float y;
float width;
float height;
float direction;
float speed;

public Enemy(float x, float y, float width, float height, float direction, float speed) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
    this.direction = direction;
    this.speed = speed;
}

public void tick() {
    direction += 0.01;
    if (!(GameClass.wall.collides((int) (x + (Math.cos(direction) * speed)), (int) (y + (Math.sin(direction) * speed)),(int)width,(int)height))) {
        x += Math.cos(direction) * speed;
        y += Math.sin(direction) * speed;
    }
}

public void draw(Graphics g) {
    g.drawRect((int) x, (int) y, (int) width, (int) height);
}
}

墙代码:

public class Wall {
ArrayList<Rectangle> rectlist = new ArrayList<Rectangle>();

public Wall() {
    // create list of walls here
    rectlist.add(new Rectangle(10, 10, 50, 400));
    rectlist.add(new Rectangle(410,10,50,400));
    rectlist.add(new Rectangle(60,10,350,50));
    rectlist.add(new Rectangle(60,360,350,50));
}

public void draw(Graphics g) {
    for (Rectangle d : rectlist) {
        g.drawRect(d.x, d.y, d.width, d.height);
    }
}
public boolean collides(int x,int y,int width,int height){
    for(Rectangle d:rectlist){
        if(d.intersects(x, y, width, height)){
            return true;
        }
    }
    return false;
}
}

2 个答案:

答案 0 :(得分:1)

Linux的图形调度存在问题,这意味着由于某些原因它变得越来越慢。解决这个问题的方法是在执行panel.repaint()之后使用Toolkit.getDefaultToolkit()。sync(),这会停止减速。

这个函数似乎对其他操作系统上的任何东西都没有帮助,但它确实占用了宝贵的CPU周期(实际上相当多),所以使用System.getProperty(&#34; os.name&#) 34;)确定是否需要使用它。

答案 1 :(得分:0)

作为一种解决方法,我猜你可以模拟&#39;通过在您的操作侦听器周围添加setVisible(false)setVisible(true)来调整大小行为:

    public void actionPerformed(ActionEvent e) {
        panel.setVisible(false);
        GameClass.tick();
        panel.repaint();
        panel.setVisible(true);

    }