データベースとは?|初心者でもわかるプログラミング学習入門
GEEK JOB編集部
前回の記事では、マウスリスナーについて勉強しました。
今回は同じくリスナーである「キーリスナー」と「アクションリスナー」について勉強します。
リスナー | 監視するイベント |
KeyListener | キーボードの入力イベント |
ActionListener | 一定時間ごとに自動的に発生するイベント |
キーボードから入力を受け取って、自機を動かします。以下が完成イメージです。
KeyListenerには3つのメソッドがあります。
以下にそれぞれのメソッドについて簡単にまとめました。
イベント | 呼ばれるタイミング |
keyPressed | キーを押しているとき |
keyReleased | キーを離したとき |
keyTyped | キーを入力しているとき |
リスナーの追加方法については、MouseListenerのときとほとんど同じです。
コードとしては、以下のようなものになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
class Field extends JPanel implements KeyListener { private int x = 100; private int y = 100; public Field() { setSize(600, 400); setBackground(Color.white); <span style="background-color: #ffff00;">setFocusable(true);</span> addKeyListener(this); } @Override public void paintComponent(Graphics g) { g.clearRect(0, 0, getWidth(), getHeight()); g.setColor(Color.red); g.fillOval(x, y, 50, 50); } @Override public void keyTyped(KeyEvent e) { } <span style="background-color: #ffff00;">@Override public void keyPressed(KeyEvent e) { int keycode = e.getKeyCode(); switch (keycode) { case KeyEvent.VK_LEFT : x -= 10; break; case KeyEvent.VK_RIGHT : x += 10; break; case KeyEvent.VK_UP : y -= 10; break; case KeyEvent.VK_DOWN : y += 10; break; } repaint(); }</span> @Override public void keyReleased(KeyEvent e) { } } |
ハイライトで示しましたが、注目すべきポイントが2つあります。
まず、MouseListenerと違って、KeyListenerではあらかじめFieldにフォーカスがあっている必要があります。
そのフォーカスを合わせるために追加したのが、以下の一文です。
1 |
setFocusable(true); |
次に、KeyEventの内容についてです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public void keyPressed(KeyEvent e) { int keycode = e.getKeyCode(); switch (keycode) { case KeyEvent.VK_LEFT : x -= 10; break; case KeyEvent.VK_RIGHT : x += 10; break; case KeyEvent.VK_UP : y -= 10; break; case KeyEvent.VK_DOWN : y += 10; break; } repaint(); } |
getKeyCode()は、Enterキーやスペースキー、上下左右キーといった、対応する文字コードがないようなボタンの入力を取得するために用います。
getKeyChar()という関数もあり、こちらは「a」や「A」のような、対応する文字が存在するボタンの入力を取得するために用います。
今回は、上下左右キーが押されたときにfillOval()の座標として使っている(x,y)の値を増減することで、自機を移動させています。
時間を計測して、自機から弾を発射したときに、弾が自動的に飛んでいくようにします。
完成イメージは以下の通りです。
時間を計測する方法にはいくつかありますが、今回はJavaで最もお手軽な方法であるActionListenerを用いることにします。
本格的にゲームを作るとすると、この方法では厳しいですが、あくまで勉強用ということでActionListenerを使います。
KeyListenerやMouseListenerと異なり、ActionListenerには1つしかメソッドがありません。
イベント | 呼ばれるタイミング |
ActionPerformed | 定期的に自動で呼ばれる |
このActionPerformed()をオーバーライドすることで、そのコンポーネントに定期的に行わせたい処理を書くことができます。
今回は、自機と別に円をもう一つ作り、その座標を時間ごとに変化させてみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
class Field extends JPanel implements KeyListener, ActionListener { private int x = 300; private int y = 300; private int bullet_x = 300; private int bullet_y = 300; public Field() { setSize(600, 400); setBackground(Color.white); setFocusable(true); addKeyListener(this); Timer timer = new Timer(20, this); timer.start(); } @Override public void paintComponent(Graphics g) { g.clearRect(0, 0, getWidth(), getHeight()); g.setColor(Color.red); g.fillOval(x, y, 50, 50); g.fillOval(bullet_x, bullet_y, 10, 10); } @Override public void keyTyped(KeyEvent e) { } @Override public void keyPressed(KeyEvent e) { int keycode = e.getKeyCode(); switch (keycode) { case KeyEvent.VK_LEFT : x -= 10; break; case KeyEvent.VK_RIGHT : x += 10; break; case KeyEvent.VK_UP : y -= 10; break; case KeyEvent.VK_DOWN : y += 10; break; } } @Override public void keyReleased(KeyEvent e) { } @Override public void actionPerformed(ActionEvent e) { bullet_y -= 5; repaint(); } } |
1つ注意していただきたいのが、コンストラクタ内のリスナーの追加方法についてです。
1 2 |
Timer timer = new Timer(20, this); timer.start(); |
MouseListenerやKeyListenerと異なり、Timerのインスタンスを作ってstart()することでタイマーを開始しています。
タイマーのコンストラクタ中の20という数字は、20ミリ秒ごとにこのコンポーネントのactionPerformed()が呼ばれることを表しています。
最後に、repaint()でコンポーネントを再描画するのを忘れないようにしましょう。
この1文を入れないと、変更が画面に反映されません。
代わりに、keyPressed()の中のrepaint()は削除しました。
別にあってもかまいませんが、どちらにせよactionPerformed()の中で定期的に呼ばれるので、コードを簡略化するためにそうしています。