2012-05-20 1 views
2

Проблема в том, что этот шар после его перетаскивания и выхода из клика, он должен перерисовываться в соответствии с новым компонентом 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){} 
} 

основной() класса

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(); 
    } 
} 
+1

Для лучшей помощи раньше, опубликовать [SSCCE] (http://sscce.org/). –

+0

После добавления 'main' и запуска этого, я не совсем понимаю проблему. Я могу перетащить мяч туда, где захочу, но если я перевешу его на левую стену, он там останется и больше не сдвинется. Это намерение? Если нет, можете ли вы объяснить, другими словами, что должно произойти? –

+0

Это очень маленький код, поэтому я разместил его полностью. Я просто отредактировал его, чтобы просто включить предметы первой необходимости. Спасибо ... – CommonKnowledge

ответ

4

SSCCE начинает показывать проблемы в коде.

  1. Скомпилируйте код.
  2. Запустите его.
  3. Переместите мяч вверх.
  4. Освободите мяч.
  5. Снимите мышь с области рисунка, чтобы увидеть ..
  6. Падение мяча вверх!

Вы, кажется, получили значения Y с ног на голову. Они начинаются сверху экрана и идут вниз. Кроме того, код блокировал EDT в бесконечном цикле. Чтобы решить эту проблему, запустите анимацию с помощью Swing Timer.

Прочтите документ на SSCCE &, спросите, есть ли что-нибудь в нем, которое вы не понимаете. Я хорошо объясню. :)


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); 
      } 
     }); 
    } 
} 
0

Попробуйте updateUI() вместо repaint().

Если нет эффекта, удалите компонент и добавьте его снова.

+2

Кажется, что (плохое целевое &) случайное предположение для меня. Я сделал много анимации и никогда не вызывал 'updateUI()' как часть процесса. Второе предложение еще хуже. :(Пожалуйста, удалите это. Это не ответ, и я бы сделал для плохого комментария (предполагая, что у вас есть репутация, чтобы опубликовать их). –

+0

Извините, но у меня была проблема с этой проблемой, и для решения проблемы требуется много времени. , – shadowdiver

Смежные вопросы