welcome: please sign in
location: "ピースを動かす"の差分
41と42のリビジョン間の差分
2012-01-12 07:00:55時点のリビジョン41
サイズ: 3868
編集者: masahiko
コメント:
2012-01-12 07:02:55時点のリビジョン42
サイズ: 5560
編集者: masahiko
コメント:
削除された箇所はこのように表示されます。 追加された箇所はこのように表示されます。
行 100: 行 100:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Game6 extends JPanel implements MouseListener
{
 Image img;
 int[][] ban;
 int spx, spy;
 
 Game6()
 {
  ImageIcon ii = new ImageIcon("game0.png");
  img = ii.getImage();
  addMouseListener(this);
  ban = new int[4][4];
  shokika();
  spx = 3;
  spy = 3;
 }

 void shokika()
 {
  int x, y;
  
  for (x = 0; x < 4; x++)
   for (y = 0; y < 4; y++)
    ban[x][y] = x + y*4;
 }
 
 public void paintComponent(Graphics g)
 {
  int w, h, ax, ay, sx, sy, x, y;
  w = 100;
  h = 100;
  for (x = 0; x < 4; x++)
   for (y = 0; y < 4; y++)
   {
    ax = x*100 ;
    ay = y*100 ;
    sx = (ban[x][y] % 4)*100 ;
    sy = (ban[x][y] / 4)*100 ;
    g.drawImage(img, ax,ay,ax+w,ay+h, sx,sy,sx+w,sy+h, this);
   }
  g.setColor(Color.blue);
  g.fillRect(spx*100, spy*100, 100, 100);
 }
 
 public void mousePressed(MouseEvent e)
 {
  int x, y, cx, cy;
  x = e.getX();
  y = e.getY();
  cx = x / 100;
  cy = y / 100;
  if (cx == spx && cy == spy-1 || cx == spx && cy == spy+1 ||
      cy == spy && cx == spx-1 || cy == spy && cx == spx+1)
  {
   ban[spx][spy] = ban[cx][cy];
   spx = cx;
   spy = cy;
   ban[spx][spy] = 15;
   repaint();
  }
 }
 public void mouseEntered(MouseEvent e) { }
 public void mouseExited(MouseEvent e) { }
 public void mouseReleased(MouseEvent e) { }
 public void mouseClicked(MouseEvent e) { }
 
 public static void main(String[] args)
 {
  JFrame f;
  
  f = new JFrame();
  f.setVisible(true);
  f.setTitle("15Game");
  f.setSize(420, 450);
  f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  f.add( new Game6() );
 }
}

ピースを動かす

ピースを1つ取り除いてできた空白の箇所を使って 移動するための処理を記述します。


空白の箇所の表現

どこに空白があるかを表すために、インスタンス変数を使います。

  • spxで空白の横方向の位置を、0~3の値で表すものとします。
  • spyで空白の縦方向の位置を、0~3の値で表すものとします。

例えば、spx=0, spy=2 のときは 上から3番目の左端が空白。

初期化

最初は右下隅のピースを取り除いた位置です。 したがって値は

  • spx = 3
  • spy = 3

空白箇所は右下のピースを取り除いたものですから、 配列要素の値は右下のピースの値としておきます。

  • ban[spx][spy] = 15


空白箇所の表示

paintComponent内に記述。

spx,spyで表された場所は空白であることを示すため、 1色で塗りつぶします。

クリック時の処理の演習ではcx,cyで示された位置を塗りつぶしていましたが、 spx,spyが示す箇所を塗りつぶすように修正します。

塗りつぶしの色は好みのものを指定してください。


ボタンが押されたときの処理

mousePressed内に記述。

クリック時の処理の演習では クリックされた座標x,yから対応する位置cx,cyを求めました。

  • cx,cyはmousePressedメソッド内でしか使わないので、(インスタンス変数ではなく)メソッド内の変数として宣言します。

このcx,cyとspx,spyの値を比較し、 クリックされた位置のピースが移動可能かどうか判定し、 可能な場合は移動する処理を記述します。

移動可能かどうかの判定

空白箇所の上下左右のとなりにあるピースの上でクリックされたときは、 そのピースをスライドして移動できる。

例えば丸で示した位置が空白のとき

  • idou1.png

クリックされた位置がA,B,C,Dのどれかであればよい。

空白の位置はspx,spyで、クリックされた位置はcx,cyで表されているので、 これを用いて判定を行う。

例えば、丸の位置が空白部分でAの位置でボタンが押された場合、変数の値は次のようになっています。

  • spx は 1
  • spy は 2
  • cx は 2
  • cy は 2

ピースを移動する処理

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

次の処理を順に行ないます。

  • 1)Aの位置にあるピースをすぐ左の空白位置に移動します。
  • 2)空白位置をAの位置に変更します。
  • 3)新しい空白位置に対応する値を代入します。

1)Aの位置どのピースがあるかはban[cx][cy]の値として記憶しており、 この値を空白位置である(spx,spy)に移すには

  • ban[spx][spy] = ban[cx][cy]

を行えばよい。

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

  • spx = cx
  • spy = cy

3)空白位置に対応する値(15)を代入します。

  • ban[spx][spy] = 15

以上をまとめると次のようになります。

  • ban[spx][spy] = ban[cx][cy];
  • spx = cx;
  • spy = cy;
  • ban[spx][spy] = 15;

空白の右隣のAの位置で考えましたが、 B,C,Dの位置でもこの命令でよいことを理解しておくこと。


プログラム

  •    1 import javax.swing.*;
       2 import java.awt.*;
       3 import java.awt.event.*;
       4 
       5 public class Game6 extends JPanel implements MouseListener
       6 {
       7         Image img;
       8         int[][] ban;
       9         int spx, spy;
      10         
      11         Game6()
      12         {
      13                 ImageIcon ii = new ImageIcon("game0.png");
      14                 img = ii.getImage();
      15                 addMouseListener(this);
      16                 ban = new int[4][4];
      17                 shokika();
      18                 spx = 3;
      19                 spy = 3;
      20         }
      21 
      22         void shokika()
      23         {
      24                 int x, y;
      25                 
      26                 for (x = 0; x < 4; x++)
      27                         for (y = 0; y < 4; y++)
      28                                 ban[x][y] = x + y*4;
      29         }
      30         
      31         public void paintComponent(Graphics g)
      32         {
      33                 int w, h, ax, ay, sx, sy, x, y;
      34                 w = 100;
      35                 h = 100;
      36                 for (x = 0; x < 4; x++)
      37                         for (y = 0; y < 4; y++)
      38                         {
      39                                 ax = x*100 ;
      40                                 ay = y*100 ;
      41                                 sx = (ban[x][y] % 4)*100 ;
      42                                 sy = (ban[x][y] / 4)*100 ;
      43                                 g.drawImage(img, ax,ay,ax+w,ay+h, sx,sy,sx+w,sy+h, this);
      44                         }
      45                 g.setColor(Color.blue);
      46                 g.fillRect(spx*100, spy*100, 100, 100);
      47         }
      48         
      49         public void mousePressed(MouseEvent e)
      50         {
      51                 int x, y, cx, cy;
      52                 x = e.getX();
      53                 y = e.getY();
      54                 cx = x / 100;
      55                 cy = y / 100;
      56                 if (cx == spx && cy == spy-1 || cx == spx && cy == spy+1 ||
      57                     cy == spy && cx == spx-1 || cy == spy && cx == spx+1)
      58                 {
      59                         ban[spx][spy] = ban[cx][cy];
      60                         spx = cx;
      61                         spy = cy;
      62                         ban[spx][spy] = 15;
      63                         repaint();
      64                 }
      65         }
      66         public void mouseEntered(MouseEvent e) { }
      67         public void mouseExited(MouseEvent e) { }
      68         public void mouseReleased(MouseEvent e) { }
      69         public void mouseClicked(MouseEvent e) { }
      70         
      71         public static void main(String[] args)
      72         {
      73                 JFrame f;
      74                 
      75                 f = new JFrame();
      76                 f.setVisible(true);
      77                 f.setTitle("15Game");
      78                 f.setSize(420, 450);
      79                 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      80                 f.add( new Game6() );
      81         }
      82 }
    


演習

ボタンが押された位置が空白箇所の隣であるかを判定する条件を ? の位置に記述しプログラムを完成させなさい。

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