【问题标题】:How to stop the auto-repaint() when I resize the Jframe调整 Jframe 大小时如何停止自动重绘()
【发布时间】:2014-11-29 16:42:29
【问题描述】:

我还在学习Java,如果有人可以帮助我,我会很高兴!

抱歉英语不好,我是西班牙人! 我正在制作一个瓷砖游戏,该游戏使用经典的“游戏循环”,将引擎限制在 60fps 循环休眠,然后调用 repaint(); 这很好用!但是..

问题是当 JFrame 被调整大小或最大化时会调用 repaint 事件! 例如,当 JFrame 被最大化/调整大小时,游戏以 10000fps 渲染,但当它们没有时,游戏以我设置的速度渲染,因此有一种方法可以禁用自动重绘并使其仅在“component.repaint() " 是从我的代码中调用的吗?

这里的问题不是“游戏循环”,问题是当调整大小/最大化以更高的 fps 渲染游戏时,重绘被称为自动!

public class Handling {
static private int fps=0;
static private int fpsfinal=0;
static int frames = 60;
static int frames_skip = 1000 / frames;
static long ticknext = GetTickCount();
static long ticksleep = 0;

public static void Run() {
    for(;;){
        Main.getDevice().repaint();
        fps++;
        ticknext += frames_skip;
        ticksleep = ticknext - GetTickCount();
        if(ticksleep >= 0) {
            try {
                Thread.sleep(ticksleep);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public static long GetTickCount(){
    return System.currentTimeMillis();
}

public static int GetFPS(){
    fpsfinal=fps;
    fps=0;
    return fpsfinal-2;
}

import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.ImageObserver;

import javax.swing.*;
public class Game extends JPanel{
private static final long serialVersionUID = 1L;
static boolean dir=true;

@Override 
public void paintComponent(Graphics g){
    super.paintComponent(g);        
    int layout=Main.layout;
    Graphics2D g2d = (Graphics2D) g;
    g.setFont(Resources.GetFont(0));    
    Camera.UpdateCameraAxis();
    Camera.DoCamera();
    Cursor.MouseLoop(); 
    if (layout==0){
        this.setBackground(new Color(210,247,255));
        for(int xx=Math.max( etc....

【问题讨论】:

  • 请添加一些代码,仅通过描述很难帮助您。
  • 所以您希望能够在不调用 repaint() 的情况下调整窗口大小?
  • 是的,这正是我想要的,我希望游戏以 60 fps 运行,但是当我调整大小时,调用 repaint() 以使游戏以 1000 fps 运行
  • 在这种情况下,我必须说您可能使用了错误的语言。 Java 在后端做了很多你无法控制(合法)改变的事情。我会做更多的研究,所以我可以给你一个明确的答案,但我的猜测是,没有办法按照你的要求做......
  • psyche,我可能是错的,检查这个问题,看看它是否有帮助 -- LINK 具体来说,查看第二个答案。我觉得这可能是您需要的。

标签: java swing jpanel awt


【解决方案1】:

所以当 JFrame 没有最大化时

我不知道为什么这会导致问题,因为应该只生成一个重绘请求。

或(调整大小)

我可以看到这是一个问题,因为对于您调整帧大小的每个像素都会调用重绘。在这种情况下,也许你可以使用:

Toolkit.getDefaultToolkit().setDynamicLayout(false); 

现在组件将在调整大小完成后进行验证。

this.setBackground(新颜色(210,247,255));

不要使用像上面这样的代码,因为改变背景会导致 repaint() 被调用,这将再次调用 paintComponent() 方法。绘画方法仅供绘画。

【讨论】:

  • 我应该在什么地方添加这段代码:Toolkit.getDefaultToolkit().setDynamicLayout(false);在开始还是在重绘?
  • @LesterMurillo,您为什么要不断设置此属性?
  • 游戏逻辑和渲染以设定的 fps (60) 工作,调整大小/最大化调用这更经常导致重叠/更多 fps,因此游戏图形与逻辑不同步,如果你不问的话为此,我理解不好,(我是西班牙人)
  • @LesterMurillo,正如我在回答中所说的那样。最大化只会生成一个绘制请求。如果您使用我的建议来设置动态布局,那么调整框架大小也只会在释放鼠标时生成一个绘制请求。这不应该影响您的游戏,除非您的绘画代码正在改变您不应该这样做的游戏状态。我唯一的其他建议是看看Full Screen Exclusive Mode API
【解决方案2】:

“当我调整 Jframe 大小时如何停止 auto-repaint()”

简短的回答,你控制它。更长的答案,您需要确保您没有在 paintComponent 方法中做任何改变状态的事情(您用来绘画)。例如:

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    Random random = new Random();
    int x = random.nextInt(100);
    int y = random.nextInt(100);
    int size = random.nextInt(100);
    g.drawRect(x, y, size, size);
}

这里发生的情况是,每次 GUI 重新绘制时,不在您的控制之下,矩形都会调整大小,而您并不希望它这样做。因此,如果您希望矩形仅在 告诉它时重新绘制,您需要确保您只从 outside 操作状态(即 x、y、大小) paintComponent 方法,并且使用该状态进行绘制。类似的东西

Random random = new Random();
int x, y, size;
...
void reset() {
    x = random.nextInt(100);
    y = random.nextInt(100);
    size = random.nextInt(100);
}
...
Timer timer = new Timer(25, new ActionListener(){
    @Override
    public void actionPerformed(ActionEvent e) {
        reset();
        repaint();
    }
}).start();
...
@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);

    g.drawRect(x, y, size, size);
}

【讨论】:

  • 谢谢,问题是当用户调整 Jframe 的大小时,Jframe 改变了它们的大小但游戏几乎一样(没有变化)但是感谢您的帮助,我会尝试渲染游戏到 BuferredImage 并绘制图像,所以游戏只会在我想要 c: 时更新,但仍然感谢游戏
  • 是的,但是我没有改变paint方法的状态,问题是重绘是在我的控制之外调用的,java应该有办法禁用自动绘制:(
  • @LesterMurillo 我假设Camera.UpdateCameraAxis(); 或这个for(int xx=Math.max( 改变了一些绘画状态。没有不完整的代码就无法判断。也许我错了
  • Camera.UpdateCameraAxis() 改变相机 x 和 y,但是当玩家不移动时没有变化但自动重绘仍然完成并且 for 循环是绘制瓷砖,(它是像我的世界 2d/泰拉瑞亚游戏)。我正在考虑在我的游戏中禁用调整大小并使其以固定分辨率工作:s
  • @LesterMurillo 是 xypaintComponent 方法中使用(我们看不到)吗?如果是这样,在游戏循环中调用该方法不是更有意义,因为那是您显式调用repaint()的地方
猜你喜欢
  • 2011-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多