如何创建计时器任务的新实例而不是取消并重新启动它?

How to create new instances of a timer Task instead of canceling and restarting it all over?

嗯,问题是我有一个项目,我必须在 java 上制作游戏。在我的游戏中有一艘发射激光的宇宙飞船。我或多或少地了解了发射激光的机制,但我目前正在使用计时器任务使激光飞过 JFrame 并给人以发射激光的印象。

问题是我一开始拍摄很多次,TimerTask 似乎就出问题了。

主要目标是以给定速度在屏幕上移动对象

我还能做些什么来实现这个目标吗?有没有更好的方法来实现这个? 我感谢我能得到的所有帮助,谢谢。 这是一些代码:

public Space() {
        this.setBackground(Color.BLACK);
        this.setCursor(Cursor.getDefaultCursor());

        this.addMouseMotionListener(new MouseAdapter() {
            public void mouseMoved(MouseEvent e) {
                repaint();
                x = e.getX()-spaceFighterIcon.getIconHeight()/2;
                y = e.getY()-spaceFighterIcon.getIconWidth()/2;

            }
            public void mouseDragged(MouseEvent e) {
                repaint();
                x = e.getX()-spaceFighterIcon.getIconHeight()/2; //Positions the cursor on the middle of the spaceShip and viceVersa 
                y = e.getY()-spaceFighterIcon.getIconWidth()/2; 

            }
        }
        );
        this.addMouseListener(new MouseAdapter(){

            public void mousePressed(MouseEvent e) {
                if(timerRunning = true){
                laserTimer.cancel();
                laserTimer.purge();
                laserFired = false;
                }
                if(SwingUtilities.isLeftMouseButton(e)){ // Gets where the laser is going to be shot from 
                    repaint();
                    laserX = e.getX()-spaceFighterIcon.getIconWidth()/6; 
                    laserY = e.getY();
                    laserFired = true;
                }
                if(SwingUtilities.isRightMouseButton(e)){

                }
                if(SwingUtilities.isMiddleMouseButton(e)){

                }
            }
        });
    }

    public void paintComponent(Graphics g) {
        this.graphics = g;
        super.paintComponent(g);

        spaceFighterIcon.paintIcon(this, g, x, y);
        if(laserFired == true){
            shootLaser();
        }
    }
    public void shootLaser(){
        laserIcon.paintIcon(this, graphics, laserX, laserY-50); // paints the laser
        laserTimer = new Timer();
        laserTimer.schedule(new AnimateLasers(), 0, 200); // Timer to move the laser across the frame
        timerRunning = true;
        repaint();
    }
    public void lasers(){
        laserY = laserY-1; // function to move the laser 
        if(laserY <= 0){
            laserTimer.cancel();
            laserTimer.purge();
        }
    }
    public class AnimateLasers extends TimerTask {

        public void run() {
            lasers(); 
            repaint();
        }
    }

先看看 Concurrency in Swing and How to use Swing Timers 而不是 java.util.Timer

Swing Timer 与 Swing 一起使用更安全,因为它在事件调度线程的上下文中执行它滴答

另请参阅 Painting in AWT and Swing and Performing Custom Painting 以了解有关绘画工作原理的更多详细信息

不要在 paint 方法之外维护对 Graphics 上下文的引用。系统会告知您的组件何时应该自行重新绘制(通过调用 paintComponent 方法),本质上,您使用时间更新 "laser" 的位置并调用 repaint,然后在 paintComponent 被绘制系统

调用时在 paintComponent 内绘制激光