ゲームらしくするために、チーズを導入した。チーズは、[Alt]+矢印キーで上下左右に移動可能である。チーズを移動するたびに、ネズミがチーズに近づく。チーズを使って、ネズミを池に誘い込むというゲームにした。
このために、以下の機能を追加しなければならない:
2のネズミをチーズに近づける処理を実装するために、ネズミがランダムに動くだけではだめである。 ネズミを指定した方向へ動かすことができるように、まずはJavascriptゲーム03のプログラムを書き換えるところから始めよう。
Javascriptゲーム 03では、onclick、mouseover、mouseup、mouseoutというイベントハンドラーの処理としてmove()関数を指定してランダムにネズミを移動していた。move()関数では、呼び出されるたびにgetElementById()関数で要素を取得していたが、これをグローバル変数として要素を表すnezumi1とnezumi2を用意して、移動のたびにgetElementById()関数を呼び出す必要がないようにした。
function coordinates(element)の定義で使用している
は、Javascriptの連想配列の定義である。
これにより定義された連想配列positionは、キーxの値は0、キーyの値も0で初期化している。
例えば、連想配列positionのキーxの変数は、position.xと書く。Perlのようにposition['x']と書くこともできる(Perlの連想配列は$position{'x'}のように[]ではなく{}を使用するので、似ているというだけで同じではない)。
イベントハンドラーと同様に、イベントの発生に対応して関数を呼び出す方法に、イベントリスナーを使用する方法がある。 キーボードのキーを押すというイベントの発生に対して、チーズを移動するという仕組みをイベントリスナーを使って実装しよう。
Firefoxでは、キーを押す(keydown)というイベントの発生に対してKeyDownFunc()という関数を呼び出すイベントリスナーは、
によって設定して開始する。
function KeyDownFunc(e)の定義では、
とコメントアウトしてある部分のコメントを解除すると、キーが押されたときにkey_codeの値をFirefoxのWebコンソールのロギングで確認できる。 これを利用して、[→]、[←]、[↓]、[↑]キーを押したときのキーのコードを調べて、チーズを動かす関数move_cheese(dx, dy)を呼び出して、チーズを動かしている。
キーボードのキーを押してチーズを動かしたときに、ネズミをチーズに近づけるために動かす関数は、function move2cheese(element, Delta)で定義している。 本来はmove_to_cheeseという名前にすべきであったが、_to_で名前が長くなりすぎるので同じ発音の2を使った。プログラミングではtoの代わりに発音が同じ2を名前に使う場合がよくある。
function move2cheese(element, Delta)の定義のなかの
if(cheese.style.display == "none" ){ return; } if(element.style.display == "none" ){ return; }
は、チーズが非表示の時、あるいはネズミ自身が非表示のときは、何もしないで戻るということで、ネズミを動かさないという意味である。
は、ネズミからチーズの方向へ向かうベクトルを表わす連想配列である。
は、このベクトルの長さで、ネズミからチーズまでの距離である。 Deltaが、ネズミのチーズ方向への移動距離である。
function KeyDownFunc(e)の定義でmove2cheese(element, Delta)を呼び出すときに、
として、DeltaがD_nezumi/2になるように呼び出しているので、ネズミの移動量はD_nezumiの半分になっている。
関数function check_cheese(element)を、引数elementがチーズと重なる場合は1、そうでない場合は0を返すように定義している。
randomove(nezumi1, D_nezumi)やmove2cheese(nezumi1, D_nezumi/2)で、ネズミを動かしたとき、check_cheese()を呼び出してチェックしている。
// 位置が変更されたネズミがチーズとぶつかったか否かを判定 if( check_cheese(element) == 1 ){ alert("Thanks for the cheese!"); cheese.style.display = "none"; }
ネズミがチーズに重なったときは、cheese.style.display = "none"によって、チーズを非表示にしている。
チーズを非表示にするだけではなく、document.removeEventListner("keydown" , KeyDownFunc, true)を実行して、イベントリスナーを解除した方がよい場合もある。
チーズを動かす関数function move_cheese(Delta_x, Delta_y)では、ネズミと同様、チーズが穴(このバージョンでは、池)に落ちたか否かをチェックし、落ちた場合はチーズを非表示にしている。
// 位置が変更されたチーズが穴に入ったか否かを判定 if( check_hole(p.x, p.y) == 1 ){ alert("Oops!"); cheese.style.display = "none"; }
var element = document.getElementById("Nezumi1"); element.style.zIndex = "1";
CSSのプロパティz-indexと同じ名前を、DOMを使ってJavascriptで使うことはできない。なぜなら、Javascriptでは-は引き算のマイナスを意味してしまうため、z-indexはzという変数から indexという変数の値の引く引き算と見なされてしまうからである。Javascriptでは、変数名に_(アンダースコア)は使用可能なので、z_indexとしても良かったと思うのだが、DOMではzIndexとなっている(大文字と小文字の違いに注意すること)。