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

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # Java 益智游戲 > 原文: [https://zetcode.com/tutorials/javagamestutorial/puzzle/](https://zetcode.com/tutorials/javagamestutorial/puzzle/) 在 Java 游戲教程的這一部分中,我們創建一個 Java 解謎游戲克隆。 源代碼和圖像可以在作者的 Github [Java Swing 益智游戲](https://github.com/janbodnar/Puzzle-game-in-Java-Swing)存儲庫中找到。 ## Java 益智游戲要點 * 使用 Swing 和 Java 2D 圖形來構建游戲。 * 用`Collections.shuffle()`隨機打亂播放按鈕。 * 用`ImageIO.read()`加載圖像。 * 用`BufferedImage`調整圖像大小。 * 用`CropImageFilter`裁剪圖像。 * 用`GridLayout`布局按鈕。 * 使用兩個點的`ArrayLists`檢查解決方案。 ## Java 益智游戲示例 這個小游戲的目的是形成一張圖片。 通過單擊包含圖像的按鈕來移動它們。 只能移動與空按鈕相鄰的按鈕。 `PuzzleEx.java` ```java package com.zetcode; import java.awt.BorderLayout; import java.awt.Color; import java.awt.EventQueue; import java.awt.Graphics2D; import java.awt.GridLayout; import java.awt.Image; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.awt.image.CropImageFilter; import java.awt.image.FilteredImageSource; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.imageio.ImageIO; import javax.swing.AbstractAction; import javax.swing.BorderFactory; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JPanel; class MyButton extends JButton { private boolean isLastButton; public MyButton() { super(); initUI(); } public MyButton(Image image) { super(new ImageIcon(image)); initUI(); } private void initUI() { isLastButton = false; BorderFactory.createLineBorder(Color.gray); addMouseListener(new MouseAdapter() { @Override public void mouseEntered(MouseEvent e) { setBorder(BorderFactory.createLineBorder(Color.yellow)); } @Override public void mouseExited(MouseEvent e) { setBorder(BorderFactory.createLineBorder(Color.gray)); } }); } public void setLastButton() { isLastButton = true; } public boolean isLastButton() { return isLastButton; } } public class PuzzleEx extends JFrame { private JPanel panel; private BufferedImage source; private BufferedImage resized; private Image image; private MyButton lastButton; private int width, height; private List<MyButton> buttons; private List<Point> solution; private final int NUMBER_OF_BUTTONS = 12; private final int DESIRED_WIDTH = 300; public PuzzleEx() { initUI(); } private void initUI() { solution = new ArrayList<>(); solution.add(new Point(0, 0)); solution.add(new Point(0, 1)); solution.add(new Point(0, 2)); solution.add(new Point(1, 0)); solution.add(new Point(1, 1)); solution.add(new Point(1, 2)); solution.add(new Point(2, 0)); solution.add(new Point(2, 1)); solution.add(new Point(2, 2)); solution.add(new Point(3, 0)); solution.add(new Point(3, 1)); solution.add(new Point(3, 2)); buttons = new ArrayList<>(); panel = new JPanel(); panel.setBorder(BorderFactory.createLineBorder(Color.gray)); panel.setLayout(new GridLayout(4, 3, 0, 0)); try { source = loadImage(); int h = getNewHeight(source.getWidth(), source.getHeight()); resized = resizeImage(source, DESIRED_WIDTH, h, BufferedImage.TYPE_INT_ARGB); } catch (IOException ex) { Logger.getLogger(PuzzleEx.class.getName()).log( Level.SEVERE, null, ex); } width = resized.getWidth(null); height = resized.getHeight(null); add(panel, BorderLayout.CENTER); for (int i = 0; i < 4; i++) { for (int j = 0; j < 3; j++) { image = createImage(new FilteredImageSource(resized.getSource(), new CropImageFilter(j * width / 3, i * height / 4, (width / 3), height / 4))); MyButton button = new MyButton(image); button.putClientProperty("position", new Point(i, j)); if (i == 3 && j == 2) { lastButton = new MyButton(); lastButton.setBorderPainted(false); lastButton.setContentAreaFilled(false); lastButton.setLastButton(); lastButton.putClientProperty("position", new Point(i, j)); } else { buttons.add(button); } } } Collections.shuffle(buttons); buttons.add(lastButton); for (int i = 0; i < NUMBER_OF_BUTTONS; i++) { MyButton btn = buttons.get(i); panel.add(btn); btn.setBorder(BorderFactory.createLineBorder(Color.gray)); btn.addActionListener(new ClickAction()); } pack(); setTitle("Puzzle"); setResizable(false); setLocationRelativeTo(null); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } private int getNewHeight(int w, int h) { double ratio = DESIRED_WIDTH / (double) w; int newHeight = (int) (h * ratio); return newHeight; } private BufferedImage loadImage() throws IOException { BufferedImage bimg = ImageIO.read(new File("src/resources/icesid.jpg")); return bimg; } private BufferedImage resizeImage(BufferedImage originalImage, int width, int height, int type) throws IOException { BufferedImage resizedImage = new BufferedImage(width, height, type); Graphics2D g = resizedImage.createGraphics(); g.drawImage(originalImage, 0, 0, width, height, null); g.dispose(); return resizedImage; } private class ClickAction extends AbstractAction { @Override public void actionPerformed(ActionEvent e) { checkButton(e); checkSolution(); } private void checkButton(ActionEvent e) { int lidx = 0; for (MyButton button : buttons) { if (button.isLastButton()) { lidx = buttons.indexOf(button); } } JButton button = (JButton) e.getSource(); int bidx = buttons.indexOf(button); if ((bidx - 1 == lidx) || (bidx + 1 == lidx) || (bidx - 3 == lidx) || (bidx + 3 == lidx)) { Collections.swap(buttons, bidx, lidx); updateButtons(); } } private void updateButtons() { panel.removeAll(); for (JComponent btn : buttons) { panel.add(btn); } panel.validate(); } } private void checkSolution() { List<Point> current = new ArrayList<>(); for (JComponent btn : buttons) { current.add((Point) btn.getClientProperty("position")); } if (compareList(solution, current)) { JOptionPane.showMessageDialog(panel, "Finished", "Congratulation", JOptionPane.INFORMATION_MESSAGE); } } public static boolean compareList(List ls1, List ls2) { return ls1.toString().contentEquals(ls2.toString()); } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { PuzzleEx puzzle = new PuzzleEx(); puzzle.setVisible(true); } }); } } ``` 我們使用的是冰河世紀電影中 Sid 角色的圖像。 我們縮放圖像并將其切成十二塊。 這些片段由`JButton`組件使用。 最后一塊沒有使用; 我們有一個空按鈕。 您可以下載一些相當大的圖片并在游戲中使用它。 ```java addMouseListener(new MouseAdapter() { @Override public void mouseEntered(MouseEvent e) { setBorder(BorderFactory.createLineBorder(Color.yellow)); } @Override public void mouseExited(MouseEvent e) { setBorder(BorderFactory.createLineBorder(Color.gray)); } }); ``` 當我們將鼠標指針懸停在按鈕上時,其邊框變為黃色。 ```java public boolean isLastButton() { return isLastButton; } ``` 有一個按鈕稱為最后一個按鈕。 它是沒有圖像的按鈕。 其他按鈕與此空間交換空間。 ```java private final int DESIRED_WIDTH = 300; ``` 我們用來形成的圖像被縮放以具有所需的寬度。 使用`getNewHeight()`方法,我們可以計算新的高度,并保持圖像的比例。 ```java solution.add(new Point(0, 0)); solution.add(new Point(0, 1)); solution.add(new Point(0, 2)); solution.add(new Point(1, 0)); ... ``` 解決方案數組列表存儲形成圖像的按鈕的正確順序。 每個按鈕由一個`Point`標識。 ```java panel.setLayout(new GridLayout(4, 3, 0, 0)); ``` 我們使用`GridLayout`存儲我們的組件。 布局由 4 行和 3 列組成。 ```java image = createImage(new FilteredImageSource(resized.getSource(), new CropImageFilter(j * width / 3, i * height / 4, (width / 3), height / 4))); ``` `CropImageFilter`用于從已調整大小的圖像源中切出矩形。 它旨在與`FilteredImageSource`對象結合使用,以生成現有圖像的裁剪版本。 ```java button.putClientProperty("position", new Point(i, j)); ``` 按鈕由其`position`客戶端屬性標識。 這是包含按鈕在圖片中正確的行和列的位置的點。 這些屬性用于確定窗口中按鈕的順序是否正確。 ```java if (i == 3 && j == 2) { lastButton = new MyButton(); lastButton.setBorderPainted(false); lastButton.setContentAreaFilled(false); lastButton.setLastButton(); lastButton.putClientProperty("position", new Point(i, j)); } else { buttons.add(button); } ``` 沒有圖像的按鈕稱為最后一個按鈕。 它放置在右下角網格的末端。 該按鈕與被單擊的相鄰按鈕交換位置。 我們使用`setLastButton()`方法設置其`isLastButton`標志。 ```java Collections.shuffle(buttons); buttons.add(lastButton); ``` 我們隨機重新排列`buttons`列表的元素。 最后一個按鈕,即沒有圖像的按鈕,被插入到列表的末尾。 它不應該被改組,它總是在我們開始益智游戲時結束。 ```java for (int i = 0; i < NUMBER_OF_BUTTONS; i++) { MyButton btn = buttons.get(i); panel.add(btn); btn.setBorder(BorderFactory.createLineBorder(Color.gray)); btn.addActionListener(new ClickAction()); } ``` `buttons`列表中的所有組件都放置在面板上。 我們在按鈕周圍創建一些灰色邊框,并添加一個點擊動作監聽器。 ```java private int getNewHeight(int w, int h) { double ratio = DESIRED_WIDTH / (double) w; int newHeight = (int) (h * ratio); return newHeight; } ``` `getNewHeight()`方法根據所需的寬度計算圖像的高度。 圖像的比例保持不變。 我們使用這些值縮放圖像。 ```java private BufferedImage loadImage() throws IOException { BufferedImage bimg = ImageIO.read(new File("src/resources/icesid.jpg")); return bimg; } ``` 從磁盤加載了 JPG 圖像。 `ImageIO`的`read()`方法返回`BufferedImage`,這是 Swing 操縱圖像的重要類。 ```java private BufferedImage resizeImage(BufferedImage originalImage, int width, int height, int type) throws IOException { BufferedImage resizedImage = new BufferedImage(width, height, type); Graphics2D g = resizedImage.createGraphics(); g.drawImage(originalImage, 0, 0, width, height, null); g.dispose(); return resizedImage; } ``` 通過創建具有新大小的新`BufferedImage`來調整原始圖像的大小。 我們將原始圖像繪制到此新的緩沖圖像中。 ```java private void checkButton(ActionEvent e) { int lidx = 0; for (MyButton button : buttons) { if (button.isLastButton()) { lidx = buttons.indexOf(button); } } JButton button = (JButton) e.getSource(); int bidx = buttons.indexOf(button); if ((bidx - 1 == lidx) || (bidx + 1 == lidx) || (bidx - 3 == lidx) || (bidx + 3 == lidx)) { Collections.swap(buttons, bidx, lidx); updateButtons(); } } ``` 按鈕存儲在數組列表中。 然后,此列表將映射到面板的網格。 我們得到最后一個按鈕和被單擊按鈕的索引。 如果它們相鄰,則使用`Collections.swap()`進行交換。 ```java private void updateButtons() { panel.removeAll(); for (JComponent btn : buttons) { panel.add(btn); } panel.validate(); } ``` `updateButtons()`方法將列表映射到面板的網格。 首先,使用`removeAll()`方法刪除所有組件。 `for`循環用于通過`buttons`列表,將重新排序的按鈕添加回面板的布局管理器。 最后,`validate()`方法實現了新的布局。 ```java private void checkSolution() { List<Point> current = new ArrayList<>(); for (JComponent btn : buttons) { current.add((Point) btn.getClientProperty("position")); } if (compareList(solution, current)) { JOptionPane.showMessageDialog(panel, "Finished", "Congratulation", JOptionPane.INFORMATION_MESSAGE); } } ``` 通過將正確排序的按鈕的點列表與包含窗口中按鈕順序的當前列表進行比較,來完成解決方案檢查。 如果解決方案出現,則會顯示一個消息對話框。 ![Puzzle](https://img.kancloud.cn/81/f3/81f3bb4bc5c36817f1d05222c33bd6c5_310x260.jpg) 圖:創建圖像 這是用 Java 創建的益智游戲。
                  <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>

                              哎呀哎呀视频在线观看