2014-10-31 1 views
6

스레드가있는 [1 명의 플레이어 대 PC] 게임을 만들고 싶습니다.자바 - SwingWorker를 사용하여 멀티 스레드 게임을 만드는 방법

우리는 다음과 같이 우리의 보드 10 개 * 10 두 색상 모양이 : 플레이어는 파란색 동그라미를 클릭 할 때

enter image description here

은, 그들의 색깔은 회색으로 변합니다.

반대쪽 PC는 모든 RED 사각형을 회색으로 바꿔야합니다.

승자가 누구입니까 더 이상 자신의 모든 셰이프를 지 웁니다.


플레이어에 대한 코드가 잘 작동하지만, 내 문제는 내가이 article에서 읽을 때 나는 GUI에서 스레딩을 구현하는 SwingWorker를 사용해야합니다, 게임의 PC 측의 구현입니다. 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

+0

작업자가 제대로 작동하지 않습니다. 스크린 샷에서 볼 수 있듯이 직사각형은 회색으로 바뀌지 않습니다 ... –

+2

doInBackground()는 첫 번째 루프 반복 후에 끝납니다. – Durandal

답변

4

난 당신의 코드가 제대로, 당신은 인간의 플레이어가 자신의 모양 모두에 가능한 한 빨리 클릭하는 게임을 만들고 이해하면 동안 PC는 도형을 무작위로 클릭합니다. 그의 모든 모양을 제거하는 첫 번째 승리. 즉 올바른 경우

, 당신은 아마 게임이 끝날 때까지 당신의 SwingWorker

  • 에 루프를 조정합니다. 현재 루프 종료 루프의 끝이 return 문으로 인해 도달 처음
  • 당신이 SwingWorker의 부울 반환 값으로 작업을 수행하지 않는 때문에
  • , 당신은뿐만 아니라 그것을 무효
  • 필요 반환하지 할 수 있습니다 done 메서드에서 get으로 전화하십시오. 메서드가 호출되는 순간에 SwingWorker이 완료되었습니다.
  • process 메서드에서 모든 값을 반복 할 수 있습니다.process 방법은 이 아니며 이라고 각각이라고 부릅니다. 시간이 publish 일 것입니다. 게시 한 값은 그룹화되어 EDT (Event Dispatch Thread)를 사용할 수있는 경우 process 메서드로 대량 전달됩니다.
+0

고마워요. @Robin, 대답은 나를 위해 스윙 노동자를 명확히했고, 문제는 희망적으로 해결되었습니다. :) –

+1

@Mahdi Rashidi가 예외 또는 결과를주의 깊게 반환합니다. – mKorbel

관련 문제