好吧,我有一个项目必须在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 SwingHow to use Swing Timers而不是java.util.Timer

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

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

不要在paint方法之外维护对Graphics上下文的引用。系统将告知您组件何时应自行重新绘制(通过调用paintComponent方法),从本质上讲,您需要花费时间来更新“激光”的位置并调用repaint,然后绘制油漆系统调用paintComponent中的激光时

09-11 18:10
查看更多