<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>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 碰撞檢測 > 原文: [https://zetcode.com/tutorials/javagamestutorial/collision/](https://zetcode.com/tutorials/javagamestutorial/collision/) 在 Java 2D 游戲教程的這一部分中,我們將討論碰撞檢測。 許多游戲都需要處理碰撞,尤其是街機游戲。 簡而言之,我們需要檢測兩個對象何時在屏幕上碰撞。 在下一個代碼示例中,我們將擴展上一個示例。 我們添加了一個新的外星人精靈。 我們將檢測兩種類型的碰撞:當導彈擊中外星人的飛船和我們的航天器與外星人相撞時。 ## 射擊外星人 在示例中,我們有一個航天器和外星人。 我們可以使用光標鍵在板上移動航天器。 用空格鍵發射消滅外星人的導彈。 `Sprite.java` ```java package com.zetcode; import java.awt.Image; import java.awt.Rectangle; import javax.swing.ImageIcon; public class Sprite { protected int x; protected int y; protected int width; protected int height; protected boolean visible; protected Image image; public Sprite(int x, int y) { this.x = x; this.y = y; visible = true; } protected void getImageDimensions() { width = image.getWidth(null); height = image.getHeight(null); } protected void loadImage(String imageName) { ImageIcon ii = new ImageIcon(imageName); image = ii.getImage(); } public Image getImage() { return image; } public int getX() { return x; } public int getY() { return y; } public boolean isVisible() { return visible; } public void setVisible(Boolean visible) { this.visible = visible; } public Rectangle getBounds() { return new Rectangle(x, y, width, height); } } ``` 可以由所有子畫面(工藝品,外星人和導彈)共享的代碼放在`Sprite`類中。 ```java public Rectangle getBounds() { return new Rectangle(x, y, width, height); } ``` `getBounds()`方法返回精靈圖像的邊界矩形。 在碰撞檢測中我們需要邊界。 `SpaceShip.java` ```java package com.zetcode; import java.awt.event.KeyEvent; import java.util.ArrayList; import java.util.List; public class SpaceShip extends Sprite { private int dx; private int dy; private List<Missile> missiles; public SpaceShip(int x, int y) { super(x, y); initCraft(); } private void initCraft() { missiles = new ArrayList<>(); loadImage("src/resources/spaceship.png"); getImageDimensions(); } public void move() { x += dx; y += dy; if (x < 1) { x = 1; } if (y < 1) { y = 1; } } public List<Missile> getMissiles() { return missiles; } public void keyPressed(KeyEvent e) { int key = e.getKeyCode(); if (key == KeyEvent.VK_SPACE) { fire(); } if (key == KeyEvent.VK_LEFT) { dx = -1; } if (key == KeyEvent.VK_RIGHT) { dx = 1; } if (key == KeyEvent.VK_UP) { dy = -1; } if (key == KeyEvent.VK_DOWN) { dy = 1; } } public void fire() { missiles.add(new Missile(x + width, y + height / 2)); } public void keyReleased(KeyEvent e) { int key = e.getKeyCode(); if (key == KeyEvent.VK_LEFT) { dx = 0; } if (key == KeyEvent.VK_RIGHT) { dx = 0; } if (key == KeyEvent.VK_UP) { dy = 0; } if (key == KeyEvent.VK_DOWN) { dy = 0; } } } ``` 此類代表航天器。 ```java private List<Missile> missiles; ``` 航天器發射的所有導彈都存儲在`missiles`列表中。 ```java public void fire() { missiles.add(new Missile(x + width, y + height / 2)); } ``` 當我們發射導彈時,新的`Missile`對象將添加到`missiles`列表中。 它會保留在列表中,直到與外星人碰撞或離開窗口為止。 `Board.java` ```java package com.zetcode; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.util.ArrayList; import java.util.List; import javax.swing.JPanel; import javax.swing.Timer; public class Board extends JPanel implements ActionListener { private Timer timer; private SpaceShip spaceship; private List<Alien> aliens; private boolean ingame; private final int ICRAFT_X = 40; private final int ICRAFT_Y = 60; private final int B_WIDTH = 400; private final int B_HEIGHT = 300; private final int DELAY = 15; private final int[][] pos = { {2380, 29}, {2500, 59}, {1380, 89}, {780, 109}, {580, 139}, {680, 239}, {790, 259}, {760, 50}, {790, 150}, {980, 209}, {560, 45}, {510, 70}, {930, 159}, {590, 80}, {530, 60}, {940, 59}, {990, 30}, {920, 200}, {900, 259}, {660, 50}, {540, 90}, {810, 220}, {860, 20}, {740, 180}, {820, 128}, {490, 170}, {700, 30} }; public Board() { initBoard(); } private void initBoard() { addKeyListener(new TAdapter()); setFocusable(true); setBackground(Color.BLACK); ingame = true; setPreferredSize(new Dimension(B_WIDTH, B_HEIGHT)); spaceship = new SpaceShip(ICRAFT_X, ICRAFT_Y); initAliens(); timer = new Timer(DELAY, this); timer.start(); } public void initAliens() { aliens = new ArrayList<>(); for (int[] p : pos) { aliens.add(new Alien(p[0], p[1])); } } @Override public void paintComponent(Graphics g) { super.paintComponent(g); if (ingame) { drawObjects(g); } else { drawGameOver(g); } Toolkit.getDefaultToolkit().sync(); } private void drawObjects(Graphics g) { if (spaceship.isVisible()) { g.drawImage(spaceship.getImage(), spaceship.getX(), spaceship.getY(), this); } List<Missile> ms = spaceship.getMissiles(); for (Missile missile : ms) { if (missile.isVisible()) { g.drawImage(missile.getImage(), missile.getX(), missile.getY(), this); } } for (Alien alien : aliens) { if (alien.isVisible()) { g.drawImage(alien.getImage(), alien.getX(), alien.getY(), this); } } g.setColor(Color.WHITE); g.drawString("Aliens left: " + aliens.size(), 5, 15); } private void drawGameOver(Graphics g) { String msg = "Game Over"; Font small = new Font("Helvetica", Font.BOLD, 14); FontMetrics fm = getFontMetrics(small); g.setColor(Color.white); g.setFont(small); g.drawString(msg, (B_WIDTH - fm.stringWidth(msg)) / 2, B_HEIGHT / 2); } @Override public void actionPerformed(ActionEvent e) { inGame(); updateShip(); updateMissiles(); updateAliens(); checkCollisions(); repaint(); } private void inGame() { if (!ingame) { timer.stop(); } } private void updateShip() { if (spaceship.isVisible()) { spaceship.move(); } } private void updateMissiles() { List<Missile> ms = spaceship.getMissiles(); for (int i = 0; i < ms.size(); i++) { Missile m = ms.get(i); if (m.isVisible()) { m.move(); } else { ms.remove(i); } } } private void updateAliens() { if (aliens.isEmpty()) { ingame = false; return; } for (int i = 0; i < aliens.size(); i++) { Alien a = aliens.get(i); if (a.isVisible()) { a.move(); } else { aliens.remove(i); } } } public void checkCollisions() { Rectangle r3 = spaceship.getBounds(); for (Alien alien : aliens) { Rectangle r2 = alien.getBounds(); if (r3.intersects(r2)) { spaceship.setVisible(false); alien.setVisible(false); ingame = false; } } List<Missile> ms = spaceship.getMissiles(); for (Missile m : ms) { Rectangle r1 = m.getBounds(); for (Alien alien : aliens) { Rectangle r2 = alien.getBounds(); if (r1.intersects(r2)) { m.setVisible(false); alien.setVisible(false); } } } } private class TAdapter extends KeyAdapter { @Override public void keyReleased(KeyEvent e) { spaceship.keyReleased(e); } @Override public void keyPressed(KeyEvent e) { spaceship.keyPressed(e); } } } ``` 這是`Board`類。 ```java private final int[][] pos = { {2380, 29}, {2500, 59}, {1380, 89}, {780, 109}, {580, 139}, {680, 239}, {790, 259}, {760, 50}, {790, 150}, {980, 209}, {560, 45}, {510, 70}, {930, 159}, {590, 80}, {530, 60}, {940, 59}, {990, 30}, {920, 200}, {900, 259}, {660, 50}, {540, 90}, {810, 220}, {860, 20}, {740, 180}, {820, 128}, {490, 170}, {700, 30} }; ``` 這些是外星飛船的初始位置。 ```java public void initAliens() { aliens = new ArrayList<>(); for (int[] p : pos) { aliens.add(new Alien(p[0], p[1])); } } ``` `initAliens()`方法創建一個外星對象列表。 外星人從`pos`數組中占據初始位置。 ```java @Override public void paintComponent(Graphics g) { super.paintComponent(g); if (ingame) { drawObjects(g); } else { drawGameOver(g); } Toolkit.getDefaultToolkit().sync(); } ``` 在`paintComponent()`方法內,我們繪制游戲精靈或通過消息編寫游戲。 這取決于`ingame`變量。 ```java private void drawObjects(Graphics g) { if (spaceship.isVisible()) { g.drawImage(spaceship.getImage(), spaceship.getX(), spaceship.getY(), this); } ... } ``` `drawObjects()`方法在窗口上繪制游戲精靈。 首先,我們繪制工藝精靈。 ```java for (Alien alien : aliens) { if (alien.isVisible()) { g.drawImage(alien.getImage(), alien.getX(), alien.getY(), this); } } ``` 在這個循環中,我們吸引了所有外星人。 僅在以前未銷毀它們的情況下才繪制它們。 通過`isVisible()`方法檢查。 ```java g.setColor(Color.WHITE); g.drawString("Aliens left: " + aliens.size(), 5, 15); ``` 在窗口的左上角,我們繪制了剩余的外星人數量。 ```java private void drawGameOver(Graphics g) { String msg = "Game Over"; Font small = new Font("Helvetica", Font.BOLD, 14); FontMetrics fm = getFontMetrics(small); g.setColor(Color.white); g.setFont(small); g.drawString(msg, (B_WIDTH - fm.stringWidth(msg)) / 2, B_HEIGHT / 2); } ``` `drawGameOver()`在窗口中間的消息上方繪制游戲。 該消息顯示在游戲結束時,當我們摧毀所有外星飛船或與其中一艘發生碰撞時。 ```java @Override public void actionPerformed(ActionEvent e) { inGame(); updateShip(); updateMissiles(); updateAliens(); checkCollisions(); repaint(); } ``` 每個動作事件代表一個游戲周期。 游戲邏輯被納入特定方法中。 例如,`updateMissiles()`會移動所有可用的導彈。 ```java private void updateAliens() { if (aliens.isEmpty()) { ingame = false; return; } for (int i = 0; i < aliens.size(); i++) { Alien a = aliens.get(i); if (a.isVisible()) { a.move(); } else { aliens.remove(i); } } } ``` 在`updateAliens()`方法內部,我們首先檢查`aliens`列表中是否還有任何異物。 如果列表為空,則游戲結束。 如果它不為空,則瀏覽列表并移動其所有項目。 被摧毀的外星人將從名單中刪除。 ```java public void checkCollisions() { Rectangle r3 = spaceship.getBounds(); for (Alien alien : aliens) { Rectangle r2 = alien.getBounds(); if (r3.intersects(r2)) { spaceship.setVisible(false); alien.setVisible(false); ingame = false; } } ... } ``` `checkCollisions()`方法檢查可能的沖突。 首先,我們檢查工藝對象是否與任何外來對象發生碰撞。 我們使用`getBounds()`方法獲得對象的矩形。 `intersects()`方法檢查兩個矩形是否相交。 ```java List<Missile> ms = spaceship.getMissiles(); for (Missile m : ms) { Rectangle r1 = m.getBounds(); for (Alien alien : aliens) { Rectangle r2 = alien.getBounds(); if (r1.intersects(r2)) { m.setVisible(false); alien.setVisible(false); } } } ``` 該代碼檢查導彈與外星人之間的碰撞。 `Alien.java` ```java package com.zetcode; public class Alien extends Sprite { private final int INITIAL_X = 400; public Alien(int x, int y) { super(x, y); initAlien(); } private void initAlien() { loadImage("src/resources/alien.png"); getImageDimensions(); } public void move() { if (x < 0) { x = INITIAL_X; } x -= 1; } } ``` 這是`Alien`類。 ```java public void move() { if (x < 0) { x = INITIAL_X; } x -= 1; } ``` 外星人消失在左側后,他們會返回到右側的屏幕。 `Missile.java` ```java package com.zetcode; public class Missile extends Sprite { private final int BOARD_WIDTH = 390; private final int MISSILE_SPEED = 2; public Missile(int x, int y) { super(x, y); initMissile(); } private void initMissile() { loadImage("src/resources/missile.png"); getImageDimensions(); } public void move() { x += MISSILE_SPEED; if (x > BOARD_WIDTH) visible = false; } } ``` 這是`Missile`類。 ```java public void move() { x += MISSILE_SPEED; if (x > BOARD_WIDTH) visible = false; } ``` 導彈只能向一個方向移動。 它們到達右窗口邊框后消失。 `CollisionEx.java` ```java package com.zetcode; import java.awt.EventQueue; import javax.swing.JFrame; public class CollisionEx extends JFrame { public CollisionEx() { initUI(); } private void initUI() { add(new Board()); setResizable(false); pack(); setTitle("Collision"); setLocationRelativeTo(null); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main(String[] args) { EventQueue.invokeLater(() -> { CollisionEx ex = new CollisionEx(); ex.setVisible(true); }); } } ``` 最后,這是主要類。 ![Shooting aliens](https://img.kancloud.cn/f0/23/f0232211640358662b2bcbb3166f13ab_402x326.jpg) 圖:射擊外星人 本章是關于碰撞檢測的。
                  <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>

                              哎呀哎呀视频在线观看