【问题标题】:How to draw Rectangle loop to draw a wall in a game?如何绘制矩形循环以在游戏中绘制墙壁?
【发布时间】:2021-05-07 08:42:08
【问题描述】:

如何创建Rectangle 循环,使其看起来像游戏中的一堵墙?

我不必分别创建和绘制每个矩形。在Rectangle 类中我还没有找到设置坐标的setter。

【问题讨论】:

  • Rectangle 本身只需要很少的开销(内存等),但如果您想要来自同一个矩形的多个绘图,请使用 AffineTransform 移动/旋转/缩放每个矩形或正在绘制它们的 Graphics 对象。
  • “我怎样才能创建一个矩形循环,让它看起来像游戏中的一堵墙?”根据需要创建尽可能多的 Rectangle 实例,将它们放入 java.util.List 中,然后在您的绘图 JPanel 中,读取 List 并绘制/填充 Rectangle 实例。
  • (1-) 我还没有找到设置坐标的setter。 - 你用的是什么矩形类?通过指定 x/y/width/height 创建矩形。或者您可以使用 setLocation(...) 方法。
  • @camickr 我以为我只能设置 x 或 y
  • @GilbertLeBlanc 如果我想用不同的坐标、宽度和高度绘制呢?

标签: java loops swing jframe coordinates


【解决方案1】:

我创建了一些东西,您可能可以将其用于我正在开发的坦克游戏。

这是图形用户界面

要使用此 GUI,您左键单击您想要墙的位置。如果左键单击墙壁,墙壁部分会消失。

SaveGameGridListeneractionPerformed 方法中,我硬编码了文本文件输出的特定位置。你会想要改变它。

此 GUI 的输出是一个 44 个字符的 22 行文本文件,由 0 和 1 值组成。 0 表示比赛场地,1 表示墙。您可能需要为 Packman 游戏调整比赛场地的尺寸。

这是这个特定游戏板的文本文件。

00000000000000000000011000000000000000000000
00000000000000000000011000000000000000000000
00000000000000000000000000000000000000000000
00000111000000000000000000000000000011100000
00000000000000000000000000000000000000000000
00000000000001111000000000011110000000000000
00000000000001000000000000000010000000000000
00001100000000000000000000000000000000110000
00000100000000000000000000000000000000100000
00000100000000000000000000000000000000100000
00000100011000000000011000000000011000100000
00000100011000000000011000000000011000100000
00000100000000000000000000000000000000100000
00000100000000000000000000000000000000100000
00001100000000000000000000000000000000110000
00000000000001000000000000000010000000000000
00000000000001111000000000011110000000000000
00000000000000000000000000000000000000000000
00000111000000000000000000000000000011100000
00000000000000000000000000000000000000000000
00000000000000000000011000000000000000000000
00000000000000000000011000000000000000000000

现在,我的游戏板很稀疏。你的游戏板会有更多的墙,但你可以使用和我一样的原理。

  1. 创建一个包含 0 和 1 的文本文件以生成您的游戏板。
  2. 使用文本文件创建您的游戏板。

这是我使用的完整可运行代码。我把所有的类都做成了内部类,这样我就可以将代码作为一个块发布。代码在项目的 Resources 文件夹中需要一个 grid.txt 文件。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileFilter;

public class GenerateGameGrid implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new GenerateGameGrid());
    }

    @Override
    public void run() {
        new GenerateGameGridFrame(new GameGrid());
    }
    
    public class GenerateGameGridFrame {
        
        private final GameGrid gameGrid;
        
        private final GenerateGameGridPanel generateGameGridPanel;
        
        private final JFrame frame;

        public GenerateGameGridFrame(GameGrid gameGrid) {
            this.gameGrid = gameGrid;
            this.generateGameGridPanel = new GenerateGameGridPanel(this, gameGrid);
            this.frame = createAndShowGUI();
        }
        
        private JFrame createAndShowGUI() {
            JFrame frame = new JFrame("Generate Game Grid");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setJMenuBar(createJMenuBar());
            
            frame.add(generateGameGridPanel, BorderLayout.CENTER);
            
            frame.pack();
            frame.setLocationByPlatform(true);
            frame.setVisible(true);
            
            System.out.println(frame.getSize());
            
            return frame;
        }
        
        private JMenuBar createJMenuBar() {
            JMenuBar menuBar = new JMenuBar();
            
            JMenu fileMenu = new JMenu("File");
            
            JMenuItem saveItem = new JMenuItem("Save Game Grid...  ");
            saveItem.setAccelerator(KeyStroke.getKeyStroke("control S"));
            saveItem.addActionListener(new SaveGameGridListener(this, gameGrid));
            fileMenu.add(saveItem);
            
            fileMenu.addSeparator();
            
            JMenuItem exitItem = new JMenuItem("Exit");
            exitItem.setAccelerator(KeyStroke.getKeyStroke("alt X"));
            exitItem.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent event) {
                    frame.dispose();
                    System.exit(0);
                }
            });
            fileMenu.add(exitItem);
            
            menuBar.add(fileMenu);
            
            return menuBar;
        }

        public JFrame getFrame() {
            return frame;
        }
        
        public void repaint() {
            generateGameGridPanel.repaint();
        }

    }
    
    public class GameGrid {
        
        private final int blockwidth;
        private final int margin;

        private final int[][] grid;
        
        private final Color backgroundColor;
        private final Color foregroundColor;
        
        public GameGrid() {
            this.blockwidth = 24;
            this.margin = 10;
            this.backgroundColor = new Color(187, 71, 14);
            this.foregroundColor = new Color(244, 192, 83);
            this.grid = readGrid();
        }
        
        private int[][] readGrid() {
            int[][] grid = new int[22][44];
            
            try {
                readGrid(grid, "grid.txt");
            } catch (IOException e) {
                e.printStackTrace();
            }
            
            return grid;
        }
        
        private void readGrid(int[][] grid, String filename) throws IOException {
            InputStream is = getClass().getResourceAsStream("/" + filename);
            InputStreamReader streamReader = new InputStreamReader(is, StandardCharsets.UTF_8);
            BufferedReader reader = new BufferedReader(streamReader);
            
            int row = 0;
            String line = reader.readLine();
            while (line != null) {
                char[] chars = line.toCharArray();
                for (int column = 0; column < chars.length; column++) {
                    grid[row][column] = Integer.valueOf(Character.toString(chars[column]));
                }
                row++;
                line = reader.readLine();
            }
            reader.close();
        }

        public int[][] getGrid() {
            return grid;
        }

        public Color getBackgroundColor() {
            return backgroundColor;
        }

        public Color getForegroundColor() {
            return foregroundColor;
        }

        public int getBlockwidth() {
            return blockwidth;
        }

        public int getMargin() {
            return margin;
        }
        
    }

    public class GenerateGameGridPanel extends JPanel {
        
        private static final long serialVersionUID = 1L;
        
        private final GameGrid gameGrid;
        
//      private final GenerateGameGridFrame frame;

        public GenerateGameGridPanel(GenerateGameGridFrame frame, GameGrid gameGrid) {
//          this.frame = frame;
            this.gameGrid = gameGrid;
            
            int[][] grid = gameGrid.getGrid();
            int blockwidth = gameGrid.getBlockwidth();
            int margin = gameGrid.getMargin();
            int height = blockwidth * (grid.length + 2) + margin + margin;
            int width = blockwidth * (grid[0].length + 2) + margin + margin;
            this.setBackground(gameGrid.getBackgroundColor());
            this.setPreferredSize(new Dimension(width, height));
            this.addMouseListener(new BlockListener(frame, gameGrid));
        }
        
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            g2d.setRenderingHint(
                    RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
            drawBorder(g2d);
            drawGrid(g2d, gameGrid.getGrid());
        }
        
        private void drawBorder(Graphics2D g2d) {
            int blockwidth = gameGrid.getBlockwidth();
            int margin = gameGrid.getMargin();
            
            int x = margin;
            int y = margin;
            int width = getWidth() - margin - margin;
            int height = blockwidth;
            
            g2d.setColor(gameGrid.getForegroundColor());
            g2d.fillRect(x, y, width, height);
            
            x = margin;
            y = margin;
            width = blockwidth;
            height = getHeight() - margin - margin;
            
            g2d.fillRect(x, y, width, height);
            
            x = margin;
            y = getHeight() - margin - blockwidth;
            width = getWidth() - margin - margin;
            height = blockwidth;
            
            g2d.fillRect(x, y, width, height);
            
            x = getWidth() - blockwidth - margin;
            y = margin;
            width = blockwidth;
            height = getHeight() - margin - margin;
            
            g2d.fillRect(x, y, width, height);
        }
        
        private void drawGrid(Graphics2D g2d, int[][] grid) {
            int blockwidth = gameGrid.getBlockwidth();
            int margin = gameGrid.getMargin();
            g2d.setColor(gameGrid.getForegroundColor());
            
            for (int row = 0; row < grid.length; row++) {
                for (int column = 0; column < grid[row].length; column++) {
                    if (grid[row][column] == 1) {
                        int x = (column + 1) * blockwidth + margin;
                        int y = (row + 1) * blockwidth + margin;
                        g2d.fillRect(x, y, blockwidth, blockwidth);
                    }
                }
            }
        }

    }
    
    public class BlockListener extends MouseAdapter {

        private final GameGrid gameGrid;
        
        private final GenerateGameGridFrame frame;
        
        public BlockListener(GenerateGameGridFrame frame, GameGrid gameGrid) {
            this.frame = frame;
            this.gameGrid = gameGrid;
        }

        @Override
        public void mouseReleased(MouseEvent event) {
            int[][] grid = gameGrid.getGrid();
            int blockwidth = gameGrid.getBlockwidth();
            int margin = gameGrid.getMargin();
            Point point = event.getPoint();
            int row = (point.y - margin - blockwidth) / blockwidth;
            int column = (point.x - margin - blockwidth) / blockwidth;
            grid[row][column] = grid[row][column] ^ 1;
            frame.repaint();
        }

    }
    
    public class SaveGameGridListener implements ActionListener {

        private final GameGrid gameGrid;
        
        private final GenerateGameGridFrame frame;
        
        public SaveGameGridListener(GenerateGameGridFrame frame, GameGrid gameGrid) {
            this.frame = frame;
            this.gameGrid = gameGrid;
        }

        @Override
        public void actionPerformed(ActionEvent event) {
            OSFileChooser fc = new OSFileChooser();
            File dir = new File("D:\\Eclipse\\Eclipse-2020-workspace\\com.ggl.combat\\resources");
            fc.setCurrentDirectory(dir);
            fc.addChoosableFileFilter(new FileTypeFilter( 
                    "Text", "txt"));
            fc.setAcceptAllFileFilterUsed(false);
            
            int returnVal = fc.showSaveDialog(frame.getFrame());
            if (returnVal == OSFileChooser.APPROVE_OPTION) {
                File file = fc.getSelectedFile();
                try {
                    writeFile(file);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        
        private void writeFile(File file) throws IOException {
            int[][] grid = gameGrid.getGrid();
            BufferedWriter writer = new BufferedWriter(new FileWriter(file));
            for (int row = 0; row < grid.length; row++) {
                StringBuilder builder = new StringBuilder();
                for (int column = 0; column < grid[row].length; column++) {
                    builder.append(grid[row][column]);
                }
                builder.append(System.lineSeparator());
                writer.write(builder.toString());
            }
            writer.close();
        }

    }
    
    public class OSFileChooser extends JFileChooser {

        private static final long serialVersionUID = 1L;

        @Override
        public void approveSelection() {
            File f = getSelectedFile();
            
            if (f.exists() && getDialogType() == SAVE_DIALOG) {
                int result = JOptionPane.showConfirmDialog(this, f.getName() + 
                        " exists, overwrite?",
                        "Existing file", JOptionPane.YES_NO_CANCEL_OPTION);
                switch (result) {
                case JOptionPane.YES_OPTION:
                    super.approveSelection();
                    return;
                case JOptionPane.NO_OPTION:
                    return;
                case JOptionPane.CLOSED_OPTION:
                    return;
                case JOptionPane.CANCEL_OPTION:
                    cancelSelection();
                    return;
                }
            }
            
            super.approveSelection();
        }
        
        @Override
        public File getSelectedFile() {
            File file = super.getSelectedFile();
            
            if (file != null && getDialogType() == SAVE_DIALOG) {
                String extension = getExtension(file);
                if (extension.isEmpty()) {
                    FileTypeFilter filter = (FileTypeFilter) getFileFilter();
                    if (filter != null) {
                        extension = filter.getExtension();
                        String fileName = file.getPath();
                        fileName += "." + extension;
                        file = new File(fileName);
                    }
                }
            }
            
            return file;
        }
        
        public String getExtension(File file) {
            String extension = "";
            String s = file.getName();
            int i = s.lastIndexOf('.');

            if (i > 0 && i < (s.length() - 1)) {
                extension = s.substring(i + 1).toLowerCase();
            }

            return extension;
        }
        
    }
    
    public class FileTypeFilter extends FileFilter {
        private String extension;
        private String description;
     
        public FileTypeFilter(String description, String extension) {
            this.extension = extension;
            this.description = description;
        }
     
        @Override
        public boolean accept(File file) {
            if (file.isDirectory()) {
                return true;
            }
            return file.getName().endsWith("." + extension);
        }
     
        @Override
        public String getDescription() {
            return description + String.format(" (*.%s)", extension);
        }
        
        public String getExtension() {
            return extension;
        }
        
    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-10
    • 1970-01-01
    • 2013-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-22
    相关资源
    最近更新 更多