5492
コメント:
|
6580
|
削除された箇所はこのように表示されます。 | 追加された箇所はこのように表示されます。 |
行 15: | 行 15: |
1.クラス宣言にimplements !MouseListenerを追加 2.addMouseListener(this)を追加 |
1.import文を追加 . 3行目 2.クラス宣言にimplements !MouseListenerを追加 . 5行目 3.addMouseListener(this)を追加 |
行 19: | 行 23: |
3.マウスイベントに対する5つのメソッドを記述 . public void mousePressed(!MouseEvent e) { } . public void mouseEntered(!MouseEvent e) { } . public void mouseExited(!MouseEvent e) { } . public void mouseReleased(!MouseEvent e) { } . public void mouseClicked(!MouseEvent e) { } |
. 16行目 4.マウスイベントに対する5つのメソッドを記述 . public void mousePressed(!MouseEvent e) . public void mouseEntered(!MouseEvent e) . public void mouseExited(!MouseEvent e) . public void mouseReleased(!MouseEvent e) . public void mouseClicked(!MouseEvent e) . 44行目以下 |
行 40: | 行 46: |
. 前回作成したshokikaメソッドの中に追加すること。 . 35,36行目 |
. 前回(と今回で)作成したshokikaメソッドの中に追加すること。 . 22,23行目 |
行 52: | 行 58: |
. 40,41行目 | |
行 53: | 行 60: |
. 色は自由に指定してください。 | |
行 55: | 行 61: |
. 長方形の塗りつぶしを使っています。 ---- === 値の更新 === 変数 spx,spy の値はmousePressedメソッド内で、押された場所に応じて更新します。 |
colorは好みの色を指定してください。 長方形の塗りつぶしを使っています。 ---- === ボタンが押されたときの処理 === 変数 spx,spy の値をmousePressedメソッド内で、押された場所に応じて更新します。 |
行 67: | 行 74: |
クリックされた盤座標をx,yに得るために次を行う。 | クリックされた盤座標をx,yに得るために次を行います。 . 48,49行目 |
行 71: | 行 79: |
==== 空白部分の隣で押されたときの処理 ==== | ボタンが押された位置が盤の外であるときは、以下の処理は行いません。<<BR>> 盤の内部であるかどうかはx,yの値で判定できます。<<BR>> x,yとも負の数にはならないので、4方向のうち2方向の判定だけを行っています。 . 50,51行目 . if(x >= yoko || y >= tate) . return; ==== ピースを移動する処理 ==== |
行 77: | 行 92: |
空白の位置、ボタンが押された位置を表す変数の値は、図の場合このようになっています。 | 空白の位置、ボタンが押された位置を表す変数の値は、図の場合には次のようになっています。 |
行 83: | 行 98: |
このときの処理は次のようになります。 | 次の2つの処理を順に行うよう記述します。 |
行 87: | 行 102: |
Aの位置にあるピースはban[x][y]で、これを空白位置ban[spx][spy]に移すには | Aの位置どのピースがあるかはban[x][y]の値として記憶しており、 この値を空白位置である(spx,spy)に移すには |
行 91: | 行 107: |
ban[x][y]にも同じ値が入ったままになっている。) | ban[x][y]にも同じ値が残ったままになっている。) |
行 98: | 行 114: |
. 54~56行目 | |
行 102: | 行 119: |
==== 移動できる位置で押されたか判断する ==== |
---- === 演習 === ピースを移動する処理は、空白箇所の隣でボタンが押されたときだけ行います。 条件が成り立つときだけ、ピースを移動する処理を行いrepaintを指示します。 ボタンが押された位置が空白箇所の隣であるかを判定する条件を <<Color(red:演習(52行目))>> の位置に記述しプログラムを完成させなさい。 ヒント . if( Aの位置である || Bの位置である || Cの位置である || Dの位置である ) |
行 107: | 行 134: |
記述の無い部分は前回と同じです。 | |
行 112: | 行 140: |
public class Game13 extends JPanel implements MouseListener | public class Game2 extends JPanel implements MouseListener |
行 121: | 行 149: |
Game2() { addMouseListener(this); } void shokika() { ... spx = yoko-1; spy = tate-1; } |
|
行 139: | 行 179: |
void shokika() { ... spx = yoko-1; spy = tate-1; } Game13() { addMouseListener(this); } |
ピースを動かす
ピースを1つ取り除いてできた空白部分を使って 移動するための処理を記述します。
前回作成したプログラムに書き加えて完成させましょう。
このページの最後にプログラムの修正が必要な部分のみを示しています。
マウスを使えるようにする
マウスを使えるようにする方法は前に述べた通りです。
1.import文を追加
- 3行目
2.クラス宣言にimplements MouseListenerを追加
- 5行目
3.addMouseListener(this)を追加
- コンストラクタ内に記述します。
- 16行目
4.マウスイベントに対する5つのメソッドを記述
public void mousePressed(MouseEvent e)
public void mouseEntered(MouseEvent e)
public void mouseExited(MouseEvent e)
public void mouseReleased(MouseEvent e)
public void mouseClicked(MouseEvent e)
- 44行目以下
変数の宣言と初期化
空白部分の位置を変数 spx,spy を使って表すことにします。
- int型の変数で、空白の位置は横spx、縦spyであることを表します。
インスタンス変数として宣言します。
- 12行目
- int spx, spy;
初期化
- 最初は右下隅のピースを取り除いた位置です。
- shokikaメソッド内で初期化します。
- 前回(と今回で)作成したshokikaメソッドの中に追加すること。
- 22,23行目
- spx = yoko-1;
- spy = tate-1;
空白部分の表示
spx,spyで示された位置は空白であることを示す表示を行います。
- この処理はpaintComponent内に追加します。
forループを使って各位置の画像を表示したあとで、空白の位置は1色で塗りつぶします。 ループ内でspx,spyの位置にも何か表示されますが、その後すぐに塗りつぶすことになります。 (後で述べるように、ban[spx][spy]に入っているのは古い値であって正しい値ではありません。)
- 40,41行目
- g.setColor(Color.lightGray);
- g.fillRect(spx*haba, spy*haba, haba, haba);
colorは好みの色を指定してください。 長方形の塗りつぶしを使っています。
ボタンが押されたときの処理
変数 spx,spy の値をmousePressedメソッド内で、押された場所に応じて更新します。
mousePressedメソッドでは引数(MouseEvent e)を通して ボタンが押された位置を得ることができます。
- e.getX() でX座標(左からのピクセル値)が得られます。
- e.getY() でY座標(上からのピクセル値)が得られます。
この値を盤の座標値に変換するには 1つのピースの縦横の大きさで割ればよい。
ピースの大きさは変数habaに入っているので、 クリックされた盤座標をx,yに得るために次を行います。
- 48,49行目
- x = e.getX() / haba;
- y = e.getY() / haba;
ボタンが押された位置が盤の外であるときは、以下の処理は行いません。
盤の内部であるかどうかはx,yの値で判定できます。
x,yとも負の数にはならないので、4方向のうち2方向の判定だけを行っています。
- 50,51行目
if(x >= yoko || y >= tate)
- return;
ピースを移動する処理
○の位置が空白部分で、そのすぐ右のAの位置でボタンが押された場合を考えます。
空白の位置、ボタンが押された位置を表す変数の値は、図の場合には次のようになっています。
- spx は 1
- spy は 2
- x は 2
- y は 2
次の2つの処理を順に行うよう記述します。
- 1)Aの位置にあるピースをすぐ左の空白位置に移動します。
- 2)空白位置をAの位置に変更します。
1) Aの位置どのピースがあるかはban[x][y]の値として記憶しており、 この値を空白位置である(spx,spy)に移すには
- ban[spx][spy] = ban[x][y]
を行えばよい。 (注意: ban[x][y]にも同じ値が残ったままになっている。)
2)spx,spyの値を新しい空白位置の値であるx,yに修正します。
- spx = x;
- spy = y;
以上をまとめると次の3行になります。
- 54~56行目
- ban[spx][spy] = ban[x][y]
- spx = x;
- spy = y;
空白の右隣のAの位置で考えましたが、B,C,Dの位置でも同様の処理でよいことがわかります。
演習
ピースを移動する処理は、空白箇所の隣でボタンが押されたときだけ行います。
条件が成り立つときだけ、ピースを移動する処理を行いrepaintを指示します。
ボタンが押された位置が空白箇所の隣であるかを判定する条件を 演習(52行目) の位置に記述しプログラムを完成させなさい。
ヒント
if( Aの位置である || Bの位置である || Cの位置である || Dの位置である )
以下のプログラムでは、修正が必要な箇所のみ示しています。 記述の無い部分は前回と同じです。
1 import javax.swing.*;
2 import java.awt.*;
3 import java.awt.event.*;
4
5 public class Game2 extends JPanel implements MouseListener
6 {
7 int haba;
8 int yoko, tate;
9 String fname;
10 Image img;
11 int[][] ban;
12 int spx, spy;
13
14 Game2()
15 {
16 addMouseListener(this);
17 }
18
19 void shokika()
20 {
21 ...
22 spx = yoko-1;
23 spy = tate-1;
24 }
25
26 public void paintComponent(Graphics g)
27 {
28 int dx, dy, sx, sy;
29
30 for(dy = 0; dy < tate; dy++)
31 for(dx = 0; dx < yoko; dx++)
32 {
33 sx = ...;
34 sy = ...;
35 g.drawImage(img,
36 dx*haba, dy*haba, (dx+1)*haba, (dy+1)*haba,
37 sx*haba, sy*haba, (sx+1)*haba, (sy+1)*haba,
38 this);
39 }
40 g.setColor(Color.lightGray);
41 g.fillRect(spx*haba, spy*haba, haba, haba);
42 }
43
44 public void mousePressed(MouseEvent e)
45 {
46 int x, y;
47
48 x = e.getX() / haba;
49 y = e.getY() / haba;
50 if(x >= yoko || y >= tate)
51 return;
52 if( 演習 )
53 {
54 ban[spx][spy] = ban[x][y];
55 spx = x;
56 spy = y;
57 repaint();
58 }
59 }
60
61 public void mouseEntered(MouseEvent e) { }
62 public void mouseExited(MouseEvent e) { }
63 public void mouseReleased(MouseEvent e) { }
64 public void mouseClicked(MouseEvent e) { }