2013-04-03 101 views
-1

所以現在當你按下它去對面移動到屏幕上,但我也希望它移動它的腿因此它做的事情,而不只是原地踏步。有關如何做到這一點的任何提示?我知道這將是移動次回合指針來回,但我不知道該怎麼做如何讓動畫在移動時移動其雙腿?

類Stick2:

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



public class Stick2 extends JFrame implements ActionListener { 

    // Declares constants 
    public static final int FRAME_WIDTH = 500; 
    private static final int FRAME_HEIGHT = 500; 
    private static final int FRAME_X_ORIGIN = 150; 
    private static final int FRAME_Y_ORIGIN = 200; 
    private static final int BUTTON_WIDTH =80; 
    private static final int BUTTON_HEIGHT = 30; 

    JPanel buttonPanel, panel; 

    MovingBanner2 myBanner; 
    JButton startButton, stopButton; 

    Thread thrd; 


    public static void main(String[] args) 
    { 
     Stick2 frame = new Stick2(); 
     frame.setVisible(true); 
    } 

    public Stick2(){ 


     Container contentPane= getContentPane(); 

     // Sets Frame 
     setSize(FRAME_WIDTH,FRAME_HEIGHT); 
     setResizable(false); 
     setTitle("Animation"); 
     setLocation(FRAME_X_ORIGIN, FRAME_Y_ORIGIN); 

     // Sets layout manager 
     contentPane.setLayout(new BorderLayout(10,0)); 


     buttonPanel = new JPanel(); 

     JButton startButton = new JButton("Start"); 
     startButton.setSize(BUTTON_WIDTH, BUTTON_HEIGHT); 
     buttonPanel.add(startButton); 
     startButton.addActionListener(this); 

     JButton stopButton = new JButton("Stop"); 
     stopButton.setSize(BUTTON_WIDTH,BUTTON_HEIGHT); 
     buttonPanel.add(stopButton); 
     stopButton.addActionListener(this); 

     contentPane.add (buttonPanel, BorderLayout.SOUTH); 

     // Creates a balloon 
     myBanner = new MovingBanner2(); 
     panel = myBanner; 
     panel.setBorder(BorderFactory.createLineBorder(Color.BLUE)); 
     contentPane.add(panel, BorderLayout.CENTER); 



    } 

    public void actionPerformed (ActionEvent event){ 
     JButton clickedButton = (JButton) event.getSource(); 

     String buttonText = clickedButton.getText(); 

     if (buttonText.equals("Stop")) { 

      myBanner.stopAnimation(); 
      thrd = null; 
     } 
     else { 

      myBanner.startAnimation(); 
      thrd = new Thread (myBanner); 
      thrd.start(); 


     } 
    }    
} 

類MovingBanner2:

class MovingBanner2 extends JPanel implements Runnable { 

     private int x; 

     private Boolean animate; 

     int bodyX = 250; 
     int bodyY1 = 160; 
     int bodyY2 = 210; 
     int armHeight = 190; 
     int armLength = bodyX + 30; 
     int armLength1 = bodyX - 30; 
     int legY = 340; 

     public MovingBanner2() { 
      x=10; 
      animate = true; 
     } 

     // Draws the String 
     public void paintComponent (Graphics g) { 
      super.paintComponent(g); 

      g.setColor(Color.RED); 
      //g.drawString("I love Java", x,50); 
      g.drawLine(bodyX + x, bodyY1, bodyX + x, bodyY2); //body 
      g.drawOval(bodyX + x - 15, bodyY1 - 40, 40, 40); //head 
      g.drawLine(armLength + x,armHeight, armLength1 + x, armHeight); //arms 
      g.drawLine(bodyX + x, bodyY2, bodyX + 20 + x,legY); //leg 
      g.drawLine(bodyX + x, bodyY2, bodyX - 20 + x, legY); //leg 
     } 

     public void run() { 
      while (animate) { 
       changeX(); 
       repaint();  
       try {Thread.sleep(100); } catch(Exception e){}; 
      } 
     } 



     public void changeX() { 

      if (x <= Stick2.FRAME_WIDTH - 240) 
       x++; 
      else x = 10; 

     } 

     public void stopAnimation() { 
      animate = false; 
     } 

     public void startAnimation() { 
      animate = true; 
     } 
} 
+0

歡迎來到SO,閱讀關於如何編寫好問題的FAQ。不要轉儲您的代碼,並期望我們閱讀它並理解所做的一切。只發布相關代碼(a.k.a [SSCCE](http://sscce.org)),並描述一切工作。 – Mordechai 2013-04-03 22:04:00

+0

我最後一次發佈的相關代碼的人想整個事情 – 2013-04-03 22:05:00

+0

@BilboAsdfasd這可能意味着你還不是完全合格的,以確定哪些*相關*代碼。你需要練習並依靠他人的反饋。 – 2013-04-03 22:14:53

回答

3

有可能許多問題的答案。我能想到的最好的基本是設計某種「循環」。

甲週期的時間在其動畫可以運行公知的週期。在這個例子中,它是1秒。

然後,您需要提供一系列的通知的變化週期隨着時間的推移,這使得他們能夠做出相應的變化Animatable對象。您也可以忽略那些不需要循環的元素的循環。

的目的是提供一個單一動畫引擎可以負責一氣呵成更新整個狀態,而不是試圖用多個線程/定時器這可能會降低系統的性能。

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Container; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GridBagLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.text.NumberFormat; 
import java.util.ArrayList; 
import java.util.List; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class TestAnimation06 { 

    public static void main(String[] args) { 
     new TestAnimation06(); 
    } 

    public TestAnimation06() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public interface Animatable { 
     public void update(float progress); 
    } 

    public class AnimationEngine { 

     private List<Animatable> animations; 
     private int cycleTime = 1000; 
     private long startTime = -1; 

     public AnimationEngine() { 
      animations = new ArrayList<>(25); 
      Timer timer = new Timer(40, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        if (startTime < 0) { 
         startTime = System.currentTimeMillis(); 
        } 
        long duration = System.currentTimeMillis() - startTime; 
        float progress = (float)duration/(float)cycleTime; 
        if (duration >= cycleTime) { 
         progress = 1f; 
         startTime = System.currentTimeMillis(); 
        } 
        for (Animatable animatable : animations) { 
         animatable.update(progress); 
        } 
       } 
      }); 
      timer.setRepeats(true); 
      timer.setCoalesce(true); 
      timer.start(); 
     } 

     public void add(Animatable animatable) { 
      animations.add(animatable); 
     } 

    } 

    public class TestPane extends JPanel { 

     private AnimationEngine engine; 

     public TestPane() { 
      setLayout(null); 
      engine = new AnimationEngine(); 
      Legs legs = new Legs(); 
      Walker walker = new Walker(legs); 
      engine.add(legs); 
      engine.add(walker); 
      walker.setSize(walker.getPreferredSize()); 
      add(walker); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      g2d.dispose(); 
     } 
    } 

    public class Walker extends JPanel implements Animatable { 

     private int speed = 2; 

     public Walker(Legs legs) { 
      setLayout(new GridBagLayout()); 
      add(legs); 
     } 

     @Override 
     public void update(float progress) { 
      Container parent = getParent(); 
      int width = parent.getWidth(); 
      int xPos = getX() + speed; 
      if (xPos <= 0) { 
       speed *= -1; 
       xPos = 0; 
      } else if (xPos + getWidth() >= width) { 
       speed *= -1; 
       xPos = width - getWidth(); 
      } 
      System.out.println(xPos); 
      setLocation(xPos, (parent.getHeight() - getHeight())/2); 
      repaint(); 
     } 

    } 

    public class Legs extends JPanel implements Animatable { 

     private float frameProgress; 

     public Legs() { 
      setOpaque(false); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(25, 50); 
     } 

     @Override 
     public void update(float progress) { 
      frameProgress = progress; 
      repaint(); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      int width = getWidth(); 
      int height = getHeight(); 

      g.setColor(Color.BLACK); 
      g.drawLine(width/2, 0, (int)(width * frameProgress), height); 
      g.drawLine(width/2, 0, width - (int)(width * frameProgress), height); 
     } 

    } 

} 
+0

可能是一個新的'ProgressBarUI'。 :-) – trashgod 2013-04-04 09:11:38