如何在不重置Java的情况下绘制多个对象

Posted

技术标签:

【中文标题】如何在不重置Java的情况下绘制多个对象【英文标题】:How to paint multiple objects without reset Java 【发布时间】:2020-06-20 15:27:34 【问题描述】:

当我开始康威生命游戏时,我正在尝试绘制单个单元格 (20x20px)。当我单击屏幕时,我绘制一个单元格,或者根据数组中单元格的状态将其删除。这是可行的,但是,在任何给定时刻,屏幕上只能出现一个单元格,我不确定为什么如果单击屏幕的不同部分,单元格数组中的位置会发生变化。

主代码



import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferStrategy;
import java.util.ArrayList;
import java.util.Iterator;

public class mainApplication extends JFrame implements Runnable, MouseListener 


    private static final Dimension windowsize = new Dimension(80, 600);
    private BufferStrategy strategy;
    private static boolean isGraphicsInitialised = false;
    private static int rows = 40;
    private static int columns = 40;
    private static int height = windowsize.height;
    private static int width = windowsize.width;
    private static ArrayList<Cell> cellsList = new ArrayList<>();
    private int xArrayElement,yArrayElement, xPosition, yPosition;
    private static boolean gameState[][] = new boolean[rows][columns];


    public mainApplication() 


        System.out.println(System.getProperty("user.dir"));

        setDefaultCloseOperation(EXIT_ON_CLOSE);
        Dimension screensize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();

        int x = screensize.width / 2 - width / 2;
        int y = screensize.height / 2 - height / 2;

        setBounds(x, y, screensize.width, screensize.height);

        setVisible(true);

        createBufferStrategy(2);

        strategy = getBufferStrategy();

        isGraphicsInitialised = true;

       // MouseEvent mouseEvent = new MouseEvent();
        addMouseListener(this);
       // addMouseMotionListener(MouseEvent);

        Thread t = new Thread(this);

        t.start();

    


    public void mousePressed(MouseEvent e)  

    public void mouseReleased(MouseEvent e)  

    public void mouseEntered(MouseEvent e)  

    public void mouseExited(MouseEvent e)  

    public void mouseClicked(MouseEvent e) 

           int x = e.getX();
           int y = e.getY();

            xArrayElement = (x/20);
            yArrayElement = (y/20);

            xPosition = x - (x % 20);
            yPosition = y - (y % 20);

//      cellList.removeIf(cell -> cell.contains(xPosition, yPosition));

        Iterator<Cell> iterator = cellsList.iterator();

        if (e.getButton() == MouseEvent.BUTTON3) 
            while (iterator.hasNext()) 
                if (iterator.next().contains(xPosition, yPosition)) 
                    iterator.remove();
                
            
        

        else

            cellsList.add(new Cell(xPosition, yPosition));
        


    

    @Override
    public void run() 
            while (true) 

                try  //threads entry point
                    Thread.sleep(20); //forces us to  catch exception
                

                catch (InterruptedException e) 
                
            
        


    public void paint(Graphics g) 

        if (isGraphicsInitialised) 
            g = strategy.getDrawGraphics();
            g.setColor(Color.BLACK);
            g.fillRect(0, 0, 800, 800);

            if(cellsList != null) 

                for (Cell cell : cellsList) 
                    cell.paint(g);
                    System.out.println("test");
                
            

        this.repaint();
        strategy.show();
        
    

    public static void main(String[]args)

        mainApplication test = new mainApplication();

    

细胞类

import java.awt.*;

public class Cell 

    int x;
    int y;


    public Cell(int x, int y)
        this.x = x;
        this.y = y;
    


    public boolean contains(int xx, int yy) 

        return xx >= x && yy >= y && xx <= x + 20 && yy <= y + 20;
    

    public void paint(Graphics g)
        g.setColor(Color.white);
        g.fillRect(x, y, 20,20);
    


【问题讨论】:

记住我的另一个答案。当您单击一个单元格时,将该单元格添加到某种列表中。重新绘制时,请遍历列表并重新绘制所在位置的所有单元格。这是因为每次重绘时都会清除背景(这是您应该做的)。所以每次都需要刷新屏幕。我将编写一个快速演示,以便您查看。 嘿,抱歉,在看到您的其他答案之前,我实际上已经上传了这个,但我一直在努力解决这个问题。我做了一个列表,添加了单元格。在我遍历列表的绘制方法中,如果列表中有一个元素,我会绘制单元格,如果没有,那么我会创建一个 if 语句来绘制任何被删除的单元格。然而,从来没有画过任何东西。我会为你更新我的代码 【参考方案1】:

这是一个供您检查的示例。它使用鼠标添加或删除彩色方块。要添加正方形,请将鼠标放在面板中的某处,然后单击左键。要删除,请将鼠标放在正方形上,然后单击右键。请注意,每单击一次鼠标,我都会修改列表并重新绘制整个列表。

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class AddingSquares 
    JFrame f = new JFrame("Demo");

    public AddingSquares() 
        f.add(new MyPanel(500, 500));
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // compress various components and invoke any 
        // layout managers.
        f.pack();
        // center on screen
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    

    public static void main(String[] args) 
        // start on the EDT
        SwingUtilities.invokeLater(() -> new AddingSquares());
    



class MyPanel extends JPanel 

    public MyPanel(int w, int h) 
        // the following statement won't work unless you
        // do super.paintComponent().
        setBackground(Color.white);
        setPreferredSize(new Dimension(w, h));
        addMouseListener(new MyMouseListener());
    

    List<Square> list = new ArrayList<>();
    int side = 20;

    public void paintComponent(Graphics g) 
        super.paintComponent(g);
        // I prefer graphics2D as it has additional features.
        // Not using any here though.
        Graphics2D g2d = (Graphics2D) g.create();
        if (list != null) 
            for (Square sq : list) 
                sq.draw(g2d);
            
        

        g2d.dispose();
    

    private class MyMouseListener extends MouseAdapter 
        public void mouseClicked(MouseEvent me) 
            int x = me.getX();
            int y = me.getY();
            // right mouse button removes square
            if (me.getButton() == MouseEvent.BUTTON3) 
                Iterator<Square> it = list.iterator();
                while (it.hasNext()) 
                    if (it.next().contains(x, y)) 
                        it.remove();
                        break;
                    
                
             else 
                // I want the square drawn with the mouse at the center, not upper left
                // corner, so I adjust the coordinates
                list.add(new Square(x - side/2, y - side/2));
            
            repaint();
        
    
    // this could be an external class but it is convenient for this demo.
    private class Square 
        int x;
        int y;
        Color color = Color.blue;

        public Square(int x, int y) 
            this.x = x;
            this.y = y;
        

        // used to find the right square to remove
        public boolean contains(int xx, int yy) 
            return xx >= x && yy >= y && xx <= x + side
                    && yy <= y + side;
        

        public void draw(Graphics2D g2d) 
            g2d.setColor(color);
            g2d.fillRect(x, y, side, side);
        
    


【讨论】:

啊,要是我能在那个级别上编码就好了,我只使用 java 大约 7 或 8 个月,所以总有一天我会到达那里。因此,相反,在鼠标单击的方法中,如果您右键单击并且在这些坐标处有一个正方形,则将其删除。否则你添加一个新的正方形。请问,你的 contains 布尔方法是如何工作的,我发现它有点难以想象。 我将正方形的位置存储在 x,y 处,它的边长是边 = 20。假设我有一个 300,200 的正方形。因此,我检查是否在 >= 300 和 >= 200 和 哦,我明白了,这是一种非常简洁且合乎逻辑的方法,我正忙于做其他事情,但我稍后会更多地研究它。再次非常感谢您! 嘿WJS,我拿了你给我的一些工具并修改了我的代码。我在我的帖子中更新了它,所以你可以看到我做了什么。我知道它与您的操作方式不完全一样,但我想采用您的工具并以一种与我已有的工具配合使用的方式实施它们,以便我真正理解它!但是,我已经很完整了,当我右键单击以删除正方形时,如果连接了正方形/单元格,则会删除多个正方形,就像它们彼此相邻时被视为一个对象一样,我不知道为什么.你已经做的够多了,但代码就在那里!非常感谢!

以上是关于如何在不重置Java的情况下绘制多个对象的主要内容,如果未能解决你的问题,请参考以下文章

如何在不重置位置的情况下更改 UIButton?

如何在不从表单中删除数据的情况下重置 BootstrapValidator? [复制]

通知意图 - 如何在不重置的情况下恢复通知中的活动?

如何使用 git reset 在不丢失本地更改的情况下重置未推送的提交

如何在不覆盖之前数据的情况下创建多个 java txt 文件? [复制]

如何在不重置其当前状态的情况下从一个视图控制器到自身进行转场?