1068
コメント:
|
5095
|
削除された箇所はこのように表示されます。 | 追加された箇所はこのように表示されます。 |
行 1: | 行 1: |
#acl All: | |
行 3: | 行 2: |
{{{ | ピースを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が示す箇所を塗りつぶすように修正します。 塗りつぶしの色は好みのものを指定してください。 ---- === ボタンが押されたときの処理 === クリック時の処理の演習では クリックされた座標x,yから対応する位置cx,cyを求めました。 . cx,cyはmousePressedメソッド内でしか使わないので、(インスタンス変数ではなく)メソッド内の変数として宣言します。 このcx,cyとspx,spyの値を比較し、 クリックされた位置のピースが移動可能かどうか判定し、 可能な場合は移動する処理を記述します。 ==== 移動可能かどうかの判定 === 空白箇所の上下左右のとなりにあるピースの上でクリックされたときは、 そのピースをスライドして移動できる。 ==== ピースを移動する処理 ==== ○の位置が空白部分で、そのすぐ右の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の位置である ) ---- 以下のプログラムでは、修正が必要な箇所のみ示しています。 記述の無い部分は前回と同じです。 {{{#!java |
行 8: | 行 107: |
public class Game14 extends JPanel implements MouseListener | public class Game2 extends JPanel implements MouseListener |
行 17: | 行 116: |
Game14() | Game2() |
行 21: | 行 120: |
void shokika() { ... spx = yoko-1; spy = tate-1; } 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); } |
|
行 23: | 行 148: |
int x, y, dx, dy; | int x, y; |
行 27: | 行 152: |
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) |
行 43: | 行 154: |
while (x != spx || y != spy) | if( 演習 ) |
行 45: | 行 156: |
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が示す箇所を塗りつぶすように修正します。
塗りつぶしの色は好みのものを指定してください。
ボタンが押されたときの処理
クリック時の処理の演習では クリックされた座標x,yから対応する位置cx,cyを求めました。
- cx,cyはmousePressedメソッド内でしか使わないので、(インスタンス変数ではなく)メソッド内の変数として宣言します。
このcx,cyとspx,spyの値を比較し、 クリックされた位置のピースが移動可能かどうか判定し、 可能な場合は移動する処理を記述します。
==== 移動可能かどうかの判定 === 空白箇所の上下左右のとなりにあるピースの上でクリックされたときは、 そのピースをスライドして移動できる。
ピースを移動する処理
○の位置が空白部分で、そのすぐ右の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) { }