编辑:这个错误仅当我在 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)
Linux 的图形调度存在问题,这意味着它由于某种原因变得越来越慢。解决这个问题的方法是在执行 panel.repaint() 之后使用 Toolkit.getDefaultToolkit().sync() ,这会阻止速度减慢。
这个函数似乎对其他操作系统没有任何帮助,但它确实占用了宝贵的 CPU 周期(实际上相当多),因此使用 System.getProperty("os.name") 来确定是否需要使用它。