Java - How to create a multi-threaded game using SwingWorker

I want to create a game [1 Player vs PC] with streams.

We have 10 * 10 two colors in our board:

enter image description here

when a player clicks on BLUE Circles, their color turns gray.

on the other hand, the PC should turn all the RED Rectangles into gray.

A WINNER is one who Cleans all his own forms earlier.


The code for the player works fine, but, My problem is to implement the PC-side of the game, as I read in this article , I have to use SwingWorker to implement Threading in the GUI. This is my first time using SwingWorkers, and I don’t know how this should work correctly.

Here are my codes:

Main class

public class BubblePopGame { public static final Color DEFAULT_COLOR1 = Color.BLUE; public static final Color DEFAULT_COLOR2 = Color.RED; public BubblePopGame() { List<ShapeItem> shapes = new ArrayList<ShapeItem>(); int Total = 10; for (int i = 1; i <= Total; i++) { for (int j = 1; j <= Total; j++) { if ((i + j) % 2 == 0) { shapes.add(new ShapeItem(new Ellipse2D.Double(i * 25, j * 25, 20, 20), DEFAULT_COLOR1)); } else { shapes.add(new ShapeItem(new Rectangle2D.Double(i * 25, j * 25, 20, 20), DEFAULT_COLOR2)); } } } JFrame frame = new JFrame("Bubble Pop Quest!!"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); ShapesPanel panel = new ShapesPanel(shapes); frame.add(panel); frame.setLocationByPlatform(true); frame.pack(); frame.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { new BubblePopGame(); } }); } 

}

Form element class

 public class ShapeItem { private Shape shape; private Color color; public ShapeItem(Shape shape, Color color) { super(); this.shape = shape; this.color = color; } public Shape getShape() { return shape; } public void setShape(Shape shape) { this.shape = shape; } public Color getColor() { return color; } public void setColor(Color color) { this.color = color; } 

}

Class ShapesPanel

 public class ShapesPanel extends JPanel { private List<ShapeItem> shapes; private Random rand = new Random(); private SwingWorker<Boolean, Integer> worker; public ShapesPanel(List<ShapeItem> shapesList) { this.shapes = shapesList; worker = new SwingWorker<Boolean, Integer>() { @Override protected Boolean doInBackground() throws Exception { while (true) { Thread.sleep(200); int dim = rand.nextInt(300); publish(dim); return true; } } @Override protected void done() { Boolean Status; try { Status = get(); System.out.println(Status); super.done(); //To change body of generated methods, choose Tools | Templates. } catch (InterruptedException ex) { Logger.getLogger(ShapesPanel.class.getName()).log(Level.SEVERE, null, ex); } catch (ExecutionException ex) { Logger.getLogger(ShapesPanel.class.getName()).log(Level.SEVERE, null, ex); } } @Override protected void process(List<Integer> chunks) { int mostRecentValue = chunks.get(chunks.size()-1); System.out.println(mostRecentValue); Color color2 = Color.LIGHT_GRAY; ShapeItem tmpShape = shapes.get(mostRecentValue); if(tmpShape.getColor()==Color.RED){ tmpShape.setColor(color2); } repaint(); } }; worker.execute (); addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { Color color1 = Color.LIGHT_GRAY; for (ShapeItem item : shapes) { if (item.getColor() == Color.BLUE) { if (item.getShape().contains(e.getPoint())) { item.setColor(color1); } } } repaint(); } }); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g.create(); for (ShapeItem item : shapes) { g2.setColor(item.getColor()); g2.fill(item.getShape()); } g2.dispose(); } @Override public Dimension getPreferredSize() { return new Dimension(300, 300); } private Color getRandomColor() { return new Color(rand.nextFloat(), rand.nextFloat(), rand.nextFloat()); } 

}

+6
source share
1 answer

If I understand your code correctly, you are making a game in which the human player must click as quickly as possible on all of his pieces, while the PC accidentally clicks on the pieces. The first who cleans all his forms will win.

If this is correct, you probably want to configure SwingWorker to

  • until the game is over. Your loop is currently completing the first time the loop end is reached due to the return
  • Since you are not doing anything with the SwingWorker return SwingWorker , you can also let it return void
  • No need to call get in the done method. The moment this method is called, SwingWorker completes. You are only interested in intermediate results.
  • In the process method, you can iterate over all the values. Note that the process method is not called every time you publish something. The values ​​you publish are grouped and passed in bulk to the process method when EDT (Event Dispatch Thread) is available
+4
source

Source: https://habr.com/ru/post/977555/


All Articles