welcome: please sign in
location: "ピースを動かす"の差分
4と18のリビジョン間の差分 (その間の編集: 14回)
2009-12-15 12:40:54時点のリビジョン4
サイズ: 1192
編集者: masahiko
コメント:
2010-01-06 00:26:33時点のリビジョン18
サイズ: 5206
編集者: masahiko
コメント:
削除された箇所はこのように表示されます。 追加された箇所はこのように表示されます。
行 3: 行 3:
行 5: 行 6:

----
=== マウスを使えるようにする ===
マウスを使えるようにする方法は前に述べた通りです。

1.クラス宣言にimplements !MouseListenerを追加

2.addMouseListener(this)を追加
 . コンストラクタ内に記述します。

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) { }

----
=== 変数の宣言と初期化 ===

空白部分の位置を変数 spx,spy を使って表すことにします。
 . int型の変数で、空白の位置は横spx、縦spyであることを表します。

インスタンス変数として宣言します。
 . int spx, spy;

初期化
 . 最初は右下隅のピースを取り除いた位置です。
 . shokikaメソッド内で初期化します。
 . spx = yoko-1;
 . spy = tate-1;

----
=== 空白部分の表示 ===
spx,spyで示された位置は空白であることを示す表示を行います。
 . この処理はpaintComponent内に追加します。
forループを使って各位置の画像を表示したあとで、空白の位置は1色で塗りつぶします。
ループ内でspx,spyの位置にも何か表示されますが、その後すぐに塗りつぶすことになります。
(後で述べるように、ban[spx][spy]に入っているのは古い値であって正しい値ではありません。)
 . g.setColor(Color.lightGray);
 . 色は自由に指定してください。
 . g.fillRect(spx*haba, spy*haba, haba, haba);
 . 長方形の塗りつぶしを使っています。
----
=== 値の更新 ===
変数 spx,spy の値はmousePressedメソッド内で、押された場所に応じて更新します。

mousePressedメソッドでは引数(!MouseEvent e)を通して
ボタンが押された位置を得ることができます。
 . e.getX() でX座標(左からのピクセル値)が得られます。
 . e.getY() でY座標(上からのピクセル値)が得られます。
この値を盤の座標値に変換するには
1つのピースの縦横の大きさで割ればよい。<<BR>>
ピースの大きさは変数habaに入っているので、
クリックされた盤座標をx,yに得るために次を行う。
 . x = e.getX() / haba;
 . y = e.getY() / haba;

==== 空白部分の隣で押されたときの処理 ====

○の位置が空白部分で、そのすぐ右のAの位置でボタンが押された場合を考えます。

 . {{attachment:idou1.png}}

空白の位置、ボタンが押された位置を表す変数の値は、図の場合このようになっています。
 . spx は 1
 . spy は 2
 . x は 2
 . y は 2

このときの処理は次のようになります。
 . 1)Aの位置にあるピースをすぐ左の空白位置に移動します。
 . 2)空白位置をAの位置に変更します。
1)
Aの位置にあるピースはban[x][y]で、これを空白位置ban[spx][spy]に移すには
 . ban[spx][spy] = ban[x][y]
を行えばよい。
(注意:
ban[x][y]にも同じ値が入ったままになっている。)

2)spx,spyの値を新しい空白位置の値であるx,yに修正します。
 . spx = x;
 . spy = y;

以上をまとめると次の3行になります。
 . ban[spx][spy] = ban[x][y]
 . spx = x;
 . spy = y;
空白の右隣のAの位置で考えましたが、B,C,Dの位置でも同様の処理でよいことがわかります。

==== 移動できる位置で押されたか判断する ====

----
以下のプログラムでは、修正が必要な箇所のみ示しています。
行 10: 行 105:
public class Game14 extends JPanel implements MouseListener public class Game13 extends JPanel implements MouseListener
行 19: 行 114:
 Game14()  public void paintComponent(Graphics g)
 {
  int dx, dy, sx, sy;
  
  for(dy = 0; dy < tate; dy++)
   for(dx = 0; dx < yoko; dx++)
   {
    sx = ...;
    sy = ...;
    g.drawImage(img,
     dx*haba, dy*haba, (dx+1)*haba, (dy+1)*haba,
     sx*haba, sy*haba, (sx+1)*haba, (sy+1)*haba,
     this);
   }
  g.setColor(Color.lightGray);
  g.fillRect(spx*haba, spy*haba, haba, haba);
 }

 void shokika()
 {
  ...
  spx = yoko-1;
  spy = tate-1;
 }

 Game13()
行 23: 行 143:
行 25: 行 146:
  int x, y, dx, dy;   int x, y;
行 29: 行 150:
  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)
行 45: 行 152:
  while (x != spx || y != spy)   if( 演習 )
行 47: 行 154:
   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つ取り除いてできた空白部分を使って 移動するための処理を記述します。


マウスを使えるようにする

マウスを使えるようにする方法は前に述べた通りです。

1.クラス宣言にimplements MouseListenerを追加

2.addMouseListener(this)を追加

  • コンストラクタ内に記述します。

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) { }


変数の宣言と初期化

空白部分の位置を変数 spx,spy を使って表すことにします。

  • int型の変数で、空白の位置は横spx、縦spyであることを表します。

インスタンス変数として宣言します。

  • int spx, spy;

初期化

  • 最初は右下隅のピースを取り除いた位置です。
  • shokikaメソッド内で初期化します。
  • spx = yoko-1;
  • spy = tate-1;


空白部分の表示

spx,spyで示された位置は空白であることを示す表示を行います。

  • この処理はpaintComponent内に追加します。

forループを使って各位置の画像を表示したあとで、空白の位置は1色で塗りつぶします。 ループ内でspx,spyの位置にも何か表示されますが、その後すぐに塗りつぶすことになります。 (後で述べるように、ban[spx][spy]に入っているのは古い値であって正しい値ではありません。)

  • g.setColor(Color.lightGray);
  • 色は自由に指定してください。
  • g.fillRect(spx*haba, spy*haba, haba, haba);
  • 長方形の塗りつぶしを使っています。


値の更新

変数 spx,spy の値はmousePressedメソッド内で、押された場所に応じて更新します。

mousePressedメソッドでは引数(MouseEvent e)を通して ボタンが押された位置を得ることができます。

  • e.getX() でX座標(左からのピクセル値)が得られます。
  • e.getY() でY座標(上からのピクセル値)が得られます。

この値を盤の座標値に変換するには 1つのピースの縦横の大きさで割ればよい。
ピースの大きさは変数habaに入っているので、 クリックされた盤座標をx,yに得るために次を行う。

  • x = e.getX() / haba;
  • y = e.getY() / haba;

空白部分の隣で押されたときの処理

○の位置が空白部分で、そのすぐ右のAの位置でボタンが押された場合を考えます。

  • idou1.png

空白の位置、ボタンが押された位置を表す変数の値は、図の場合このようになっています。

  • spx は 1
  • spy は 2
  • x は 2
  • y は 2

このときの処理は次のようになります。

  • 1)Aの位置にあるピースをすぐ左の空白位置に移動します。
  • 2)空白位置をAの位置に変更します。

1) Aの位置にあるピースはban[x][y]で、これを空白位置ban[spx][spy]に移すには

  • ban[spx][spy] = ban[x][y]

を行えばよい。 (注意: ban[x][y]にも同じ値が入ったままになっている。)

2)spx,spyの値を新しい空白位置の値であるx,yに修正します。

  • spx = x;
  • spy = y;

以上をまとめると次の3行になります。

  • ban[spx][spy] = ban[x][y]
  • spx = x;
  • spy = y;

空白の右隣のAの位置で考えましたが、B,C,Dの位置でも同様の処理でよいことがわかります。

移動できる位置で押されたか判断する


以下のプログラムでは、修正が必要な箇所のみ示しています。

   1 import javax.swing.*;
   2 import java.awt.*;
   3 import java.awt.event.*;
   4 
   5 public class Game13 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         public void paintComponent(Graphics g)
  15         {
  16                 int dx, dy, sx, sy;
  17                 
  18                 for(dy = 0; dy < tate; dy++)
  19                         for(dx = 0; dx < yoko; dx++)
  20                         {
  21                                 sx = ...;
  22                                 sy = ...;
  23                                 g.drawImage(img,
  24                                         dx*haba, dy*haba, (dx+1)*haba, (dy+1)*haba,
  25                                         sx*haba, sy*haba, (sx+1)*haba, (sy+1)*haba,
  26                                         this);
  27                         }
  28                 g.setColor(Color.lightGray);
  29                 g.fillRect(spx*haba, spy*haba, haba, haba);
  30         }
  31 
  32         void shokika()
  33         {
  34                 ...
  35                 spx = yoko-1;
  36                 spy = tate-1;
  37         }
  38 
  39         Game13()
  40         {
  41                 addMouseListener(this);
  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) { }      

ピースを動かす (最終更新日時 2012-01-12 07:09:21 更新者 masahiko)