西蒙说不会显示序列

时间:2015-10-08 17:16:40

标签: java methods jframe jpanel jcomponent

以下是我正在研究的S​​imon Says计划。现在它只显示一个灰色框。我在keyListener中添加了以查看是否可以使弧点亮。我想显示一个flash动画序列。有人可以解释为什么这不起作用吗?

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 个答案:

答案 0 :(得分:0)

创建任何Swing GUI时,应始终使用model / view / controller pattern。此模式允许您将您的关注点分开,并一次关注GUI的一部分。

分而治之。

这是我创建的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;
    }

}

除了getter和setter之外,我们还有一种提亮颜色的方法和一种使颜色变暗的方法。我将亮色设置为白色,使其更容易看清。

现在我们已经创建了模型类,让我们看一下视图类。第一个视图类是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的主要课程。该类创建游戏模型并创建GUI。

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

run方法的最后两行创建动画。

控制器类是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;
    }

}

记住,分而治之。祝其他代码好运。