| 
  
   サイズ: 2258 
  
  コメント:  
 | 
  
   サイズ: 5491 
  
  コメント:  
 | 
| 削除された箇所はこのように表示されます。 | 追加された箇所はこのように表示されます。 | 
| 行 1: | 行 1: | 
| #acl All: | |
| 行 4: | 行 3: | 
| ピースを1つ取り除いてできた空白部分を使って | ピースを1つ取り除いてできた空白の箇所を使って | 
| 行 8: | 行 7: | 
| === マウスを使えるようにする === マウスを使えるようにする方法は前に述べた通りです。  | 
=== 空白の箇所の表現 === | 
| 行 11: | 行 9: | 
| 1.クラス宣言にimplements MouseListenerを追加 | どこに空白があるかを表すために、インスタンス変数を使います。 | 
| 行 13: | 行 11: | 
| 2.addMouseListener(this)を追加 . コンストラクタ内に記述します。  | 
* spxで空白の横方向の位置を、0~3の値で表すものとします。 | 
| 行 16: | 行 13: | 
| 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) { }  | 
* spyで空白の縦方向の位置を、0~3の値で表すものとします。 | 
| 行 23: | 行 15: | 
| 例えば、spx=0, spy=2 のときは 上から3番目の左端が空白。  | 
|
| 行 24: | 行 18: | 
| === 初期化 === 最初は右下隅のピースを取り除いた位置です。 したがって値は . spx = 3 . spy = 3 空白箇所は右下のピースを取り除いたものですから、 配列要素の値は右下のピースの値としておきます。 . ban[spx][spy] = 15 ---- === 空白箇所の表示 === spx,spyで表された場所は空白であることを示すため、 1色で塗りつぶします。 クリック時の処理の演習ではcx,cyで示された位置を塗りつぶしていましたが、 spx,spyが示す箇所を塗りつぶすように修正します。 塗りつぶしの色は好みのものを指定してください。 ---- === ボタンが押されたときの処理 === 変数 spx,spy の値をmousePressedメソッド内で、押された場所に応じて更新します。 mousePressedメソッドでは引数(!MouseEvent e)を通して ボタンが押された位置を得ることができます。 . e.getX() でX座標(左からのピクセル値)が得られます。 . e.getY() でY座標(上からのピクセル値)が得られます。 この値を盤の座標値に変換するには 1つのピースの縦横の大きさで割ればよい。<<BR>> ピースの大きさは変数habaに入っているので、 クリックされた盤座標をx,yに得るために次を行います。 . 48,49行目 . x = e.getX() / haba; . y = e.getY() / haba; ボタンが押された位置が盤の外であるときは、以下の処理は行いません。<<BR>> 盤の内部であるかどうかはx,yの値で判定できます。<<BR>> x,yとも負の数にはならないので、4方向のうち2方向の判定だけを行っています。 . 50,51行目 . if(x >= yoko || y >= tate) . return; ==== ピースを移動する処理 ==== ○の位置が空白部分で、そのすぐ右のAの位置でボタンが押された場合を考えます。 . {{attachment:idou1.png}} 空白の位置、ボタンが押された位置を表す変数の値は、図の場合には次のようになっています。 . 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を指示します。 ボタンが押された位置が空白箇所の隣であるかを判定する条件を <<Color(red:演習(52行目))>> の位置に記述しプログラムを完成させなさい。 ヒント . if( Aの位置である || Bの位置である || Cの位置である || Dの位置である ) ---- 以下のプログラムでは、修正が必要な箇所のみ示しています。 記述の無い部分は前回と同じです。  | 
|
| 行 29: | 行 114: | 
| public class Game14 extends JPanel implements MouseListener | public class Game2 extends JPanel implements MouseListener | 
| 行 38: | 行 123: | 
|  Game2() { addMouseListener(this); } void shokika() { ... spx = yoko-1; spy = tate-1; }  | 
|
| 行 56: | 行 153: | 
|  void shokika() { ... spx = yoko-1; spy = tate-1; } Game14() { addMouseListener(this); }  | 
|
| 行 70: | 行 155: | 
| int x, y, dx, dy; | int x, y; | 
| 行 74: | 行 159: | 
|   dx = (x<spx) ? -1 : (x>spx) ? 1 : 0; dy = (y<spy) ? -1 : (y>spy) ? 1 : 0; // if(x < spx) // dx = -1; // else if(x > spx) // dx = 1; // else // dx = 0; // if(y < spy) // dy = -1; // else if(y > spy) // dy = 1; // else // dy = 0; if(dx != 0 && dy != 0)  | 
if(x >= yoko || y >= tate) | 
| 行 90: | 行 161: | 
| while (x != spx || y != spy) | if( 演習 ) | 
| 行 92: | 行 163: | 
|    ban[spx][spy] = ban[spx+dx][spy+dy]; spx = spx + dx; spy = spy + dy; }; repaint();  | 
   ban[spx][spy] = ban[x][y]; spx = x; spy = y; repaint(); }  | 
ピースを動かす
ピースを1つ取り除いてできた空白の箇所を使って 移動するための処理を記述します。
空白の箇所の表現
どこに空白があるかを表すために、インスタンス変数を使います。
- spxで空白の横方向の位置を、0~3の値で表すものとします。
 - spyで空白の縦方向の位置を、0~3の値で表すものとします。
 
例えば、spx=0, spy=2 のときは 上から3番目の左端が空白。
初期化
最初は右下隅のピースを取り除いた位置です。 したがって値は
- spx = 3
 - spy = 3
 
空白箇所は右下のピースを取り除いたものですから、 配列要素の値は右下のピースの値としておきます。
- ban[spx][spy] = 15
 
空白箇所の表示
spx,spyで表された場所は空白であることを示すため、 1色で塗りつぶします。
クリック時の処理の演習ではcx,cyで示された位置を塗りつぶしていましたが、 spx,spyが示す箇所を塗りつぶすように修正します。
塗りつぶしの色は好みのものを指定してください。
ボタンが押されたときの処理
変数 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) { }      
