※追記(2018/8/29)
より分かりやすい記事になるよう修正しました。
今回はJavaを使って、じゃんけんゲームを作る方法を紹介します。
eclipseがインストールされており、Javaの開発環境が整っている状態からのスタートとなります。
今回作るじゃんけんゲーム
では、まずは今回作成するじゃんけんゲームを紹介します。
今回はこのような物を作ります。
新しいプロジェクトの作成
まず、新しいプロジェクトを作成していきます。
「File」→「New」→「Java Project」の順番でクリックしていきます。
今回はProject nameを、JankenGameとし、Finishをクリックして、完了です。
クラスを作成する
それでは、クラスを作っていきましょう。
こちらも前回と同様に作っていきます。画面上部の「File」→「New」→「Class」と選択します。
すろと、この様な画面が表示されるので、画像の様に入力します。
packageには、ドメインを逆さまにしたものに、適当な名前をつけて使うことが多いと思います。
同じものがあってはいけないので、世界に一つのドメインを逆さまにするのが習慣のようです。
私の場合、本当は「original-game.com」というドメインですが、ハイフン(-)が使えないので、今回はアンダースコア(_)を使っています。
ドメインを持っていない方は、適当に。。。
Nameには「GameMain」と入力し、「Which method stubs would you like to create?」と訊かれている部分は、「public static void main(String[] args)」にチェックを入れます。
最後にFinishをクリックしてクラスが作成されます。
package com.original_game.janken; public class GameMain { public static void main(String[] args) { // TODO Auto-generated method stub } }
3行目のGameMainクラスの中に、public static void main(String[] args){}と書かれています。
これは、プログラムの一番最初に読まれるメソッドです。
先ほどクラスを作成した時、「public static void main(String[] args)」にチェックが入っていましたね。
このチェックを入れると、このメソッドを自動的に作ってくれるのです。
JFrameでウィンドウの表示
さて、ここからプログラミングらしくなってきましたね。
画像の様なウィンドウを表示します。今回はJFrameを使用します。
ウィンドウが表示されると、やっぱりゲーム感がでてきますね。
では、早速ソースを書いていきましょう。
package com.original_game.janken; import javax.swing.JFrame; public class GameMain { public static void main(String[] args) { // TODO Auto-generated method stub //ウィンドウの表示 JFrame frame = new JFrame("じゃんけんゲーム"); frame.setSize(640, 480); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setResizable(false); frame.setVisible(true); } }
上のコードで、ウィンドウを表示することが出来ます。
3行目は、JFrameを簡単に書く為の処理をしています。もしもこれが書かれていない場合、10行目で、JFrame frame = new JFrame("じゃんけんゲーム");
を、javax.swing.JFrame frame = new javax.swing.JFrame("じゃんけんゲーム");
と書く必要が生じます。
つまり、楽する為にimport文を書くという感じです。
ちなみに、3行目を書かなくても、先に10行目を書いてShift+command+Oで、自動的に記述することが可能です。
10行目では、JFrameクラスのインスタンスを作っています。
11行目では、作ったウィンドウのサイズを設定しています。ここは単純に640*480のサイズに設定しました。
12行目で、ウィンドウを画面の中心に設定します。
13行目で、ウィンドウの×をクリックして終了できる様にします。これがないと、×をクリックしても終了しないというド変態なウィンドウになってしまいます。
14行目で、ウィンドウのサイズを固定します。これがないと、ウィンドウのサイズが自由に変更できてしまうので、ゲーム全体のレイアウトが崩れたりします。
15行目で、見えなかったウィンドウを実際に表示します。
ウィンドウに三つのパネルを貼付ける。
今回のじゃんけんゲームでは、ウィンドウを三つに分割して作っていきたいと思っています。
今回は、一番上のパネルをヘッダー、真ん中のパネルをコンテンツ、一番下のパネルをフッターとします。
ヘッダーには今の状況を、コンテンツにはゲームのメインとなる部分を、フッターにはゲームを操作する部分を作っていこうと思います。
パネルの作り方
では、実際にパネルを作ってみましょう。まずはヘッダーのパネルから貼付けようと思います。
パネルを表示するプログラムを書いてみましょう。
パネル表示のプログラムは、import文以外setVisibleよりも前に書きます。
何故なら、setVisibleでウィンドウ内のパネルなどの表示も同時にされるからです。
package com.original_game.janken; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import javax.swing.JFrame; import javax.swing.JPanel; public class GameMain { public static void main(String[] args) { // TODO Auto-generated method stub //ウィンドウ設定 JFrame frame = new JFrame("じゃんけんゲーム"); frame.setSize(640, 480); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setResizable(false); //パネル表示 JPanel headerPanel = new JPanel(); headerPanel.setBackground(Color.BLACK); Dimension headerPanelDimension = new Dimension(640, 50); headerPanel.setPreferredSize(headerPanelDimension); frame.add(headerPanel,BorderLayout.NORTH); //ウィンドウ表示 frame.setVisible(true); } }
import文は22行目を書いた後にShift+command+Oで自動的に記述できます。
22行目では、JPanelクラスのインスタンスを生成しています。先ほどはJFrameでしたが、今度はJPanelのインスタンスです。
23行目で、そのパネル全体の色を指定します。今回は黒を指定しました。
24行目もインスタンスの生成ですが、今度はDimensionクラスのインスタンスを生成します。
Dimensionに、640と50を引数として指定してやると、横幅640、縦幅50に設定されます。
それを25行目の様にすると、横幅640、縦幅50のパネルというふうに設定されます。
そして、最後に26行目では、ここまでで設定したパネルを、ウィンドウ(frame)に追加するという感じです。
BorderLayout.NORTHで、パネルを追加する位置を指定しています。今回は一番上に表示したいので、NORTHとしました。
するとこのように、640*50のヘッダーパネルが作られます。
同様にほかのパネルも表示する。
では、同様にコンテンツパネル、フッタパネルも表示していこうと思います。
28〜40行目を追加します。
package com.original_game.janken; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import javax.swing.JFrame; import javax.swing.JPanel; public class GameMain { public static void main(String[] args) { // TODO Auto-generated method stub //ウィンドウ設定 JFrame frame = new JFrame("じゃんけんゲーム"); frame.setSize(640, 480); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setResizable(false); //パネル表示 JPanel headerPanel = new JPanel(); headerPanel.setBackground(Color.BLACK); Dimension HeaderPanelDimension = new Dimension(640, 50); headerPanel.setPreferredSize(HeaderPanelDimension); frame.add(headerPanel,BorderLayout.NORTH); //コンテンツパネル JPanel contentsPanel = new JPanel(); contentsPanel.setLayout(new BorderLayout()); contentsPanel.setBackground(Color.WHITE); frame.add(contentsPanel,BorderLayout.CENTER); //フッタパネル JPanel footerPanel = new JPanel(); footerPanel.setLayout(new BorderLayout()); footerPanel.setBackground(Color.BLACK); Dimension footerPanelDimension = new Dimension(640, 50); footerPanel.setPreferredSize(footerPanelDimension); frame.add(footerPanel,BorderLayout.SOUTH); //ウィンドウ表示 frame.setVisible(true); } }
ここでふと、似た様な記述が多くて無駄なことやってんじゃないの?と思ったアナタは鋭い!
正直言って、似た様な部分は一つにまとめることが出来ます。
メソッドを使い、繰り返し使う部分を何度も呼び出して使う。
ここで登場するのが、メソッドでございます。
メソッドとは、繰り返し使う部分を別の所に記述し、なんども呼び出して使うとこで、ソースを少なくすることが出来ます。
それではメソッドを使って、ソースをまとめてみましょう!
package com.original_game.janken; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import javax.swing.JFrame; import javax.swing.JPanel; public class GameMain { public static void main(String[] args) { // TODO Auto-generated method stub //ウィンドウ設定 JFrame frame = new JFrame("じゃんけんゲーム"); frame.setSize(640, 480); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setResizable(false); //ヘッダーパネル Dimension headerPanelDimension = new Dimension(640, 50); JPanel headerPanel = setPanel(Color.BLACK, headerPanelDimension); frame.add(headerPanel,BorderLayout.NORTH); //コンテンツパネル Dimension contentsPanelDimension = new Dimension(640, 380); JPanel contentsPanel = setPanel(Color.WHITE,contentsPanelDimension); frame.add(contentsPanel,BorderLayout.CENTER); //フッタパネル Dimension footerPanelDimension = new Dimension(640, 50); JPanel footerPanel = setPanel(Color.BLACK, footerPanelDimension); frame.add(footerPanel,BorderLayout.SOUTH); //ウィンドウ表示 frame.setVisible(true); } public static JPanel setPanel(Color color, Dimension PanelDimension) { JPanel panel = new JPanel(); panel.setPreferredSize(PanelDimension); panel.setLayout(new BorderLayout()); panel.setBackground(color); return(panel); } }
それぞれ重なった部分を、ソース一番下のパネルの設定の部分に移動させています。
ヘッダパネルであれば、23行目で、メソッドを呼び出しています。
()の中に書かれたものは引数といい、ここに書いた値を、39行目での()の中で宣言した変数が受け取ります。
そしてこの値を元に、39行目のメソッド内でパネルの設定をします。
最後にそれをreturn文で23行目に返し、headerPanelに入ります。
これを戻り値と言います。
パネル内に文字を表示する
パネル内に文字を表示しようと思うのですが、文字を表示するだけでも、色々な設定があります。
何も考えずに文字を表示しようとした場合
と、言う感じで作りたいのですが、ヘッダーパネルに表示するだけでも、以下のような記述が必要になり、かなり長くなってしまいます。
JLabel headerLabel = new JLabel("「さあ、じゃんけんで勝負だ!」"); headerLabel.setForeground(Color.WHITE); Font headerLabelFont = new Font("MS ゴシック",Font.PLAIN,24); headerLabel.setFont(headerLabelFont); headerLabel.setHorizontalAlignment(JLabel.CENTER); headerLabel.setVerticalAlignment(JLabel.CENTER); headerPanel.add(headerLabel);
とりあえず、説明しますと。。。
1行目で、JLabelクラスのインスタンスを生成し、引数を「さあ、じゃんけんで勝負だ!」という文字列(String型)にします。
2行目で、文字の色を指定し、
3行目で、Fontクラスのインスタンスを生成。書体やフォントサイズを引数とし、四行目のsetFontで、それを設定します。
5行目で水平位置、6行目で垂直位置を中央に指定し、
7行目で設定したラベルをヘッダパネルに追加するという感じです。
これをコンテンツパネルでも同じことを書くのは無駄な気がするし、かといってパネル設定のメソッド、setPanelの中に入れるのは、文字列や色、フォントサイズは部分部分で変えたい時に、引数の数が多すぎて見る人が分かりにくいです。
フォント設定のメソッドを作る
という訳で、もう一つフォントの設定メソッドを作るという形で、プログラム全体を変更してみたいと思います。
こんな感じになります。
package com.original_game.janken; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; public class GameMain { public static void main(String[] args) { // TODO Auto-generated method stub //ウィンドウ設定 JFrame frame = new JFrame("じゃんけんゲーム"); frame.setSize(640, 480); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setResizable(false); //ヘッダーパネル Dimension headerPanelDimension = new Dimension(640, 50); JPanel headerPanel = setPanel(Color.BLACK, headerPanelDimension); JLabel headerLabel = new JLabel("「さあ、じゃんけんで勝負だ!」"); headerLabel = setFont(Color.WHITE,headerLabel,24); headerPanel.add(headerLabel); frame.add(headerPanel,BorderLayout.NORTH); //コンテンツパネル Dimension contentsPanelDimension = new Dimension(640, 380); JPanel contentsPanel = setPanel(Color.WHITE,contentsPanelDimension); JLabel contentsLabel = new JLabel("じゃんけん・・・"); contentsLabel = setFont(Color.BLACK,contentsLabel,54); contentsPanel.add(contentsLabel); frame.add(contentsPanel,BorderLayout.CENTER); //フッタパネル Dimension footerPanelDimension = new Dimension(640, 50); JPanel footerPanel = setPanel(Color.BLACK,footerPanelDimension); frame.add(footerPanel,BorderLayout.SOUTH); //ウィンドウ表示 frame.setVisible(true); } public static JPanel setPanel(Color color, Dimension PanelDimension) { JPanel panel = new JPanel(); panel.setPreferredSize(PanelDimension); panel.setLayout(new BorderLayout()); panel.setBackground(color); return(panel); } public static JLabel setFont(Color clr,JLabel label,int strSize) { label.setForeground(clr); Font labelFont = new Font("MS ゴシック",Font.PLAIN,strSize); label.setFont(labelFont); label.setHorizontalAlignment(JLabel.CENTER); label.setVerticalAlignment(JLabel.CENTER); return(label); } }
今までの流れが理解できている人は、今回のフォントの設定の話も理解できていると思います。
全部、上で説明した話です。よくわからない方は、上をもう一度読み返せば理解できると思います。
ボタンを作る
後ボタンさえあれば、形にはなると。
早くボタンを作りたい!という訳で、ボタンを作ってみます。
この様な状態になります。まだ、クリックしても何も起きませんが。
それでは、ボタンを表示するプログラムを書いてみますが、恒例の無駄の多いプログラムから。
ボタンを表示するには、以下のソースようなが必要です。
int buttonSizeX = (640 - 20)/3; JButton btnGu = new JButton("グー"); btnGu.setPreferredSize(new Dimension(buttonSizeX, 50)); btnGu.setFont(new Font("MS ゴシック",Font.PLAIN,24)); footerPanel.add(btnGu, BorderLayout.WEST); JButton btnChoki = new JButton("チョキ"); btnChoki.setPreferredSize(new Dimension(buttonSizeX, 50)); btnChoki.setFont(new Font("MS ゴシック",Font.PLAIN,24)); footerPanel.add(btnChoki, BorderLayout.CENTER); JButton btnPa = new JButton("パー"); btnPa.setPreferredSize(new Dimension(buttonSizeX, 50)); btnPa.setFont(new Font("MS ゴシック",Font.PLAIN,24)); footerPanel.add(btnPa, BorderLayout.EAST); frame.add(footerPanel,BorderLayout.SOUTH);
ちょっと繰り返しの多いプログラムですね。
とりあえず、1行目が何なのか意味が分からないと思うのですが、ボタンを横並びに三つ表示したいので、ウィンドウの横幅から適当に20引いた値を三で割ったもの、つまりボタン一つの横幅を表しています。
ではこのソースをsetButtonというメソッドを作って、繰り返しをまとめます。
package com.original_game.janken; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; public class GameMain { public static void main(String[] args) { // TODO Auto-generated method stub //ウィンドウ設定 JFrame frame = new JFrame("じゃんけんゲーム"); frame.setSize(640, 480); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setResizable(false); //ヘッダーパネル Dimension headerPanelDimension = new Dimension(640, 50); JPanel headerPanel = setPanel(Color.BLACK, headerPanelDimension); JLabel headerLabel = new JLabel("「さあ、じゃんけんで勝負だ!」"); headerLabel = setFont(Color.WHITE,headerLabel,24); headerPanel.add(headerLabel); frame.add(headerPanel,BorderLayout.NORTH); //コンテンツパネル Dimension contentsPanelDimension = new Dimension(640, 380); JPanel contentsPanel = setPanel(Color.WHITE,contentsPanelDimension); JLabel contentsLabel = new JLabel("じゃんけん・・・"); contentsLabel = setFont(Color.BLACK,contentsLabel,54); contentsPanel.add(contentsLabel); frame.add(contentsPanel,BorderLayout.CENTER); //フッタパネル Dimension footerPanelDimension = new Dimension(640, 50); JPanel footerPanel = setPanel(Color.BLACK,footerPanelDimension); //ボタンを表示 JButton btnGu = new JButton("グー"); btnGu = setButton(btnGu); footerPanel.add(btnGu, BorderLayout.WEST); JButton btnChoki = new JButton("チョキ"); btnChoki = setButton(btnChoki); footerPanel.add(btnChoki, BorderLayout.CENTER); JButton btnPa = new JButton("パー"); btnPa = setButton(btnPa); footerPanel.add(btnPa, BorderLayout.EAST); frame.add(footerPanel,BorderLayout.SOUTH); //ウィンドウ表示 frame.setVisible(true); } public static JPanel setPanel(Color color, Dimension PanelDimension) { JPanel panel = new JPanel(); panel.setPreferredSize(PanelDimension); panel.setLayout(new BorderLayout()); panel.setBackground(color); return(panel); } public static JLabel setFont(Color clr,JLabel label,int strSize) { label.setForeground(clr); Font labelFont = new Font("MS ゴシック",Font.PLAIN,strSize); label.setFont(labelFont); label.setHorizontalAlignment(JLabel.CENTER); label.setVerticalAlignment(JLabel.CENTER); return(label); } public static JButton setButton(JButton button) { int buttonSizeX = (640 - 20)/3; Dimension buttonDimesion = new Dimension(buttonSizeX, 50); button.setPreferredSize(buttonDimesion); Font buttonFont = new Font("MS ゴシック",Font.PLAIN,24); button.setFont(buttonFont); return(button); } }
やっていることは、インスタンスを生成して……と、今までとほぼ変わりないんで省きます。
そろそろソースが長くなって読みにくいと思っている人が殆どでしょう。
そこでクラスというものを使ってみます。
新しくクラスを作り、ソースを分かりやすくする
クラスって、学校とかのクラスか?
と、思ってしまいますが、まぁ、実際そんな感じでしょう。
しかし、Javaでのクラスは、学校のクラスの様にテキトーに1組とか2組とか分かれている訳ではありません。
クラス分けは、ちゃんとその人の役割に合ったクラスでないといけません。
クラスについてしっかりと知りたい方は、こちらの記事をご覧ください。
Javaのクラスとメソッドの違いとは?ゲーム風に解説。
説明するより、実際にクラス分けを行ってみましょう。
とりあえず、パネルを生成する関係のものを別のクラスに移動させてみたいと思います。
「File」→「New」→「Class」と選択し、クラスを作成します。
また、下の方のチェックは何も入れません。
先ほどは、public static void main(String[] args)にチェックを入れましたが、今回も入れてしまうと一番最初にどちらを呼び出していいのか分からなくなってしまいますね。
では、Finishでクラスを作成します。
すると以下のようなソースが作られます。
package com.original_game.janken; public class Panel { }
パネル関係のものをクラス内に入れる
それでは、この中に、パネル関係のものを入れていきます。
しかし、ただ入れるだけでは動きません。どこのクラスにあるのかなども指定してやる必要があります。
パネル関係とは言いましたが、今回はちゃんと実行されるかどうかの確認も行いたい為、フォントの設定やボタンの設定などのメソッドもとりあえずこちらに移動させます。
では、ソースコードを見ていきましょう。
GameMain.java
package com.original_game.janken; import javax.swing.JFrame; public class GameMain { public static void main(String[] args) { // TODO Auto-generated method stub //ウィンドウ設定 JFrame frame = new JFrame("じゃんけんゲーム"); frame.setSize(640, 480); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setResizable(false); Panel.createPanel(frame); //ウィンドウ表示 frame.setVisible(true); } }
まずGameMain.javaは、フレーム(ウィンドウ)の設定と表示のソースのみにします。
そして15行目でPanel.javaに書いたPanelクラスのcreatePanelメソッドを呼び出します。
Panel.java
package com.original_game.janken; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; public class Panel { public static void createPanel(JFrame frame) { //ヘッダーパネル Dimension headerPanelDimension = new Dimension(640, 50); JPanel headerPanel = setPanel(Color.BLACK, headerPanelDimension); JLabel headerLabel = new JLabel("「さあ、じゃんけんで勝負だ!」"); headerLabel = setFont(Color.WHITE,headerLabel,24); headerPanel.add(headerLabel); frame.add(headerPanel,BorderLayout.NORTH); //コンテンツパネル Dimension contentsPanelDimension = new Dimension(640, 380); JPanel contentsPanel = setPanel(Color.WHITE,contentsPanelDimension); JLabel contentsLabel = new JLabel("じゃんけん・・・"); contentsLabel = setFont(Color.BLACK,contentsLabel,54); contentsPanel.add(contentsLabel); frame.add(contentsPanel,BorderLayout.CENTER); //フッタパネル Dimension footerPanelDimension = new Dimension(640, 50); JPanel footerPanel = setPanel(Color.BLACK,footerPanelDimension); //ボタンを表示 JButton btnGu = new JButton("グー"); btnGu = setButton(btnGu); footerPanel.add(btnGu, BorderLayout.WEST); JButton btnChoki = new JButton("チョキ"); btnChoki = setButton(btnChoki); footerPanel.add(btnChoki, BorderLayout.CENTER); JButton btnPa = new JButton("パー"); btnPa = setButton(btnPa); footerPanel.add(btnPa, BorderLayout.EAST); frame.add(footerPanel,BorderLayout.SOUTH); } public static JPanel setPanel(Color color, Dimension PanelDimension) { JPanel panel = new JPanel(); panel.setPreferredSize(PanelDimension); panel.setLayout(new BorderLayout()); panel.setBackground(color); return(panel); } public static JLabel setFont(Color clr,JLabel label,int strSize) { label.setForeground(clr); Font labelFont = new Font("MS ゴシック",Font.PLAIN,strSize); label.setFont(labelFont); label.setHorizontalAlignment(JLabel.CENTER); label.setVerticalAlignment(JLabel.CENTER); return(label); } public static JButton setButton(JButton button) { int buttonSizeX = (640 - 20)/3; Dimension buttonDimesion = new Dimension(buttonSizeX, 50); button.setPreferredSize(buttonDimesion); Font buttonFont = new Font("MS ゴシック",Font.PLAIN,24); button.setFont(buttonFont); return(button); } }
と、まだまだPanel.javaの方が見にくいので、更にクラスを作っていきたいと思います。
Playerクラスを作る
では、ボタンなど、プレイヤーが操作するものを集めたクラスを作成します。
「File」→「New」→「Class」と選択します。
今回はクラス名(Name)をPlayerとし、Finishをクリックします。
それでは、ここにプレイヤーが操作を行う関連のものを移動させていきます。
Playerクラスに移動させる
それでは、プレイヤーの操作に関連する部分を、Playerメソッドに移動させていきます。
GameMain.javaは特に変わりはありません。
Panel.java
package com.original_game.janken; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; public class Panel { public static void createPanel(JFrame frame) { //ヘッダーパネル Dimension headerPanelDimension = new Dimension(640, 50); JPanel headerPanel = setPanel(Color.BLACK, headerPanelDimension); JLabel headerLabel = new JLabel("「さあ、じゃんけんで勝負だ!」"); headerLabel = setFont(Color.WHITE,headerLabel,24); headerPanel.add(headerLabel); frame.add(headerPanel,BorderLayout.NORTH); //コンテンツパネル Dimension contentsPanelDimension = new Dimension(640, 380); JPanel contentsPanel = setPanel(Color.WHITE,contentsPanelDimension); JLabel contentsLabel = new JLabel("じゃんけん・・・"); contentsLabel = setFont(Color.BLACK,contentsLabel,54); contentsPanel.add(contentsLabel); frame.add(contentsPanel,BorderLayout.CENTER); //フッタパネル Dimension footerPanelDimension = new Dimension(640, 50); JPanel footerPanel = setPanel(Color.BLACK,footerPanelDimension); Player.createButton(footerPanel); frame.add(footerPanel,BorderLayout.SOUTH); } public static JPanel setPanel(Color color, Dimension PanelDimension) { JPanel panel = new JPanel(); panel.setPreferredSize(PanelDimension); panel.setLayout(new BorderLayout()); panel.setBackground(color); return(panel); } public static JLabel setFont(Color clr,JLabel label,int strSize) { label.setForeground(clr); Font labelFont = new Font("MS ゴシック",Font.PLAIN,strSize); label.setFont(labelFont); label.setHorizontalAlignment(JLabel.CENTER); label.setVerticalAlignment(JLabel.CENTER); return(label); } }
Player.java
package com.original_game.janken; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Font; import javax.swing.JButton; import javax.swing.JPanel; public class Player { public static void createButton(JPanel footerPanel) { //ボタンを表示 JButton btnGu = new JButton("グー"); btnGu = setButton(btnGu); footerPanel.add(btnGu, BorderLayout.WEST); JButton btnChoki = new JButton("チョキ"); btnChoki = setButton(btnChoki); footerPanel.add(btnChoki, BorderLayout.CENTER); JButton btnPa = new JButton("パー"); btnPa = setButton(btnPa); footerPanel.add(btnPa, BorderLayout.EAST); } public static JButton setButton(JButton button) { int buttonSizeX = (640 - 20)/3; Dimension buttonDimesion = new Dimension(buttonSizeX, 50); button.setPreferredSize(buttonDimesion); Font buttonFont = new Font("MS ゴシック",Font.PLAIN,24); button.setFont(buttonFont); return(button); } }
なんか、フォントの設定がPanelクラスに入ってるというのが少し気に入らないけど、まあいいや。
分割されたことで、ソースが見やすくなったのではないでしょうか。
プレイヤーの操作を反映させる。
今の状態では、形だけで、全くゲームにはなっていません。
ボタンを押しても反応がない。。。押しても引いても揉んでも、反応がないというのは寂しいです。
やっぱり、相手も何か出してくれなきゃ……。しかし、まずはプレイヤーが出したものと同じものを出すプログラムを作っていきたいと思います。
今回は『反応する!!』というだけ。
ボタンを押すと反応するプログラム
という訳で、ボタンを押すことで反応する様に作っていきたいと思います。
今回はGameMain.javaの変更はありません。
Panel.java
package com.original_game.janken; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; public class Panel { public static JLabel headerLabel; public static JLabel contentsLabel; public static void createPanel(JFrame frame) { //ヘッダーパネル Dimension headerPanelDimension = new Dimension(640, 50); JPanel headerPanel = setPanel(Color.BLACK, headerPanelDimension); headerLabel = new JLabel("「さあ、じゃんけんで勝負だ!」"); headerLabel = setFont(Color.WHITE,headerLabel,24); headerPanel.add(headerLabel); frame.add(headerPanel,BorderLayout.NORTH); //コンテンツパネル Dimension contentsPanelDimension = new Dimension(640, 380); JPanel contentsPanel = setPanel(Color.WHITE,contentsPanelDimension); contentsLabel = new JLabel("じゃんけん・・・"); contentsLabel = setFont(Color.BLACK,contentsLabel,54); contentsPanel.add(contentsLabel); frame.add(contentsPanel,BorderLayout.CENTER); //フッタパネル Dimension footerPanelDimension = new Dimension(640, 50); JPanel footerPanel = setPanel(Color.BLACK,footerPanelDimension); Player.createButton(footerPanel); frame.add(footerPanel,BorderLayout.SOUTH); } public static JPanel setPanel(Color color, Dimension PanelDimension) { JPanel panel = new JPanel(); panel.setPreferredSize(PanelDimension); panel.setLayout(new BorderLayout()); panel.setBackground(color); return(panel); } public static JLabel setFont(Color clr,JLabel label,int strSize) { label.setForeground(clr); Font labelFont = new Font("MS ゴシック",Font.PLAIN,strSize); label.setFont(labelFont); label.setHorizontalAlignment(JLabel.CENTER); label.setVerticalAlignment(JLabel.CENTER); return(label); } }
まず、Panel.javaの方ですが、二行目と三行目でPlayer.javaから、headerLabelとcontentsLabelを使いたいので、この二つをメソッドの外で宣言しました。なので、メソッド内の宣言は外しています。
つづいて、Player.javaの方です。
Player.java
package com.original_game.janken; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JPanel; public class Player implements ActionListener { public static void createButton(JPanel footerPanel) { //ボタンを表示 JButton btnGu = new JButton("グー"); btnGu = setButton(btnGu); footerPanel.add(btnGu, BorderLayout.WEST); JButton btnChoki = new JButton("チョキ"); btnChoki = setButton(btnChoki); footerPanel.add(btnChoki, BorderLayout.CENTER); JButton btnPa = new JButton("パー"); btnPa = setButton(btnPa); footerPanel.add(btnPa, BorderLayout.EAST); } public static JButton setButton(JButton button) { int buttonSizeX = (640 - 20)/3; Dimension buttonDimesion = new Dimension(buttonSizeX, 50); button.setPreferredSize(buttonDimesion); Font buttonFont = new Font("MS ゴシック",Font.PLAIN,24); button.setFont(buttonFont); Player player = new Player(); button.addActionListener(player); return(button); } public void actionPerformed(ActionEvent e) { String command = e.getActionCommand(); int playerHand = 0; if (command.equals("グー")) playerHand = 1; else if (command.equals("チョキ")) playerHand = 2; else if (command.equals("パー")) playerHand = 3; if (playerHand == 1) Panel.contentsLabel.setText("グー"); else if (playerHand == 2) Panel.contentsLabel.setText("チョキ"); else if (playerHand == 3) Panel.contentsLabel.setText("パー"); } }
12行目ではActionListenerというインターフェースを実装しています。
27行目〜38行目のsetButtonメソッドの終わりの方の2行(34、35行目)で、ボタンが押された時のメソッドactionPerformedを呼び出しています。
そして今回は、playerHandの値で、じゃんけんの勝敗を計算していくつもなので、グーが1、チョキが2、パーが3という感じでいきます。
相手が何を出すかをランダムで決定する
では、コンピュータ側が出す手をランダムで決定できるようにしていきます。
クラス名は「Computer」とします。
下の四つのチェックはいれません。
Computer.java
package com.original_game.janken; import java.util.Random; public class Computer { public static int decidesComputerHand() { Random random = new Random(); int rnd = random.nextInt(3)+1; if (rnd == 1) Panel.contentsLabel.setText("グー"); else if (rnd == 2) Panel.contentsLabel.setText("チョキ"); else if (rnd == 3) Panel.contentsLabel.setText("パー"); return (rnd); } }
7〜8行目でランダムな数値を生成します。上の様に書くと、1〜3までのランダムな数値が、変数rndに代入されます。
ゲームの勝敗
ではゲームの勝敗をつくっていきたいと思います。
画像のように、ボタンを押すと相手が出した手と勝敗が表示されます。
さらに括弧の中にポイントも表示させました。
勝った場合は1ポイント、あいこの場合はそのまま、負けた場合0に戻るというふうにします。
ここではとりあえず動かす為に、Playerクラスに色々と書き込んでみますが、Playerに関係のないプログラムも書き込んでしまうので、後で整理したいと思います。
Player.java
package com.original_game.janken; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JPanel; public class Player implements ActionListener { private static int point = 0; public static void createButton(JPanel footerPanel) { //ボタンを表示 JButton btnGu = new JButton("グー"); btnGu = setButton(btnGu); footerPanel.add(btnGu, BorderLayout.WEST); JButton btnChoki = new JButton("チョキ"); btnChoki = setButton(btnChoki); footerPanel.add(btnChoki, BorderLayout.CENTER); JButton btnPa = new JButton("パー"); btnPa = setButton(btnPa); footerPanel.add(btnPa, BorderLayout.EAST); } public static JButton setButton(JButton button) { int buttonSizeX = (640 - 20)/3; Dimension buttonDimesion = new Dimension(buttonSizeX, 50); button.setPreferredSize(buttonDimesion); Font buttonFont = new Font("MS ゴシック",Font.PLAIN,24); button.setFont(buttonFont); Player player = new Player(); button.addActionListener(player); return(button); } public void actionPerformed(ActionEvent e) { String command = e.getActionCommand(); int playerHand = 0; if (command.equals("グー")) playerHand = 1; else if (command.equals("チョキ")) playerHand = 2; else if (command.equals("パー")) playerHand = 3; int computerHand = Computer.decidesComputerHand(); int playerHandTemp = playerHand; playerHandTemp++; if (playerHand == computerHand) { Panel.headerLabel.setText("あいこかよ!(" + point + ")"); } else if ((playerHand == 3 && computerHand == 1)||(playerHandTemp == computerHand)) { point+=1; Panel.headerLabel.setText("お前の勝ちかよ!(" + point + ")"); } else { point=0; Panel.headerLabel.setText("お前の負けかよ!(" + point + ")"); } } }
13行目にprivate static int point = 0;という記述が増えました。
これはじゃんけんで勝ったポイントを表しています。
このじゃんけんゲームのルールは、勝ったらプラス1点、あいこならばプラス0点、負けたら0点に戻るです。
これで、最高何点までいけるかという遊びを、永遠に繰り返すゲームです。楽しい!!(全く面白く無い。
actionPerformedメソッドの終わりの方(52〜62行目)では、じゃんけんの勝敗を決定し、表示しています。
勝敗を決める為のクラスを作成する
じゃんけんの勝敗を決める為のクラスを作成し、ソースを整理していきたいと思います。
「File」→「New」→「Class」と選択します。
VictoryOrDefeat.javaには、先ほどPlayer.javaに書いたソースをカット&ペーストしながら作ります。
VictoryOrDefeat.java
package com.original_game.janken; public class VictoryOrDefeat { private static int point = 0; public static final void decisionVictoryOrDefeat(int computerHand,int playerHand) { int playerHandTemp = playerHand; playerHandTemp++; if (playerHand == computerHand) { Panel.headerLabel.setText("あいこかよ!(" + point + ")"); } else if ((playerHand == 3 && computerHand == 1)||(playerHandTemp == computerHand)) { point+=1; Panel.headerLabel.setText("お前の勝ちかよ!(" + point + ")"); } else { point=0; Panel.headerLabel.setText("お前の負けかよ!(" + point + ")"); } } }
4行目には、Player.javaの13行目に書いていたポイントの変数の宣言をカット&ペーストします。
5行目には、decisionVictoryOrDefeatというメソッドを作り、その中にPlayer.javaの49〜62行目をカット&ペーストします。
さらにPlayer.javaは以下のようになります。
Player.java
package com.original_game.janken; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JPanel; public class Player implements ActionListener { public static void createButton(JPanel footerPanel) { //ボタンを表示 JButton btnGu = new JButton("グー"); btnGu = setButton(btnGu); footerPanel.add(btnGu, BorderLayout.WEST); JButton btnChoki = new JButton("チョキ"); btnChoki = setButton(btnChoki); footerPanel.add(btnChoki, BorderLayout.CENTER); JButton btnPa = new JButton("パー"); btnPa = setButton(btnPa); footerPanel.add(btnPa, BorderLayout.EAST); } public static JButton setButton(JButton button) { int buttonSizeX = (640 - 20)/3; Dimension buttonDimesion = new Dimension(buttonSizeX, 50); button.setPreferredSize(buttonDimesion); Font buttonFont = new Font("MS ゴシック",Font.PLAIN,24); button.setFont(buttonFont); Player player = new Player(); button.addActionListener(player); return(button); } public void actionPerformed(ActionEvent e) { String command = e.getActionCommand(); int playerHand = 0; if (command.equals("グー")) playerHand = 1; else if (command.equals("チョキ")) playerHand = 2; else if (command.equals("パー")) playerHand = 3; int computerHand = Computer.decidesComputerHand(); VictoryOrDefeat.decisionVictoryOrDefeat(computerHand, playerHand); } }
完成した全体のコード
では最後に、完成した全体のコードを載せておきます。
もし最終的にうまく動作しない場合は、こちらを見て参考にしてください。
GameMain.java
package com.original_game.janken; import javax.swing.JFrame; public class GameMain { public static void main(String[] args) { // TODO Auto-generated method stub //ウィンドウ設定 JFrame frame = new JFrame("じゃんけんゲーム"); frame.setSize(640, 480); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setResizable(false); Panel.createPanel(frame); //ウィンドウ表示 frame.setVisible(true); } }
Panel.java
package com.original_game.janken; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; public class Panel { public static JLabel headerLabel; public static JLabel contentsLabel; public static void createPanel(JFrame frame) { //ヘッダーパネル Dimension headerPanelDimension = new Dimension(640, 50); JPanel headerPanel = setPanel(Color.BLACK, headerPanelDimension); headerLabel = new JLabel("「さあ、じゃんけんで勝負だ!」"); headerLabel = setFont(Color.WHITE,headerLabel,24); headerPanel.add(headerLabel); frame.add(headerPanel,BorderLayout.NORTH); //コンテンツパネル Dimension contentsPanelDimension = new Dimension(640, 380); JPanel contentsPanel = setPanel(Color.WHITE,contentsPanelDimension); contentsLabel = new JLabel("じゃんけん・・・"); contentsLabel = setFont(Color.BLACK,contentsLabel,54); contentsPanel.add(contentsLabel); frame.add(contentsPanel,BorderLayout.CENTER); //フッタパネル Dimension footerPanelDimension = new Dimension(640, 50); JPanel footerPanel = setPanel(Color.BLACK,footerPanelDimension); Player.createButton(footerPanel); frame.add(footerPanel,BorderLayout.SOUTH); } public static JPanel setPanel(Color color, Dimension PanelDimension) { JPanel panel = new JPanel(); panel.setPreferredSize(PanelDimension); panel.setLayout(new BorderLayout()); panel.setBackground(color); return(panel); } public static JLabel setFont(Color clr,JLabel label,int strSize) { label.setForeground(clr); Font labelFont = new Font("MS ゴシック",Font.PLAIN,strSize); label.setFont(labelFont); label.setHorizontalAlignment(JLabel.CENTER); label.setVerticalAlignment(JLabel.CENTER); return(label); } }
Player.java
package com.original_game.janken; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JPanel; public class Player implements ActionListener { public static void createButton(JPanel footerPanel) { //ボタンを表示 JButton btnGu = new JButton("グー"); btnGu = setButton(btnGu); footerPanel.add(btnGu, BorderLayout.WEST); JButton btnChoki = new JButton("チョキ"); btnChoki = setButton(btnChoki); footerPanel.add(btnChoki, BorderLayout.CENTER); JButton btnPa = new JButton("パー"); btnPa = setButton(btnPa); footerPanel.add(btnPa, BorderLayout.EAST); } public static JButton setButton(JButton button) { int buttonSizeX = (640 - 20)/3; Dimension buttonDimesion = new Dimension(buttonSizeX, 50); button.setPreferredSize(buttonDimesion); Font buttonFont = new Font("MS ゴシック",Font.PLAIN,24); button.setFont(buttonFont); Player player = new Player(); button.addActionListener(player); return(button); } public void actionPerformed(ActionEvent e) { String command = e.getActionCommand(); int playerHand = 0; if (command.equals("グー")) playerHand = 1; else if (command.equals("チョキ")) playerHand = 2; else if (command.equals("パー")) playerHand = 3; int computerHand = Computer.decidesComputerHand(); VictoryOrDefeat.decisionVictoryOrDefeat(computerHand, playerHand); } }
Computer.java
package com.original_game.janken; import java.util.Random; public class Computer { public static int decidesComputerHand() { Random random = new Random(); int rnd = random.nextInt(3)+1; if (rnd == 1) Panel.contentsLabel.setText("グー"); else if (rnd == 2) Panel.contentsLabel.setText("チョキ"); else if (rnd == 3) Panel.contentsLabel.setText("パー"); return (rnd); } }
VictoryOrDefeat.java
package com.original_game.janken; public class VictoryOrDefeat { private static int point = 0; public static final void decisionVictoryOrDefeat(int computerHand,int playerHand) { int playerHandTemp = playerHand; playerHandTemp++; if (playerHand == computerHand) { Panel.headerLabel.setText("あいこかよ!(" + point + ")"); } else if ((playerHand == 3 && computerHand == 1)||(playerHandTemp == computerHand)) { point+=1; Panel.headerLabel.setText("お前の勝ちかよ!(" + point + ")"); } else { point=0; Panel.headerLabel.setText("お前の負けかよ!(" + point + ")"); } } }
まとめ
納得のいくじゃんけんゲームは出来ましたか?
これを元に、もっと様々な機能を加えていくことで、より面白いじゃんけんゲームが作れると思います。
自分だけのオリジナルのじゃんけんゲームを作ってみて下さい。
そんなわけで、Eclipseを使ったJavaでのじゃんけんゲームプログラムの作り方でした。
こんにちは!!
じゃんけんゲームの書き方についてとても参考になりました。
勝ち負けあいこの時に、それぞれ違う音がなるようにしたいのですが、苦戦しています。。。
良ければプログラムを教えていただけないでしょうか?