【问题标题】:Java Applet Troubles w/ Paint Method带有 Paint 方法的 Java Applet 问题
【发布时间】:2012-08-23 11:29:57
【问题描述】:

到目前为止,我已经让这个小程序进入了工作阶段;唯一的问题是它只有在鼠标移动时才有效;如果鼠标不动,那么整个事情就会停止。如果移动鼠标,它会再次开始工作。

它的工作方式是通过mouseMoved方法调用paint方法。每次移动鼠标,它都会抛出paint方法,游戏继续进行。问题出在没有调用 mouseMoved 方法时,因此没有调用 paint 方法,整个事情只是暂停,直到鼠标移动为止。

我尝试了以下方法:

让paint方法是递归的,所以它会调用自己。这样做的问题是鼠标监听器不起作用,因为程序正忙于绘制一堆移动的东西。

我还尝试使用线程,以便鼠标侦听器会中断绘制方法。这不起作用,尽管这可能是因为我不了解线程是如何工作的。如果有人知道如何实现这一点,它似乎会起作用。

这里是问题区域的代码片段;

  public void paint( Graphics gr) {
     if( Earth != null){

        displayWorld(Earth);
        for(int a =0; a < 100; a++){      
           Earth.run();
           Earth.Worlds.get(2).forceMove(x,y);
          }
        try
        {
           Thread.sleep(100);  
        }
           catch (InterruptedException ie)
           {}   
     }

  }

public void mouseMoved( MouseEvent e ) {
     x = e.getX();
     y = e.getY();
     Graphics gr = getGraphics();      
    paint(gr);
  }  

【问题讨论】:

  • 哦,上次错过了,不要在paint方法中调用Thread.sleep。这样做是错误的地方

标签: java methods applet paint


【解决方案1】:

我建议再看看线程。这是游戏编程(以及其他编程领域)中的一个非常标准的问题——你有一个线程,永远循环,包含你的游戏逻辑。它会更新玩家的位置、计算、健康等,或者如果没有工作可做,它会休眠。如果完成了需要重绘小程序图形的工作,那么您的线程调用repaint(),它将重绘请求发送到事件调度线程(在每个Java 程序中自动创建的特殊线程)。

当玩家移动鼠标或提供键盘输入时,您的事件侦听器会更新程序的数据结构(并戳主线程以防它处于睡眠状态)。

这些指向以前涉及 Java 游戏的 StackOverflow 问题的链接可能是一个很好的起点:

Best way to implement game loop without freezing UI thread

game loop - threads

祝你好运!

【讨论】:

  • 好主意;我敢肯定,从长远来看,使用线程正确执行此操作将是有益的,尤其是当我进入其他一些项目时。如果我制作更多,我肯定会在下一个版本/级别使用线程。
【解决方案2】:

那么,您的绘画过程依赖于鼠标移动??所以你需要某种方式来告诉小程序自我更新??

private javax.swing.Timer paintTimer;

public void start() {
    // Your normal setup...

    paintTimer = new javax.swing.Timer(250, new ActionListener() {
        public void actionPerformed(ActionEvent evt) {
            Graphics gr = getGraphics();      
            paint(gr);
        }
    });
    paintTimer.setRepeats(true);
    paintTimer.setCoalesce(true);
    paintTimer.start();
}

public void mouseMoved( MouseEvent e ) {
    x = e.getX();
    y = e.getY();

    // You could wait for the timer to trigger the repaint for you...
    repaintTimer.restart();

    Graphics gr = getGraphics();      
    paint(gr);
}  

不过,你需要把握时机

【讨论】:

  • 不要在此处使用javax.swing.Timer。没有理由。你看过java.util.Timer吗?
  • @veer 为什么不呢?我错过了什么?
  • 为什么是Graphics gr = getGraphics(); paint(gr); 而不仅仅是repaint();
  • @AndrewThompson 因为这是给我的。我不想假设图形是如何更新的。如果 OP 使用的是正常的重绘过程,那么是的,你是对的(像往常一样;)),但我没有证据表明它是一种或另一种方式:P
  • “我不想假设” 我也不喜欢它,这可能解释了为什么我是 SSCCE 的忠实粉丝。 ;) +1
猜你喜欢
  • 2017-03-17
  • 2015-01-18
  • 2013-03-12
  • 2012-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-31
  • 2010-09-28
相关资源
最近更新 更多