如何绘制矩形循环以在游戏中绘制墙壁?

问题描述

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

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

解决方法

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

这是图形界面

Generate Game Grid

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

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

这个 GUI 的输出是一个 44 个字符的 22 行文本文件,由 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. 创建一个包含零和一的文本文件来生成您的游戏板。
  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,height);
            
            x = margin;
            y = getHeight() - margin - blockwidth;
            width = getWidth() - margin - margin;
            height = blockwidth;
            
            g2d.fillRect(x,height);
            
            x = getWidth() - blockwidth - margin;
            y = margin;
            width = blockwidth;
            height = getHeight() - margin - margin;
            
            g2d.fillRect(x,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,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;
        }
        
    }

}