- ユーザ側の意思の反映
- 第2講で学んだ描画法を用いれば、様々な画面が表現出来る筈です。
- しかしそれはあくまでもラインアートの域を出ておらず、お世辞にも"iαppli"と呼ぶ事は出来ません。
- 動くものを作るには、キー入力の把握を実現させる必要があります。つまりはユーザの意思で自在に動かす事が出来る・・そんな動的画面を構成します。
- そうすれば少なくともiαppliと呼べるものは仕上がる筈です。
- では、プログラムを見て行きましょう。
public void run() {
for (;;) {
//再描画
repaint();
try {
//約30分の1秒毎に1コマ描画
Thread.sleep(30);
} catch (InterruptedException e) {
//例外が発生したら終了
return;
}
//キー処理用メソッドを呼び出す
keyMovement();
}
}
/**キー入力を扱うメソッド*/
public void keyMovement() {
/**十字キーでの操作用変数*/
final int nKS = getKeypadState();
if ((nKS & 1 << Display.KEY_LEFT) != 0) {
mex--;
} else if ((nKS & 1 << Display.KEY_RIGHT) != 0) {
mex++;
}
if ((nKS & 1 << Display.KEY_UP) != 0) {
mey--;
} else if ((nKS & 1 << Display.KEY_DOWN) != 0) {
mey++;
}
}
for (;;) {
//再描画
repaint();
try {
//約30分の1秒毎に1コマ描画
Thread.sleep(30);
} catch (InterruptedException e) {
//例外が発生したら終了
return;
}
//キー処理用メソッドを呼び出す
keyMovement();
}
}
/**キー入力を扱うメソッド*/
public void keyMovement() {
/**十字キーでの操作用変数*/
final int nKS = getKeypadState();
if ((nKS & 1 << Display.KEY_LEFT) != 0) {
mex--;
} else if ((nKS & 1 << Display.KEY_RIGHT) != 0) {
mex++;
}
if ((nKS & 1 << Display.KEY_UP) != 0) {
mey--;
} else if ((nKS & 1 << Display.KEY_DOWN) != 0) {
mey++;
}
}
- まず太字で書いてある行を見て下さい。この部分ではスレッドの処理を他のメソッドへと委託しています。
- 今回の様なプログラムなら直接run()メソッド内に記述しても特に問題は無いのですが、将来的にキー入力周辺では様々な条件分岐や処理を持たせる筈です。すると、その部分は非常に長いプログラムになってしまう事でしょう。
- そういった場合、1つのメソッドとして区切っておけば可読性が上がり、デバッグ作業もし易くなります。
- キー入力の反映
- それでは引き継いだ内容を具体的に解説します。
- iαppliで扱われるキー入力は総てgetKeypadState()というメソッドが返す値が保持しています。
- 本例では十字キーしか扱わない為"十字キーでの操作用変数"と書きましたが、実際は0〜9、#及び*キー等も監視されています。
- if文で扱われている条件式は少し難しいものですが、この条件でキー入力の有無を判定出来るとだけ覚えておけば良いでしょう。
- 今回は上下でx軸を、左右でy軸を操作しています。ここで使用している変数mex及びmeyは事前にフィールドとして作成して下さい。
/**プレイヤーのx軸*/
private int mex = 120;
/**プレイヤーのy軸*/
private int mey = 120;
private int mex = 120;
/**プレイヤーのy軸*/
private int mey = 120;
- 次に(x, y)座標の移動を反映させるキャラクターを描画します。paint()メソッドを見てみましょう。
public void paint(Graphics g) {
g.lock();
g.setColor(Graphics.getColorOfRGB(0x00, 0x00, 0x00));
//背景の描画
g.fillRect(0, 0, 240, 240);
g.setColor(Graphics.getColorOfRGB(0xff, 0xff, 0xff));
//キャラクターの描画
g.drawLine(mex - 5, mey - 5, mex + 5, mey + 5);
g.drawLine(mex - 5, mey + 5, mex + 5, mey - 5);
g.unlock(true);
}
g.lock();
g.setColor(Graphics.getColorOfRGB(0x00, 0x00, 0x00));
//背景の描画
g.fillRect(0, 0, 240, 240);
g.setColor(Graphics.getColorOfRGB(0xff, 0xff, 0xff));
//キャラクターの描画
g.drawLine(mex - 5, mey - 5, mex + 5, mey + 5);
g.drawLine(mex - 5, mey + 5, mex + 5, mey - 5);
g.unlock(true);
}
- キャラクターを2本の直線で描画します。これで現在の(x, y)座標が×として表示されます。
- それではこのプログラムを実行させてみて下さい。
- この×と十時キー操作の連動が確認出来る筈です。
- 移動制限法
- さて、このプログラムには少し修正が必要な部分があります。実際に動かしてみると気付くと思いますが、このままではずっと右を押し続けると×は画面外に出てしまうのです。
- 勿論この様な画面は見えませんが、画面外に出てもx座標はインクリメントされ続けます。
- この状況を防ぐには、if文の条件で縛ると良いでしょう。xやyの値を操作する部分で画面外に出る事を防ぎます。
/**キー入力を扱うメソッド*/
public void keyMovement() {
/**十字キーでの操作用変数*/
final int nKS = getKeypadState();
if ((nKS & 1 << Display.KEY_LEFT) != 0) {
mex--;
} else if ((nKS & 1 << Display.KEY_RIGHT) != 0) {
if (x < 220) {
mex++;
}
if ((nKS & 1 << Display.KEY_UP) != 0) {
mey--;
} else if ((nKS & 1 << Display.KEY_DOWN) != 0) {
mey++;
}
}
public void keyMovement() {
/**十字キーでの操作用変数*/
final int nKS = getKeypadState();
if ((nKS & 1 << Display.KEY_LEFT) != 0) {
mex--;
} else if ((nKS & 1 << Display.KEY_RIGHT) != 0) {
if (x < 220) {
mex++;
}
if ((nKS & 1 << Display.KEY_UP) != 0) {
mey--;
} else if ((nKS & 1 << Display.KEY_DOWN) != 0) {
mey++;
}
}
- 残り3箇所も同じ様にif文で条件を設けると、×を任意の範囲内で留める事が可能です。
- また、動きを早くする場合は
mex += 2;
- この様に、変動値を大きくすると上手く行く筈です。