【问题标题】:How to draw things only in a certain area?如何只在某个区域绘制东西?
【发布时间】:2014-06-02 03:27:09
【问题描述】:

我正在制作一款塔防游戏,我将有一些标记,根据它们的放置位置,它们有可能被绘制到游戏网格之外。我一直在我的游戏类的一个画布上绘制所有东西,我想知道是否有一种方法可以只在设定的区域(在本例中是我的游戏网格)中绘制某些东西。

为了更好地解释它,如果要在游戏网格的边缘画一个圆圈,就像要切断的悬垂一样。

我的 gui 是什么样子的:

【问题讨论】:

    标签: java canvas draw area


    【解决方案1】:

    一种方法可能是调整Graphics 上下文的剪辑。我个人不喜欢弄乱剪辑,因为如果你不小心,它可能会严重影响你。

    查看Clipping the Drawing Region了解更多详情

    剪辑示例

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.imageio.ImageIO;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class TestClip {
    
        public static void main(String[] args) {
            new TestClip();
        }
    
        public TestClip() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            private BufferedImage img;
    
            public TestPane() {
                setBackground(Color.BLACK);
                try {
                    img = ImageIO.read(new File("Lurk.png"));
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(400, 400);
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g.create();
                g2d.setColor(Color.RED);
                g2d.drawRect(100, 100, 200, 200);
                g2d.setClip(101, 101, 199, 199);
                g2d.drawImage(img, 300 - (img.getWidth() / 2), (getHeight() - img.getHeight()) / 2, this);
                g2d.dispose();
            }
        }
    
    }
    

    另一种方法可能是生成一个透明的BufferedImage 作为图层,您可以确保将绘画限制为正确的大小,将这些附加元素绘制到其上,然后绘制生成的BufferedImage地图上方

    图层示例

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.imageio.ImageIO;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class TestClip {
    
        public static void main(String[] args) {
            new TestClip();
        }
    
        public TestClip() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            private BufferedImage img;
            private BufferedImage layer;
    
            public TestPane() {
                setBackground(Color.BLACK);
                try {
                    img = ImageIO.read(new File("Lurk.png"));
                    layer = new BufferedImage(199, 199, BufferedImage.TYPE_INT_ARGB);
                    Graphics2D g2d = layer.createGraphics();
                    g2d.drawImage(img, 
                            layer.getWidth() - (img.getWidth() / 2), 
                            (layer.getHeight() - img.getHeight()) / 2, 
                            this);
                    g2d.dispose();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(400, 400);
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g.create();
                g2d.setColor(Color.RED);
                g2d.drawRect(100, 100, 200, 200);
                g2d.drawImage(layer, 101, 101, this);
    //            g2d.setClip(101, 101, 199, 199);
    //            g2d.drawImage(img, 300 - (img.getWidth() / 2), (getHeight() - img.getHeight()) / 2, this);
                g2d.dispose();
            }
        }
    
    }
    

    【讨论】:

    • 非常感谢!我从来不知道 setClip()。现在我已经在我的前景渲染中设置了它,所以它不会干扰游戏其余部分中发生的任何重要事情。如果出现问题,我会研究 layer 方法。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-29
    • 2023-03-18
    • 2017-05-31
    • 1970-01-01
    • 2011-06-06
    相关资源
    最近更新 更多