方法重绘()不重绘,球重力动画

时间:2012-05-20 22:24:12

标签: java swing repaint gravity

问题是这个球被拖动并退出点击之后,它应该根据给定的新y分量重新绘制。这是从重力最终计算出来的,并加到了一个循环中加到现有y分量的速度上。

我已经多次调试了,我只是无法击中头部。

它应该...... 移动到拖动它的位置>>>当你放手的时候它会掉下来直到撞到地面。

提前谢谢你。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class DragBallPanel extends JPanel implements MouseListener, MouseMotionListener
{
     private static final int BALL_DIAMETER = 40;
     private int screen_size_x = 300;
     private int screen_size_y = 300;
     private int ground_lvl = screen_size_y - 15;

     private int _ballX     = ground_lvl/2;
     private int _ballY     = ground_lvl - BALL_DIAMETER;
     private final double GRAVITY = -9.8;
     private double velocity;
     private static final double TERM_VEL = -100;

     private int _dragFromX = 0;
     private int _dragFromY = 0;

     private boolean _canDrag  = false;


     public DragBallPanel() throws InterruptedException
     {
        setPreferredSize(new Dimension(screen_size_x, screen_size_y));
        setBackground(Color.darkGray);
        setForeground(Color.darkGray);

        this.addMouseListener(this); 
        this.addMouseMotionListener(this);
    }

    public void paintComponent(Graphics g)
     {
        super.paintComponent(g);   // Required for background.
          g.setColor (Color.green);
          g.fillRect (0, 280, 400, 50 );
          g.setColor (Color.black);
        g.fillOval(_ballX, _ballY, BALL_DIAMETER, BALL_DIAMETER);

    }

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

        if (x >= _ballX && x <= (_ballX + BALL_DIAMETER)
                && y >= _ballY && y <= (_ballY + BALL_DIAMETER))\
          {
            _canDrag = true;
            _dragFromX = x - _ballX;
            _dragFromY = y - _ballY;
        } else
          {
            _canDrag = false;
        }
    }

    //===== mouseDragged ======
    /** Set x,y  to mouse position and repaint. */
    public void mouseDragged(MouseEvent e)
    {
        if (_canDrag)
          {   // True only if button was pressed inside ball.
            //--- Ball pos from mouse and original click displacement
            _ballX = e.getX() - _dragFromX;
            _ballY = e.getY() - _dragFromY;

            //--- Don't move the ball off the screen sides
            _ballX = Math.max(_ballX, 0);
            _ballX = Math.min(_ballX, getWidth() - BALL_DIAMETER);

            //--- Don't move the ball off top or bottom
            _ballY = Math.max(_ballY, 0);
            _ballY = Math.min(_ballY, getHeight() - BALL_DIAMETER);

            this.repaint();
        }
    }

    public void mouseExited(MouseEvent e)
    {
          while(_ballY < ground_lvl)
          {
                 simulateGravity();
          }   
    }

     public void simulateGravity()
     {
         if(_canDrag)
         {
             try{
                 velocity = velocity + GRAVITY;

               if (velocity < TERM_VEL)
                 {
                    velocity = TERM_VEL;
                 }

                if (_ballY >= ground_lvl - BALL_DIAMETER)
                {
                   velocity = velocity/4; 
                } 
                _ballY += velocity;
                 Thread.sleep(400);
                 this.repaint();//**problem occurs here**

              }catch(InterruptedException ie)
              {
              }
         }
     }

    public void mouseMoved   (MouseEvent e){}
    public void mouseEntered (MouseEvent e){}
    public void mouseClicked (MouseEvent e){}
    public void mouseReleased(MouseEvent e){}
}

main()类

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;


public class DragDemo extends JApplet
{
    public static void main(String[] args) throws InterruptedException
    {
        JFrame window = new JFrame();
        window.setTitle("Drag Demo");
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          //window.add(new DragBallPanel());
        window.setContentPane(new DragBallPanel());
          window.setResizable(false);
        window.pack();
        window.show();
    }

    public DragDemo() throws InterruptedException
    {
        new DragBallPanel();
    }
}

2 个答案:

答案 0 :(得分:4)

SSCCE 开始在代码中显示问题。

  1. 编译代码。
  2. 运行它。
  3. 向上拖动球。
  4. 放球。
  5. 从绘图区域移除鼠标,以查看..
  6. 球落下 向上!
  7. 你似乎已经将Y值颠倒了。它们从屏幕顶部开始向下移动。此外,代码在无限循环中阻止EDT。要解决此问题,请使用Swing Timer

    运行动画

    请阅读SSCCE&amp ;;问你是否有任何东西你不明白。我很乐意解释。 :)


    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    public class DragBallPanel extends JPanel implements MouseListener, MouseMotionListener
    {
    
        private static final int BALL_DIAMETER = 40; // Diameter of ball
    
        private int screen_size_x = 300;
        private int screen_size_y = 300;
        private int ground_lvl = screen_size_y - 15;
    
        private int _ballX     = ground_lvl/2;
        private int _ballY     = ground_lvl - BALL_DIAMETER;
        private final double GRAVITY = -9.8;
        private double velocity;
        private static final double TERM_VEL = 100;
    
        private int _dragFromX = 0;    // pressed this far inside ball's
        private int _dragFromY = 0;    // bounding box.
    
        /** true means mouse was pressed in ball and still in panel.*/
        private boolean _canDrag  = false;
    
        public DragBallPanel()
        {
            setPreferredSize(new Dimension(screen_size_x, screen_size_y));
            setBackground(Color.darkGray);
            setForeground(Color.darkGray);
    
            this.addMouseListener(this);
            this.addMouseMotionListener(this);
        }
    
        public void paintComponent(Graphics g)
         {
            super.paintComponent(g);   // Required for background.
              g.setColor (Color.green);
              g.fillRect (0, 280, 400, 50 );
              g.setColor (Color.black);
            g.fillOval(_ballX, _ballY, BALL_DIAMETER, BALL_DIAMETER);
    
        }
    
        public void mousePressed(MouseEvent e)
        {
            int x = e.getX();   // Save the x coord of the click
            int y = e.getY();   // Save the y coord of the click
    
            if (x >= _ballX && x <= (_ballX + BALL_DIAMETER)
                    && y >= _ballY && y <= (_ballY + BALL_DIAMETER)) {
                _canDrag = true;
                _dragFromX = x - _ballX;  // how far from left
                _dragFromY = y - _ballY;  // how far from top
            } else {
                _canDrag = false;
            }
        }
    
        //========= mouseDragged =================
        /** Set x,y  to mouse position and repaint. */
        public void mouseDragged(MouseEvent e)
        {
            if (_canDrag) {   // True only if button was pressed inside ball.
                //--- Ball pos from mouse and original click displacement
                _ballX = e.getX() - _dragFromX;
                _ballY = e.getY() - _dragFromY;
    
                //--- Don't move the ball off the screen sides
                _ballX = Math.max(_ballX, 0);
                _ballX = Math.min(_ballX, getWidth() - BALL_DIAMETER);
    
                //--- Don't move the ball off top or bottom
                _ballY = Math.max(_ballY, 0);
                _ballY = Math.min(_ballY, getHeight() - BALL_DIAMETER);
    
                this.repaint(); // Repaint because position changed.
            }
        }
    
        //====================================================== method mouseExited
        /** Turn off dragging if mouse exits panel. */
        public void mouseExited(MouseEvent e)
         {
             System.out.println("Exited: " + e);
            //_canDrag = false;
            runGravity();
            /*  while(_ballY < ground_lvl)
              {
                 simulateGravity();
              }*/
        }
    
        Timer timer;
        ActionListener animate;
    
        public void runGravity() {
            if (animate==null) {
                animate = new ActionListener() {
                    public void actionPerformed(ActionEvent ae) {
                        System.out.println("Ground: " + (_ballY-ground_lvl));
                        if (_ballY > ground_lvl) {
                            timer.stop();
                        } else {
                            simulateGravity();
                        }
                    }
                };
                timer = new Timer(100,animate);
            }
            timer.start();
        }
    
         public void simulateGravity()
         {
             System.out.println("_canDrag: " + _canDrag);
             if(_canDrag)
             {
    
                 velocity = velocity + GRAVITY;
    
               if (velocity > TERM_VEL)
                 {
                    velocity = TERM_VEL;
                 }
    
                if (_ballY >= ground_lvl - BALL_DIAMETER)
                {
                    //We have hit the "ground", so bounce back up. Reverse
                    //the speed and divide by 4 to make it slower on bouncing.
                    //Just change 4 to 2 or something to make it faster.
                   velocity = velocity/4;
                }
                _ballY += velocity;
                 //this.revalidate();
                 this.repaint();
             }
        }
    
        public void mouseMoved   (MouseEvent e){}
        public void mouseEntered (MouseEvent e){}
        public void mouseClicked (MouseEvent e){}
        public void mouseReleased(MouseEvent e){}
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater( new Runnable() {
                public void run() {
                    DragBallPanel dbp = new DragBallPanel();
                    JOptionPane.showMessageDialog(null, dbp);
                }
            });
        }
    }
    

答案 1 :(得分:0)

尝试使用updateUI()代替repaint()

如果没有效果,请删除该组件并重新添加。