简体   繁体   English

定时器延迟问题Java

[英]Timer Delay Problems Java

I am trying to make a snake type game and I am having trouble making the "pellets" appear at random places at fixed intervals (I want to make it 10 seconds). 我正在尝试制作一个蛇型游戏,我很难让“颗粒”以固定的间隔出现在随机的地方(我想让它达到10秒)。 When I run the program after the brief delay I gave it (1000 milliseconds) the pellets begin to appear extremely rapidly flashing on the screen in different locations. 当我在短暂的延迟后运行程序时(1000毫秒),颗粒开始出现在不同位置的屏幕上极快地闪烁。 What I want to do is make the pellets appear one at a time in random locations every 10 seconds instead of flashing around rapidly. 我想要做的是让颗粒每10秒钟在一个随机位置出现一个,而不是快速闪烁。 Any help would be appreciated. 任何帮助,将不胜感激。

PS I have never done something like this before so, apologies if the code may seem a bit crude. PS我之前从未做过这样的事情,如果代码看起来有点粗糙,我会道歉。 Any advice with coding in general is also very appreciated. 一般编码的任何建议也非常感谢。

Edit: I know this is still incorrect but I just want to know if I am at least on the right track so far. 编辑:我知道这仍然是不正确的但我只是想知道我到目前为止是否至少在正确的轨道上。 Now the "pellet" is just sitting there in the top right hand corner of the frame. 现在,“颗粒”只是坐在框架的右上角。 Is there a problem now with my timer or the list or just everything in general. 我的计时器或列表现在是否存在问题,或者只是一般的问题。 By the way if updating my code just to show new problems is frowned upon in this website let me know and I'll just ask for help in the comments section and stop with the edits. 顺便说一句,如果更新我的代码只是为了显示新的问题在这个网站上不受欢迎,请告诉我,我只是在评论部分寻求帮助并停止编辑。

package snake;

import java.awt.* ;
import java.awt.event.*;
import java.util.* ;
import javax.swing.*;
import javax.swing.Timer;
/**
 *
 * @author Carlos
 */
public class Pellet extends JPanel
{
    Random randomNumber = new Random() ; 
    int x = 0 ;
    int y = 0 ;
    private Game game ;
    private Timer timer ;
    private final int DELAY = 100 ;
    private ArrayList<Pellet> al = new ArrayList<>() ;

    public Pellet(Game game)
    {        
        this.game = game ;        
    }

    @Override
    public void paint(Graphics g)
    {  
       super.paintComponent(g);
       g.fillOval(x, y, 10, 10);

       for(int i = 0 ; i < al.size() ; i++)
       {
           Pellet p = al.get(i) ;
           p.paintComponent(g);
       }

    }

    public void pelletTimer()
    {
        timer = new Timer(DELAY, new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                x = randomNumber.nextInt(game.getWidth()) ;
                y = randomNumber.nextInt(game.getHeight()) ;
                Pellet p = new Pellet(game) ;
                al.add(p) ;
                repaint() ;
            }
        }) ;    
        timer.start();
    }


}

You've lots of issues with your code attempt, so let's try to go through them. 您的代码尝试存在很多问题,所以让我们尝试一下。

  • First off this is a Swing program and so you must take care to not stomp on the Swing event thread, something that a java.util.Timer will do. 首先这是一个Swing程序,所以你必须注意不要踩踏Swing事件线程,这是java.util.Timer会做的事情。
  • You're also creating your java.util.Timer within a paint method, something that should never be done since this method is for painting and painting only, and should not be slowed down or involved with non-painting code. 您还要在paint方法中创建java.util.Timer ,这是永远不应该做的事情,因为此方法仅用于绘制和绘制,不应该减慢速度或与非绘制代码相关。
  • Your paint method is not a true paint method override of a Swing component since it has the wrong signature (it uses a Graphics2D parameter not the expected Graphics parameter) and your class does not extend a Swing component, so this method will do nothing of use for you. 你的paint方法不是Swing组件的真正的paint方法覆盖,因为它有错误的签名(它使用Graphics2D参数而不是预期的Graphics参数)并且你的类没有扩展Swing组件,所以这个方法什么都不用为了你。

Suggestions: 建议:

  • Draw in a paintComponent method override in a class that extends JPanel. 在扩展JPanel的类中绘制paintComponent方法覆盖。
  • Call the super.paintComponent method first. 首先调用super.paintComponent方法。
  • Use a javax.swing.Timer or "Swing" Timer to drive your animation. 使用javax.swing.Timer“Swing”Timer来驱动动画。
  • In your Timer create a new pellet, add it to an ArrayList of pellets, and call repaint() which will tell the JVM to repaint your GUI and thus it will automatically call your paintComponent method for you. 在你的Timer中创建一个新的pellet,将它添加到pellet的ArrayList,并调用repaint() ,它将告诉JVM重新绘制你的GUI,因此它将自动为你调用paintComponent方法。
  • In your paintComponent method, after calling the super's method, iterate through the pellet ArrayList drawing each individual pellet as you do. 在paintComponent方法中,在调用super的方法之后,迭代通过pellet ArrayList绘制每个单独的pellet。
  • Check out the Swing tutorials especially the graphics section. 查看Swing教程,尤其是图形部分。 You can find a link to them here: swing info . 你可以在这里找到他们的链接: 摇摆信息
  • And check out this site for Swing animation examples, many written by me. 并查看这个网站上的Swing动画示例,很多是我写的。 You can find some results with this search . 您可以通过此搜索找到一些结果。

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

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