<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 動畫 > 原文: [https://zetcode.com/tutorials/javagamestutorial/animation/](https://zetcode.com/tutorials/javagamestutorial/animation/) 在 Java 2D 游戲教程的這一部分中,我們將使用動畫。 ## 動畫 動畫是圖像序列的快速顯示,會產生運動的錯覺。 我們將為董事會上的星星設置動畫。 我們將以三種基本方式實現這一運動。 我們將使用 Swing 計時器,標準工具計時器和線程。 動畫是游戲編程中的一個復雜主題。 Java 游戲有望在具有不同硬件規格的多種操作系統上運行。 線程提供了最準確的計時解決方案。 但是,對于我們簡單的 2D 游戲,其他兩個選項也可以是一個選項。 ## Swing 計時器 在第一個示例中,我們將使用 Swing 計時器來創建動畫。 這是在 Java 游戲中為對象設置動畫的最簡單但最無效的方法。 `SwingTimerEx.java` ```java package com.zetcode; import java.awt.EventQueue; import javax.swing.JFrame; public class SwingTimerEx extends JFrame { public SwingTimerEx() { initUI(); } private void initUI() { add(new Board()); setResizable(false); pack(); setTitle("Star"); setLocationRelativeTo(null); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main(String[] args) { EventQueue.invokeLater(() -> { SwingTimerEx ex = new SwingTimerEx(); ex.setVisible(true); }); } } ``` 這是代碼示例的主要類。 ```java setResizable(false); pack(); ``` `setResizable()`設置是否可以調整幀大小。 `pack()`方法使此窗口的大小適合其子級的首選大小和布局。 請注意,這兩種方法的調用順序很重要。 (`setResizable()`在某些平臺上更改了幀的插入;在`pack()`方法之后調用此方法可能會導致錯誤的結果-星號不會精確地進入窗口的右下邊界。) `Board.java` ```java package com.zetcode; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Image; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.ImageIcon; import javax.swing.JPanel; import javax.swing.Timer; public class Board extends JPanel implements ActionListener { private final int B_WIDTH = 350; private final int B_HEIGHT = 350; private final int INITIAL_X = -40; private final int INITIAL_Y = -40; private final int DELAY = 25; private Image star; private Timer timer; private int x, y; public Board() { initBoard(); } private void loadImage() { ImageIcon ii = new ImageIcon("src/resources/star.png"); star = ii.getImage(); } private void initBoard() { setBackground(Color.BLACK); setPreferredSize(new Dimension(B_WIDTH, B_HEIGHT)); loadImage(); x = INITIAL_X; y = INITIAL_Y; timer = new Timer(DELAY, this); timer.start(); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); drawStar(g); } private void drawStar(Graphics g) { g.drawImage(star, x, y, this); Toolkit.getDefaultToolkit().sync(); } @Override public void actionPerformed(ActionEvent e) { x += 1; y += 1; if (y > B_HEIGHT) { y = INITIAL_Y; x = INITIAL_X; } repaint(); } } ``` 在`Board`類中,我們將星星從左上角移到右下角。 ```java private final int B_WIDTH = 350; private final int B_HEIGHT = 350; private final int INITIAL_X = -40; private final int INITIAL_Y = -40; private final int DELAY = 25; ``` 定義了五個常數。 前兩個常數是板的寬度和高度。 第三和第四是星星的初始坐標。 最后一個確定動畫的速度。 ```java private void loadImage() { ImageIcon ii = new ImageIcon("src/resources/star.png"); star = ii.getImage(); } ``` 在`loadImage()`方法中,我們創建`ImageIcon`類的實例。 該圖像位于項目目錄中。 `getImage()`方法將從此類返回`Image`對象。 該對象將繪制在板上。 ```java timer = new Timer(DELAY, this); timer.start(); ``` 在這里,我們創建一個 Swing `Timer`類,并調用其`start()`方法。 計時器每`DELAY`毫秒就會調用一次`actionPerformed()`方法。 為了使用`actionPerformed()`方法,我們必須實現`ActionListener`接口。 ```java @Override public void paintComponent(Graphics g) { super.paintComponent(g); drawStar(g); } ``` 自定義繪畫是通過`paintComponent()`方法完成的。 請注意,我們還調用其父級的`paintComponent()`方法。 實際繪畫將委托給`drawStar()`方法。 ```java private void drawStar(Graphics g) { g.drawImage(star, x, y, this); Toolkit.getDefaultToolkit().sync(); } ``` 在`drawStar()`方法中,我們使用`drawImage()`方法在窗口上繪制圖像。 `Toolkit.getDefaultToolkit().sync()`在緩沖圖形事件的系統上同步繪畫。 沒有這條線,動畫在 Linux 上可能會不流暢。 ```java @Override public void actionPerformed(ActionEvent e) { x += 1; y += 1; if (y > B_HEIGHT) { y = INITIAL_Y; x = INITIAL_X; } repaint(); } ``` 計時器反復調用`actionPerformed()`方法。 在方法內部,我們增加星形對象的 x 和 y 值。 然后我們調用`repaint()`方法,這將導致`paintComponent()`被調用。 這樣,我們可以定期重繪`Board`從而制作動畫。 ![Star](https://img.kancloud.cn/1c/a3/1ca3bf712a77fcf3f371ffbca624aa4a_280x240.jpg) 圖:星星 ## 實用計時器 這與以前的方法非常相似。 我們使用`java.util.Timer`代替`javax.Swing.Timer`。 對于 Java Swing 游戲,這種方式更為準確。 `UtilityTimerEx.java` ```java package com.zetcode; import java.awt.EventQueue; import javax.swing.JFrame; public class UtilityTimerEx extends JFrame { public UtilityTimerEx() { initUI(); } private void initUI() { add(new Board()); setResizable(false); pack(); setTitle("Star"); setLocationRelativeTo(null); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main(String[] args) { EventQueue.invokeLater(() -> { JFrame ex = new UtilityTimerEx(); ex.setVisible(true); }); } } ``` 這是主要的類。 `Board.java` ```java package com.zetcode; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Image; import java.awt.Toolkit; import java.util.Timer; import java.util.TimerTask; import javax.swing.ImageIcon; import javax.swing.JPanel; public class Board extends JPanel { private final int B_WIDTH = 350; private final int B_HEIGHT = 350; private final int INITIAL_X = -40; private final int INITIAL_Y = -40; private final int INITIAL_DELAY = 100; private final int PERIOD_INTERVAL = 25; private Image star; private Timer timer; private int x, y; public Board() { initBoard(); } private void loadImage() { ImageIcon ii = new ImageIcon("src/resources/star.png"); star = ii.getImage(); } private void initBoard() { setBackground(Color.BLACK); setPreferredSize(new Dimension(B_WIDTH, B_HEIGHT)); loadImage(); x = INITIAL_X; y = INITIAL_Y; timer = new Timer(); timer.scheduleAtFixedRate(new ScheduleTask(), INITIAL_DELAY, PERIOD_INTERVAL); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); drawStar(g); } private void drawStar(Graphics g) { g.drawImage(star, x, y, this); Toolkit.getDefaultToolkit().sync(); } private class ScheduleTask extends TimerTask { @Override public void run() { x += 1; y += 1; if (y > B_HEIGHT) { y = INITIAL_Y; x = INITIAL_X; } repaint(); } } } ``` 在此示例中,計時器將定期調用`ScheduleTask`類的`run()`方法。 ```java timer = new Timer(); timer.scheduleAtFixedRate(new ScheduleTask(), INITIAL_DELAY, PERIOD_INTERVAL); ``` 在這里,我們創建一個計時器并按特定的時間間隔安排任務。 有一個初始延遲。 ```java @Override public void run() { ... } ``` 計時器每 10 毫秒將調用此`run()`方法。 ## 線程 使用線程對對象進行動畫處理是最有效,最準確的動畫處理方式。 `ThreadAnimationEx.java` ```java package com.zetcode; import java.awt.EventQueue; import javax.swing.JFrame; public class ThreadAnimationEx extends JFrame { public ThreadAnimationEx() { initUI(); } private void initUI() { add(new Board()); setResizable(false); pack(); setTitle("Star"); setLocationRelativeTo(null); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main(String[] args) { EventQueue.invokeLater(() -> { JFrame ex = new ThreadAnimationEx(); ex.setVisible(true); }); } } ``` This is the main class. `Board.java` ```java package com.zetcode; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Image; import java.awt.Toolkit; import javax.swing.ImageIcon; import javax.swing.JOptionPane; import javax.swing.JPanel; public class Board extends JPanel implements Runnable { private final int B_WIDTH = 350; private final int B_HEIGHT = 350; private final int INITIAL_X = -40; private final int INITIAL_Y = -40; private final int DELAY = 25; private Image star; private Thread animator; private int x, y; public Board() { initBoard(); } private void loadImage() { ImageIcon ii = new ImageIcon("src/resources/star.png"); star = ii.getImage(); } private void initBoard() { setBackground(Color.BLACK); setPreferredSize(new Dimension(B_WIDTH, B_HEIGHT)); loadImage(); x = INITIAL_X; y = INITIAL_Y; } @Override public void addNotify() { super.addNotify(); animator = new Thread(this); animator.start(); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); drawStar(g); } private void drawStar(Graphics g) { g.drawImage(star, x, y, this); Toolkit.getDefaultToolkit().sync(); } private void cycle() { x += 1; y += 1; if (y > B_HEIGHT) { y = INITIAL_Y; x = INITIAL_X; } } @Override public void run() { long beforeTime, timeDiff, sleep; beforeTime = System.currentTimeMillis(); while (true) { cycle(); repaint(); timeDiff = System.currentTimeMillis() - beforeTime; sleep = DELAY - timeDiff; if (sleep < 0) { sleep = 2; } try { Thread.sleep(sleep); } catch (InterruptedException e) { String msg = String.format("Thread interrupted: %s", e.getMessage()); JOptionPane.showMessageDialog(this, msg, "Error", JOptionPane.ERROR_MESSAGE); } beforeTime = System.currentTimeMillis(); } } } ``` 在前面的示例中,我們以特定的間隔執行任務。 在此示例中,動畫將在線程內進行。 `run()`方法僅被調用一次。 這就是為什么我們在方法中有一個`while`循環的原因。 從該方法中,我們稱為`cycle()`和`repaint()`方法。 ```java @Override public void addNotify() { super.addNotify(); animator = new Thread(this); animator.start(); } ``` 在將我們的`JPanel`添加到`JFrame`組件后,將調用`addNotify()`方法。 此方法通常用于各種初始化任務。 我們希望我們的游戲以恒定的速度平穩運行。 因此,我們計算系統時間。 ```java timeDiff = System.currentTimeMillis() - beforeTime; sleep = DELAY - timeDiff; ``` `cycle()`和`repaint()`方法可能在不同的`while`周期中花費不同的時間。 我們計算兩種方法的運行時間,并將其從`DELAY`常數中減去。 這樣,我們要確保每個`while`周期都在恒定時間運行。 在我們的情況下,每個周期為`DELAY` ms。 Java 2D 游戲教程的這一部分涵蓋了動畫。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看