スライド タイトルなし

GUI部品とイベント処理の例
マインスィーパもどきの作成
倉敷芸術科学大学 産業科学技術学部
梶浦文夫
ゲームの説明
◎いくつかの桝目の中
に爆弾が隠れている
◎爆弾の桝目を開けると
負け
◎爆弾のない桝目を
全部開けると勝ち
◎ヒントとして周囲の爆弾
の個数を表示
ゲームの説明2
周囲の爆弾の
0
個数とは?
2
隣接する8個の
桝目のなかにあ
る爆弾の数
3
1
実行
画面
8×8の
舛目
リプレイボタン
終
了
ボ
タ
ン
実行中
の画面
桝目を開ける
と、周りの爆弾
の個数が表示
される
ここを開けたとき
実行中
の画面
爆弾の桝目を
開けてしまって
負けたところ
ゲーム盤の作成
Panel
Frame
BorderLayout
GridLayout
Button
終了ボタン
Panel
リプレイボタン
Panel
GridLayout
Frame
BorderLayout
碁盤目の作成
Panel p1;
//全体のレイアウトはボーダーレイアウト
setLayout(new BorderLayout());
//盤のためのパネル
p1 = new Panel();
p1.setLayout(new GridLayout(SIZE, SIZE));
Panel
GridLayout
碁盤目の作成
Button
//パネルp1上に盤の作成
for(int i = 0;i < SIZE;i++)
8行8列に
for(int j = 0;j < SIZE;j++)
{
ボタン作成
b[i][j] = new Button(" ");
b[i][j].addActionListener(this);
p1.add(b[i][j]);
リスナ設定
}
Panelに貼り付け
//盤を中央に貼りつけ
add(p1, BorderLayout.CENTER);
リプレイボタン、終了ボタン
Panel
リプレイボタン
Panel p2; //パネル
Button b_end; //終了ボタン
Button b_cont; //継続ボタン
//終了ボタン貼りつけ
b_end = new Button("End");
b_end.addActionListener(this);
//p2の貼りつけ
p2.add(b_end);
終了ボタン
リプレイボタン省略
add(p2, BorderLayout.SOUTH);//下側に貼りつけ
盤の状態を保持する変数(配列)
boolean bombset[8][8]; //爆弾がセットされているか?
○ 桝目の個数分の要素を持つ配列(64個)
○ 要素の型はboolean型
○ trueなら爆弾あり!
falseなら爆弾なし
boolean opened[8][8]; //桝目がオープンされているか?
○ 桝目の個数分の要素を持つ配列(64個)
○ 要素の型はboolean型
○ trueなら開かれている!
falseならまだ!
盤の初期化1
64個の要素
全部を設定
void init_board()
{
//桝目の状態初期化
for(int i = 0;i < SIZE;i++)
for(int j = 0;j < SIZE;j++)
{
opened[i][j] = false;
bombset[I][j] = false;
b[i][j].setLabel(" ");
}
ボタンの文字は空白
オープンさ
れていない
爆弾はセッ
トされてい
ない
盤の初期化2
爆弾の個数分繰り返し
//爆弾の位置設定
for(int i = 0;i < NOB;i++)
同じ位置にならないように
while(true)
{
0~7の
int x = (int)(Math.random() * 8.0);
乱数
int y = (int)(Math.random() * 8.0);
if(!bombset[x][y])
まだ爆弾がセッ
{
トされていなけ
bombset[x][y] = true;
れば
break;
}
爆弾をセット
}
0.0 <= Math.random() < 1.0 の乱数
イベント処理1
public void actionPerformed(ActionEvent ae)
{
//終了ボタンの場合
if(ae.getSource() == b_end)
System.exit(0);
//継続ボタンの場合
else if(ae.getSource() == b_cont)
init_board();
:
イベント処理2
64個のボタンの
うちどのボタンが
押されたのか調
べる
int ii = -1;
int jj = -1;
for(int i = 0;i < SIZE;i++)
for(int j = 0;j < SIZE;j++)
if(ae.getSource() == b[i][j])
{
ii = i;
押されたのはii行jj列の
jj = j;
ボタン
}
イベント処理3
if(ii >= 0 && !opened[ii][jj])
開かれてなかったら
{
//爆発!
爆弾があったら
if(bombset[ii][jj])
disp_bomb(); //爆弾の位置表示
else //ラッキー
爆弾がなかったら
{
//周囲の爆弾の個数表示
b[ii][jj].setLabel(" " + count_bomb(jj, ii));
//状態変数openedをtrueに
opened[ii][jj] = true;
}
}
隣接する8個の桝目
bombset[y-1][x-1]
bombset[y-1][x]
bombset[y][x-1]
bombset[y+1][x-1]
bombset[y-1][x+1]
bombset[y][x+1]
bombset[y+1][x]
bombset[y+1][x+1]
周りの爆弾の個数
//y行目、x桁目の周りの爆弾の個数を調べる
//周囲の爆弾の個数
int count = 0;
if(y > 0 && x > 0 && bombset[y - 1][x - 1]) count++; //左上チェック
if(y > 0 && bombset[y - 1][x]) count++;
//上チェック
if(y > 0 && x < 7 && bombset[y - 1][x + 1]) count++; //右上チェック
if(x > 0 && bombset[y][x - 1]) count++;
//左チェック
if(y < 7 && x > 0 && bombset[y + 1][x - 1]) count++; //左下チェック
if(y < 7 && bombset[y + 1][x]) count++;
//下チェック
if(y < 7 && x < 7 && bombset[y + 1][x + 1]) count++; //右下チェック
if(x < 7 && bombset[y][x + 1]) count++;
//右チェック
return count;
最後に
今回のプログラムで使用したクラスは…
Button、Panel、Frameなどである
使用したLayoutは…
FlowLayout、BorderLayout、GridLayoutである
イベント処理は…
actionPerformed( )である
今後の課題は…
現在の爆弾の個数、オープンした桝目の数な
どを表示するようにする