0

我正在尝试用 Java 编写一个名为 HighLow 的简单 GUI 骰子游戏。基本上,用户以 50 英镑的初始余额开始,他们可以选择三种不同的投注金额,如果他们选择低,则骰子必须落在 2、3、4、5 或 6 上并支付 1:1,如果他们选择高,骰子必须落在 8、9、10、11 或 12 上,赔率为 1:1。如果他们选择 7,骰子必须落在 7 上,赔率为 4:1。有两个骰子,所以两者的值都应该相加。这不是我问题的重点,只是想我会澄清这一点,以便您了解游戏的重点。

我对面板、事件处理和类似的东西完全陌生,所以我目前正在学习,但我在尝试解决这个问题时遇到了一些困难。我有五个类: Dice.java 包含一个 getFaceValue() 和 throwDie() 方法来模拟骰子的随机投掷。DiceFace.java 创建带有点/点的骰子。DiceFaceViewer.java 是框架类。DiceFaceComponent 是两个骰子的组件,GamePanel 是所有 JButton 和 JComboBox 等所在的面板。

这就是我到目前为止所做的:创建一个框架,将带有按钮等的面板粘贴进去,然后将骰子图像添加到框架中。我想要的是每当我单击“投掷骰子”按钮时,骰子就会被重新绘制到带有随机面的框架上。如果我打开和关闭窗口,它现在所做的就是生成一个随机的脸。

骰子

import java.util.Random;
public class Dice {

    // Instance variables
    private int faceValue;
    private int sides;
    private Random generator;

    public Dice(int s) {
        generator = new Random();
        sides = s;
        faceValue = generator.nextInt(sides) + 1;
    }

    // Simulates the throw of a die landing on a random face.
    public int throwDie() {
        return faceValue = (int)(Math.random() * sides) + 1;
    }

    // Returns the current face value of the die
    public int getFaceValue() {
        return faceValue;
    }

    // Set face value of die
    public void setValue(int v) {
        faceValue = v;
    }
}

骰子脸

import java.awt.*;
import java.awt.geom.*;

public class DiceFace {

    // Holds the seven possible dot positions on a standard die
    private Ellipse2D.Double[] dots = new Ellipse2D.Double[7];

    private Rectangle box;
    private int xLeft;
    private int yTop;
    private int side;
    private int diceValue;

    public DiceFace(int s, int x, int y, int v) {
        side = s;       // Dimension of dice face
        xLeft = x;      // xPos
        yTop = y;       // yPos
        diceValue = v;  // Pip value
    }

    public void draw(Graphics2D g2) {
        box = new Rectangle(xLeft, yTop, side, side);
        makeDots();

        // Black background
        g2.setColor(Color.BLACK);
        g2.fill(box);

        // White dots on black
        g2.setColor(Color.WHITE);

        // Draw dots
        if (diceValue == 1) 
            g2.fill(dots[0]);

        else if (diceValue == 2) {
            g2.fill(dots[1]); g2.fill(dots[2]);
        }

        else if (diceValue == 3) {
            g2.fill(dots[0]); g2.fill(dots[1]); g2.fill(dots[2]);
        }

        else if (diceValue == 4) {
            g2.fill(dots[1]); g2.fill(dots[2]);
            g2.fill(dots[3]); g2.fill(dots[4]);
        }

        else if (diceValue == 5) {
            g2.fill(dots[0]); g2.fill(dots[1]);
            g2.fill(dots[2]); g2.fill(dots[3]); g2.fill(dots[4]);
        }

        else if (diceValue == 6) {
            g2.fill(dots[1]); g2.fill(dots[2]); g2.fill(dots[3]);
            g2.fill(dots[4]); g2.fill(dots[5]); g2.fill(dots[6]);
        }
    }

    public void makeDots() {

        int w = side/6; // Dot width
        int h = side/6; // Dot height

        dots[0] =  new Ellipse2D.Double(xLeft + (2.5 * side)/6,
                yTop + (2.5 * side)/6, h, w);

        dots[1] = new Ellipse2D.Double(xLeft + (3.75 * side)/6,
                yTop + (3.75 * side)/6, h, w);

        dots[2] = new Ellipse2D.Double(xLeft + (1.25 * side)/6,
                yTop + (1.25 * side)/6, h, w);

        dots[3] = new Ellipse2D.Double(xLeft + (1.25 * side)/6,
                yTop + (3.75 * side)/6, h, w);

        dots[4] = new Ellipse2D.Double(xLeft + (3.75 * side)/6,
                yTop + (1.25 * side)/6, h, w);

        dots[5] =  new Ellipse2D.Double(xLeft + (1.25 * side)/6,
                yTop + (2.5 * side)/6, h, w);

        dots[6] =  new Ellipse2D.Double(xLeft + (3.75 * side)/6,
                yTop + (2.5 * side)/6, h, w);
    }
}

DiceFaceViewer

import java.awt.*;
import javax.swing.*;

public class DiceFaceViewer {
    public static void main(String[] args) {

        // Create frame
        JFrame frame = new JFrame();

        // Set frame attributes
        frame.getContentPane().setPreferredSize(new Dimension(360, 320));
        frame.pack();
        frame.setTitle("High Low");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);

        // Set location of frame to centre screen
        Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();

        int w = frame.getSize().width;
        int h = frame.getSize().height;
        int x = (dim.width-w)/2;
        int y = (dim.height-h)/2;
        frame.setLocation(x, y);

        DiceFaceComponent component = new DiceFaceComponent();
        frame.add(component);

        // Add panel to frame
        GamePanel panel = new GamePanel();
        frame.add(panel, BorderLayout.NORTH);

        frame.setVisible(true);
    }
}

骰子面组件

import java.awt.*;
import javax.swing.*;

public class DiceFaceComponent extends JComponent {

    // Instance variables
    private int faceValue1;
    private int faceValue2;

    public DiceFaceComponent() {
        faceValue1 = new Dice(6).getFaceValue();
        faceValue2 = new Dice(6).getFaceValue();
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        // Recover Graphics2D
        Graphics2D g2 = (Graphics2D) g;

        DiceFace dice1 = new DiceFace(75, 66, 160, faceValue1); // s, x, y, v
        dice1.draw(g2);
        repaint();

        DiceFace dice2 = new DiceFace(75, 219, 160, faceValue2);
        dice2.draw(g2);
        repaint();
    }
}

游戏面板

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class GamePanel extends JPanel {

    private int balance = 50;

    public GamePanel() {

        // Components
        JRadioButton highButton = new JRadioButton("High");
        JRadioButton lowButton = new JRadioButton("Low");
        JRadioButton sevensButton = new JRadioButton("Sevens");

        // Button group
        ButtonGroup bg = new ButtonGroup();
        bg.add(highButton);
        bg.add(lowButton);
        bg.add(sevensButton);

        add(highButton);
        add(lowButton);
        add(sevensButton);

        // Array to hold bet amounts
        String betAmounts[] = {"£10", "£5", "£1"};

        // Bets combo box
        JComboBox bets = new JComboBox(betAmounts);
        add(bets);

        // Balance
        JLabel bal = new JLabel(" Balance: £" + balance);
        add(bal);

        // Throw dice button
        final JButton throwButton = new JButton("Throw Dice");
        add(throwButton, FlowLayout.RIGHT);

        class Action implements ActionListener {

            Dice dice = new Dice(6);

            public void actionPerformed(ActionEvent e) {

                dice.throwDie();
                dice.getFaceValue();
            }
        }

        throwButton.addActionListener(new Action());
    }
}
4

1 回答 1

1

不要从任何paint方法中调用 repaint。这将导致重绘管理器安排另一个重绘事件,最终消耗您的 CPU 并停止您的编程。

而是调用repaint更新潜水面值的动作侦听器。

骰子和骰子之间也没有任何联系DiceFaceComponent,它永远不会知道它应该绘制什么值。

另外,在您的DiceFace课堂上,我不会费心在每次抽签上重新创建“点”,这只是浪费。而是在构造函数中创建它们。

paintComponent方法也是如此,不必费心重新创建 DiceFace,只需在构造类时创建两个引用并根据需要更新它们的面值。

我将使用Dice作为将所有各种元素联系在一起的基本模型。通过使用类似 a 的东西ChangeListerner,可以Dice通知各种组件发生了更改,从而允许它们更新屏幕

于 2012-10-28T19:07:28.983 回答