2014-10-31 79 views
6

我想创建一个带有线程的[单人游戏与PC]游戏。Java - 如何使用SwingWorker创建多线程游戏

我们有10种* 10两种颜色形状在我们的板是这样的:

enter image description here

当玩家点击蓝色圆圈,它们的颜色变成灰色。

在另一边PC应该把所有的RED矩形变成灰色。

WINNER是谁清除所有他/她自己的形状更早。


代码为球员工作正常,但, 我的问题是在执行游戏的PC端,正如我在本article阅读我应该使用的SwingWorker在GUI来实现线程。 这是我第一次使用SwingWorkers,我不知道它应该如何正常工作。

这里是我的代码:

主类

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(); 
     } 
    }); 
} 

}

形状的物品类别

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; 
} 

}

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()); 
} 

}

+1

那么......问题在哪里? – Coffee 2014-10-31 16:50:51

+0

工作人员无法正常工作。正如你在屏幕截图中看到的,矩形没有变成灰色...... – 2014-10-31 16:54:43

+2

你的doInBackground()在第一次循环迭代后结束。 – Durandal 2014-10-31 17:39:43

回答

4

如果我理解你的代码正确,你是一个游戏,人类玩家必须尽可能快地点击他所有的形状,而PC也随机点击形状。第一个清除所有形状的胜利。

如果这是正确的,你可能想,直到比赛结束调整SwingWorker

  • 循环。目前你的循环退出的第一时间,由于到向return语句循环结束
  • 既然你没有做任何事情与SwingWorker的布尔返回值,你还不如让它返回void
  • 没有必要在done方法中调用get。该方法被调用的时刻,SwingWorker已完成。您只对中间结果感兴趣
  • process方法中,您可能需要遍历所有值。请注意,process方法是不是每个时间你publish东西。当发布EDT(Event Dispatch Thread)时,您发布的值将被批量分组并传递至process方法
+0

非常感谢@Robin,你的回答为我澄清了Swing Workers,并且希望问题得到解决:) – 2014-10-31 18:19:23

+1

@Mahdi Rashidi得到了返回异常或结果,仔细地 – mKorbel 2014-11-01 09:27:09