繁体   English   中英

从Java中的另一个类调用重绘?

[英]Call repaint from another class in Java?

我可能做错了,所以请你好。 我正在开发一个Java游戏,我正处于测试角色移动/动画的阶段。

“人”可以在网格上向左和向下移动。 绘制网格的类是gamePanel类。 按钮位于gameControlPanel类中。

我有一个按钮,可以在网格上生成一个人。 然后,我有一个按钮,可以将人向左和向下移动。

按下向上移动按钮时,它会调用person类中的move up方法。 (目前,我一次只测试一个“人”。)在那个方法中是以下代码......

int move = 10;
while(move!=0)
{
    setTopLeftPoint(new Point((int)getTopLeftPoint().getX(),
                              (int)getTopLeftPoint().getY() - 3));

    try
    {
        Thread.sleep(300);
    } catch (InterruptedException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }   
    move-=1;
}

问题是我似乎无法从Person类中调用gamePanel类的重绘方法。 为了解决这个问题,我在gamePanel类中创建了一个计时器,它每20ms重新绘制一次。

当人物产生后按下向上按钮时,按钮保持按下直到while循环完成循环,然后人物的圆圈表示显示在上面的网格方框中。

我将尝试回答有关此问题的任何问题。

repaint()不会立即重新绘制GUI。 相反,它向AWT线程发布消息,告诉它在下一个方便的机会画画。 当它有机会时,它会重新绘制你的应用程序。 但是,如果在事件处理程序中执行此操作,则AWT线程已经忙,您需要退出处理程序以将控制权交还给AWT处理程序。

作为一般经验法则,您希望在AWT线程上(包括在事件处理程序中)执行任何长时间运行的计算,因为这些将阻止应用程序响应其他事件,直到您的计算完成为止。 对于用户来说,这通常会显示为您所描述的卡住按钮。 要解决这个问题,请使用可以在单独的线程上进行计算的SwingWorker

最后,需要注意的事情(但不一定要改变)是定时器和睡眠并不保证什么时候它们会被唤醒。 相反,他们保证在经过一段时间之前不会唤醒,但理论上可以无限期地睡觉。 此外,并非所有机器都具有1 ms定时器分辨率。 特别是,在许多Windows机器上,定时器只有55毫秒的分辨率,因此20毫秒的定时器可能会产生奇怪的结果。

如果你想以一定的间隔重新绘制, javax.swing.Timer可能就是你的类。 repaint的特定情况下,您可以从非EDT线程调用它,但是您可能会遇到困难,因为您现在处理多个线程。

我没有太多制作游戏的经验,但拥有一个控制所有动画的循环是游戏编程的一个基本方面。 大多数简单的2D游戏只有1个循环来渲染它的大部分动画。

根据我的经验,渲染一大堆东西的好方法是在一个地方拥有游戏中所有实体的集合,然后循环遍历此集合,将Graphics对象传递给每个实体。

这将允许每个实体将自己绘制到图形对象上。 虽然这只是一种方法。

synchronized ( entities ) {
    for ( Entity e : entities ) {
        e.draw( g );
        e.doAction();
    }
}

按下按钮是否由GUI的事件派发线程处理?

如果是这种情况,那么GUI上的重绘方法将不会触发,直到事件调度线程结束(即当按钮被释放并且它突然出现循环时)。 我最近遇到了这个问题,我建议的最好的解决方案是使用移动算法的类可以线程化,并在检测到按键时触发线程。 这允许事件派发线程完成,因此允许gui重绘。

有关线程的更多信息,请参阅启动线程

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM