当代码不滞后时,Java 窗口在 Ubuntu 上出现滞后,但在 Windows 上则不然

Hea*_*ath 1 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();
}
}
Run Code Online (Sandbox Code Playgroud)

我的游戏类:

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);
}
}
Run Code Online (Sandbox Code Playgroud)

敌方等级:

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);
}
}
Run Code Online (Sandbox Code Playgroud)

墙体代码:

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;
}
}
Run Code Online (Sandbox Code Playgroud)

Hea*_*ath 5

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

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