はじめに
こんにちは。前回の記事の最後でGridLayoutを使ってビンゴを作ろうと思い立ったので挑戦。
イメージは、
- 「ビンゴカード作成」ボタンでランダムな数字を5×5並べたカードを作る。数字が被らないようにする処理が難しそう...
- 「ゲーム開始」ボタンで、ゲーム画面に移行
- 「抽選」ボタンでランダムな数字がでて、カードのその数字があれば背景色を変えるとかそんなことをする。こっちも同じ数字は出ないようにしたいかも。
- (もしできそうだったら)リーチやビンゴ時に文字が表示されるようにする
こんな感じかな。ビンゴゲームと言いつつも、複数人でできる仕様じゃなくて、ただむなしく一人でやるもの笑
だいたいの見た目
画面サイズは適当。
public class BingoGame extends JFrame implements ActionListener{
JButton mkCardBtn;
JPanel BingoCardPanel;
JLabel bingoNumLabel[] = new JLabel[25];
Container c;
JButton startBtn;
Random random = new Random();
JFrame gameFrame;
JTextArea numLog;
JButton spinBtn;
ArrayList<Integer> numList = new ArrayList<Integer>();
public static void main(String[] args) {
BingoGame frame = new BingoGame();
frame.setVisible(true);
}
public BingoGame() {
setBounds(10,10,600,400);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mkCardBtn = new JButton("ビンゴカード作成");
mkCardBtn.addActionListener(this);
BingoCardPanel = new JPanel();
BingoCardPanel.setLayout(new GridLayout(5,5));
for(int i=0; i<bingoNumLabel.length; i++) {
String testNum = Integer.toString(i+1);
bingoNumLabel[i] = new JLabel(testNum);
LineBorder border = new LineBorder(Color.LIGHT_GRAY,2,true);
bingoNumLabel[i].setBorder(border);
BingoCardPanel.add(bingoNumLabel[i]);
}
JPanel p1_1 = new JPanel();
p1_1.setLayout(new GridLayout(1,2));
p1_1.add(mkCardBtn);
p1_1.add(BingoCardPanel);
startBtn =new JButton("ゲーム開始");
startBtn.addActionListener(this);
c = getContentPane();
c.add(p1_1, BorderLayout.CENTER);
c.add(startBtn, BorderLayout.SOUTH);
}
・ビンゴカードを作る部分はGridLayoutで5×5に設定し、マスごとにJLabelを置いている。JLabelにsetBorderメソッド
で枠線をつけて、ビンゴカードっぽく見えるようにしてみた。
・25個JLabelを宣言するのはめんどくさかったので、for文を使ってまとめて作成してみた。
・この画面に設置するボタンは2種類。
ひとつめは、「ビンゴカード作成」ボタン。これをおすと、カードにランダムな数字が表れるようにする。
2つ目は、「ゲーム開始」ボタン。このボタンをおすと、ゲーム画面にうつり、ビンゴを遊べるようにする。
ボタンの処理
public void actionPerformed(ActionEvent e) {
if(e.getSource() == mkCardBtn) {
numList.clear();
mkBingoCard();
}else if(e.getSource() == startBtn) {
insertGameFrame();
}
}
ひとつめの「ビンゴカード作成」ボタン(mkCardBtn)から説明。
public void mkBingoCard() { //ランダムな数字をカードに配置
while(numList.size() < 25) {
int num = random.nextInt(100);
if(numList.indexOf(num) == -1) {
numList.add(num);
}
}
for(int i=0; i<numList.size(); i++) {
String number =Integer.toString(numList.get(i));
bingoNumLabel[i].setText(number);
}
}
ビンゴカードの数字に必要な事は、
・ランダムであること
・一つのカード内で数字が被らないこと
のふたつ。
今回はwhile文でランダムでかぶらない25個の数をArrayListに入れて、その数字をカードのJLabelに設定するように書いてみた。
while文の条件式のところにあるnumList
がArrayListの変数名。
whileの中のif文ではindexOfメソッド
を使用している。これに渡した引数がArrayList内に存在すればその要素番号を、存在しなければー1を返すというもの。
今回は被らない数字にしたかったので、ー1が返ってきた場合のみその数字をnumListに格納するようにした。
ビンゴカード作成ボタンがでかすぎるのが少し気になるが、これはあとで調整する。
2つ目の「ゲーム開始」ボタン(startBtn)について
このボタンでinsertGameFrame()
が実行されるようにしてる。
これの中身はこちら。
public void insertGameFrame() {
gameFrame = new JFrame();
gameFrame.setBounds(100, 100, 600, 400);
gameFrame.setLocationRelativeTo(null);
gameFrame.setDefaultCloseOperation(EXIT_ON_CLOSE);
numLog = new JTextArea(5,10);
LineBorder black = new LineBorder(Color.black,2,true);
numLog.setBorder(black);
numLog.setEditable(false);
JPanel panel1 = new JPanel();
panel1.setLayout(new GridLayout(1,2));
panel1.add(BingoCardPanel);
panel1.add(numLog);
spinBtn = new JButton("Spin");
spinBtn.addActionListener(this);
Container c2 = gameFrame.getContentPane();
c2.add(panel1,BorderLayout.CENTER);
c2.add(spinBtn, BorderLayout.SOUTH);
gameFrame.setVisible(true);
}
まだ途中段階だけど、新しいフレームに画面が写って、前画面で作成したビンゴカードと、「抽選」ボタン、抽選ででた数字の履歴が表示されるJTextAreaを置いている。
実行結果はこんな感じ。
「ゲーム開始」ボタンをおすと、これが表示される。
終わり
今回の目標だったビンゴカード作成機能は作れたので、次はゲーム画面の完成をめざす。
感想としては、
繰り返し文のすばらしさを感じたね。先輩エンジニアたちにとっては当たり前のことかもしれないが、何回も同じことを書く必要がなくて数行で済むことが素晴らしすぎる。あと、被らないランダム数字の作り方は、ググったんじゃなくて、自分で考えてやってみたので、ちょっと達成感があった。もしかしたら、同じような方法がネットに載ってるのかもだけど、自分で考えて作れたことが嬉しかったね。ちょっと成長を感じたよ。
これが完成したら、同じようにビンゴを作った他の人のコードを見て、自分のと比べてみると面白そう。たくさん学べるものがあるに違いない。