2015-10-08 3 views
0

Ниже приведена программа Simon Says, над которой я работаю. Прямо сейчас отображается только серая рамка. Я добавил в keyListener, чтобы увидеть, могу ли я загореться дугами. Мне нужно отобразить последовательность анимации вспышки. Может кто-нибудь объяснить, почему это не работает?Simon Says не будет показывать последовательность

public class SimonShape extends JFrame implements KeyListener, ActionListener  { 

private JFrame f; 
private JPanel p; 

public static void main(String[] args) { 
    new SimonShape(); 
} 

public SimonShape() { 

    f = new JFrame("Simon Says"); 
    f.setSize(500, 500); 
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    DrawStuff draw = new DrawStuff(); 

    p = new JPanel(); 
    p.setBackground(Color.GRAY); 
    p.setLayout(new BorderLayout()); 
    draw.playSequence(); 
    p.add(draw, BorderLayout.CENTER); 
    // initiates the sequence 
    f.add(p); 
    f.addKeyListener(this); 
    f.setLocationRelativeTo(null); // positions the frame in the middle of 
            // the screen 


    f.setVisible(true); 

} 

public class DrawStuff extends JComponent { 

    Color COLOR1; 
    Color COLOR2; 
    Color COLOR3; 
    Color COLOR4; 

    public void playSequence() { 

     ArrayList<Integer> Computer = new ArrayList<Integer>(); 
     ArrayList<Integer> Player = new ArrayList<Integer>(); 

     int compPick, compPick2, compPick3, compPick4; 

     Random gen = new Random(); 

     compPick = gen.nextInt(4); 
     compPick2 = gen.nextInt(4); 
     compPick3 = gen.nextInt(4); 
     compPick4 = gen.nextInt(4); 

     Computer.add(compPick); 
     Computer.add(compPick4); 
     Computer.add(compPick2); 
     Computer.add(compPick3); 

     for (int i = 0; i < Computer.size(); i++) { 

      if (Computer.get(i) == 0) { 
       COLOR1 = Color.GREEN.brighter(); 
       repaint(); 
      } else if (Computer.get(i) == 1) { 
       COLOR2 = Color.BLUE.darker(); 
       repaint(); 

      } else if (Computer.get(i) == 2) { 
       COLOR3 = Color.RED.darker(); 
       repaint(); 

      } else if (Computer.get(i) == 3) { 
       COLOR4 = Color.YELLOW.brighter(); 
       repaint(); 
      } 
     } 

    } 

} 

public int flash = 0; 

public void paint(Graphics g) { 

    Graphics2D g2 = (Graphics2D) g; 
    Graphics2D g3 = (Graphics2D) g; 
    Graphics2D g4 = (Graphics2D) g; 
    Graphics2D g5 = (Graphics2D) g; 

    // assume d == 145 && e == 90 

    if (flash == 1) { 
     g2.setPaint(Color.GREEN); 
    } else { 
     g2.setPaint(Color.GREEN.darker()); 

    } 
    g2.fill(new Arc2D.Double(150, 150, 200, 200, 145, 90, Arc2D.PIE)); 
    if (flash == 2) { 
     g3.setPaint(Color.BLUE); 
    } else { 
     g3.setPaint(Color.BLUE.darker()); 
    } 
    g3.fill(new Arc2D.Double(150, 150, 200, 200, 235, 90, Arc2D.PIE)); 

    if (flash == 3) { 
     g4.setPaint(Color.RED); 
    } else { 
     g4.setPaint(Color.RED.darker()); 
    } 
    g4.fill(new Arc2D.Double(150, 150, 200, 200, 325, 90, Arc2D.PIE)); 
    if (flash == 4) { 
     g5.setPaint(Color.YELLOW); 
    } else { 
     g4.setPaint(Color.YELLOW.darker()); 
    } 
    g5.fill(new Arc2D.Double(150, 150, 200, 200, 55, 90, Arc2D.PIE)); 

} 
public void keyPressed(KeyEvent e) { 

    int event = e.getKeyCode(); 

    if (event == KeyEvent.VK_RIGHT) { 
     flash = 1; 
    } 
    if (event == KeyEvent.VK_DOWN) { 
     flash = 2; 
    } 
    if (event == KeyEvent.VK_LEFT) { 
     flash = 3; 
    } 
    if (event == KeyEvent.VK_UP) { 
     flash = 4; 
    } 
} 

@Override 
public void keyTyped(KeyEvent e) {//not used 

} 

@Override 
public void keyReleased(KeyEvent e) {//not used 

} 

@Override 
public void actionPerformed(ActionEvent e) {//not used 

} 

} 
+1

В стороне: заглавная буква из ваших имен переменных (например, 'int CompPick;'), как правило, является плохой практикой и должна использоваться только для имен классов. Я бы использовал camel-case ('int compPick;'). –

+0

Почему вы создаете еще один экземпляр 'DrawStuff' в вашем методе' playSequence()? Вы можете получить доступ к «COLOR1» и другим переменным без него, и он пока не появится, потому что этот экземпляр не добавлен в ваш JFrame. –

+0

Кроме того, 'gen.nextInt (4)' будет возвращать случайное число от 0 до 3, поэтому вы должны проверять их вместо 1-4. –

ответ

0

При создании любого графического интерфейса Swing, вы всегда должны использовать model/view/controller pattern. Этот шаблон позволяет вам разделить свои проблемы и сосредоточиться на одной части графического интерфейса одновременно.

Разделить и победить.

Вот GUI, который я создал.

Simon Says GUI

Первое, что я сделал, было создать модель для игры. Класс GameModel - это простой Java-объект, который содержит последовательность компьютеров и последовательность игроков.

public class GameModel { 

    private List<Integer> computerSequence; 
    private List<Integer> playerSequence; 

    private Random random; 

    public GameModel() { 
     this.computerSequence = new ArrayList<Integer>(); 
     this.playerSequence = new ArrayList<Integer>(); 
     this.random = new Random(); 
    } 

    public void addToComputerSequence() { 
     computerSequence.add(Integer.valueOf(random.nextInt(4))); 
    } 

    public void clearComputerSequence() { 
     computerSequence.clear(); 
    } 

    public List<Integer> getComputerSequence() { 
     return computerSequence; 
    } 

    public void clearPlayerSequence() { 
     playerSequence.clear(); 
    } 

    public void addToPlayerSequence(int number) { 
     playerSequence.add(Integer.valueOf(number)); 
    } 

    public boolean doSequencesMatch() { 
     if (computerSequence.size() == playerSequence.size()) { 
      for (int i = 0; i < computerSequence.size(); i++) { 
       int computer = computerSequence.get(i); 
       int player = playerSequence.get(i); 
       if (computer != player) { 
        return false; 
       } 
      } 

      return true; 
     } 

     return false; 
    } 

} 

модель класса позволяет добавить к компьютерной последовательности, добавить к последовательности игрока, и определить, если матч последовательности компьютера и игрока.

Далее нам нужен класс модели для хранения 4 срезов круга. Класс ArcModel - это еще один простой Java-объект, который содержит срез.

public class ArcModel { 

    private final int closureType; 

    private final double startingAngle; 
    private final double extent; 

    private Color color; 
    private final Color originalColor; 

    private final Rectangle rectangle; 

    public ArcModel(Color color, Rectangle rectangle, double startingAngle, 
      double extent, int closureType) { 
     this.color = color; 
     this.originalColor = color; 
     this.rectangle = rectangle; 
     this.startingAngle = startingAngle; 
     this.extent = extent; 
     this.closureType = closureType; 
    } 

    public int getClosureType() { 
     return closureType; 
    } 

    public double getStartingAngle() { 
     return startingAngle; 
    } 

    public double getExtent() { 
     return extent; 
    } 

    public Rectangle getRectangle() { 
     return rectangle; 
    } 

    public Color getColor() { 
     return color; 
    } 

    public void brighterColor() { 
     this.color = Color.WHITE; 
    } 

    public void darkerColor() { 
     this.color = originalColor; 
    } 

} 

В дополнении к добытчикам и сеттерам, у нас есть метод, чтобы скрасить цвет и способ затемнить цвет. Я установил яркий цвет в белый цвет, чтобы сделать его более заметным.

Теперь, когда мы создали классы моделей, давайте посмотрим на классы представления. Первый класс представления - это класс DrawingPanel.

public class DrawingPanel extends JPanel { 

    private static final long serialVersionUID = 70146219705119575L; 

    private List<ArcModel> segments; 

    public DrawingPanel() { 
     this.segments = new ArrayList<ArcModel>(); 

     int margin = 50; 
     int diameter = 300; 
     Rectangle r = new Rectangle(margin, margin, diameter, diameter); 

     segments.add(new ArcModel(Color.GREEN, r, 180, 90, Arc2D.PIE)); 
     segments.add(new ArcModel(Color.BLUE, r, 270, 90, Arc2D.PIE)); 
     segments.add(new ArcModel(Color.RED, r, 360, 90, Arc2D.PIE)); 
     segments.add(new ArcModel(Color.YELLOW, r, 90, 90, Arc2D.PIE)); 

     int width = diameter + margin + margin; 
     this.setPreferredSize(new Dimension(width, width)); 
    } 

    public void brighterArcModelColor(int index) { 
     segments.get(index).brighterColor(); 
     repaint(); 
    } 

    public void darkerArcModelColor(int index) { 
     segments.get(index).darkerColor(); 
     repaint(); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     Graphics2D g2d = (Graphics2D) g; 

     for (ArcModel arcModel : segments) { 
      g2d.setPaint(arcModel.getColor()); 
      Rectangle r = arcModel.getRectangle(); 
      g2d.fill(new Arc2D.Double(r.getX(), r.getY(), r.getWidth(), r 
        .getHeight(), arcModel.getStartingAngle(), arcModel 
        .getExtent(), arcModel.getClosureType())); 
     } 
    } 

} 

Здесь мы создаем список сегментов ArcModel. Мы устанавливаем размер панели чертежа на основе поля и диаметра круга, который мы хотим создать с помощью сегментов.

У нас есть два метода: один для осветления цвета сегмента, а другой для потемнения цвета сегмента.

Мы делаем рисунок в методе paintComponent. Поскольку мы создали класс ArcModel, фактический чертеж прост. Метод paintComponent ничего не делает, кроме как рисовать кусочки кружочка круга.

Далее мы рассмотрим основной класс SimonShape. Этот класс создает модель игры и создает графический интерфейс.

public class SimonShape implements Runnable { 

    private GameModel gameModel; 

    private JFrame frame; 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new SimonShape()); 
    } 

    public SimonShape() { 
     this.gameModel = new GameModel(); 
    } 

    @Override 
    public void run() { 
     frame = new JFrame("Simon Says"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     DrawingPanel drawingPanel = new DrawingPanel(); 
     frame.add(drawingPanel); 

     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 

     GameRunnable runnable = new GameRunnable(drawingPanel, gameModel); 
     new Thread(runnable).start(); 
    } 
} 

Последние две строки метода запуска создают анимацию.

Класс контроллера - класс GameRunnable. Я написал достаточно кода, чтобы компьютер выбрал 10 случайных сегментов и отобразил последовательность сегментов. Я оставляю остальную часть кода игры до вас. Он войдет в класс GameRunnable.

public class GameRunnable implements Runnable { 

    private volatile boolean running; 

    private DrawingPanel drawingPanel; 

    private GameModel gameModel; 

    public GameRunnable(DrawingPanel drawingPanel, GameModel gameModel) { 
     this.drawingPanel = drawingPanel; 
     this.gameModel = gameModel; 
    } 

    @Override 
    public void run() { 
     running = true; 
     while (running && gameModel.getComputerSequence().size() < 10) { 
      generateComputerSequence(); 
      sleep(1800L); 
     } 
    } 

    private void generateComputerSequence() { 

     gameModel.addToComputerSequence(); 
     for (Integer index : gameModel.getComputerSequence()) { 
      drawingPanel.brighterArcModelColor(index); 
      sleep(1000L); 
      drawingPanel.darkerArcModelColor(index); 
      sleep(200L); 
     } 

    } 

    private void sleep(long duration) { 
     try { 
      Thread.sleep(duration); 
     } catch (InterruptedException e) { 

     } 
    } 

    public synchronized void setRunning(boolean running) { 
     this.running = running; 
    } 

} 

Помните, что разделите и победителю. Удачи с остальной частью кода.

Смежные вопросы