メールや掲示板で受けた質問に対する回答をまとめています。
参考にしてもらえたら嬉しいです。
このうちいずれ本文に移動するものもあるかも知れません^^;
(Q)
JavaScriptがうまく動きませんが、原因がわかりません。
(A)
原因が色々考えられるため答えることは難しいです。
まず本編の途中でうまく動かない場合は、それ以前を復習してください。
読み飛ばしている箇所があるとか、理解していない箇所があるなどが多いようです。
プログラムは積み重ねなので焦らずじっくりやりましょう。
応用中に起きている場合は、
まずはエラーが出ていないかを確認してみるのが良いでしょう。
エラーの確認方法は
3-f.エラーメッセージについて
を見てみてください。
エラーも出なくてうまく動かない場合は、
根本的な作りというか考え方にミスがあるということになります。
これはちと難しいですが、ソースをじーっと眺めて解決するのが正攻法です。
でも私は面倒なので、
要所要所に alert('pass1') とか alert('pass2') とかって配置して、
または alert(ballx) などと変数の中身を表示して、
意図した通りに関数に来ているか、
変数が変化しているかを調べたりします(^_^;
修正を効率よくするには経験が必要なので、
めげずに色々なゲームを作ってみてください。
(Q)
『ライン10、オブジェクトを選択してください』というエラーが出ます。
どうすればよいでしょうか。
(A)
エラーの確認方法は
3-f.エラーメッセージについて
をご覧になってください。
この「オブジェクトを選択してください」というのもわかりづらいエラーメッセージですが、
このエラーが出るケースで多いミスは、
・呼び出す関数の名前を間違えている、または定義されていない
・参照する変数の名前を間違えている、または定義されていない
あたりです。
ファイルの上から10行目で使用している関数や変数で、
本当は定義する必要があるのに定義されていないものが無いか、
その関数名、変数名でスペルミスが無いか確認してみてください。
一文字でも違うと違う関数/変数とみなされますので、
注意して調べましょう。
今までこの質問をいくつか受けましたが、
質問する方が関数定義をよく理解していないケースが多いようです。
3-e.アンカーから入力してみましょう
や
4-c.レイヤーを操作してみましょう。
の中にある関数定義の説明をもう一度よく読んでみてください。
(Q)
『WEBページに問題があるため正しく表示、または機能しなくなる可能性があります。』
というエラーがでてくるんですが、WEBページの問題って何ですか?
(A)
貴方が作っているhtmlやJavaScriptのページが「WEBページ」です。
通常はどこかのホームページにミスの記述がある場合に出るメッセージなのですが、
今は貴方がそのホームページを製作し、しかもミスがある、ということになります。
これは何がエラーなのかまで詳細に確認することができると思います。
エラーの確認方法は
3-f.エラーメッセージについて
をご覧になってください。
(Q)
ブロック毎に違う得点をつけるにはどうしたらよいでしょうか。
(A)
もう一度10-b.得点を付けて完成!
をじっくり読んでみてください。
その中では共通の関数内で score に 100 を加えていますが、
各ブロックのあたり判定の中で加えるようにすればできます。
(Q)
ブロックを増やす/減らすにはどうしたらよいでしょうか。
(A)
9.ブロックをよ~く読んでください。
理解できてしまえば簡単なはずですので、
焦らずじっくりやってください。
(Q)
ブロックを増やす度にプログラムを増やさなければいけないのでしょうか。
(A)
この疑問を持った方はプログラミングセンスが良いと言えます。
ただ、今まで私の掲示板でこの質問は受けたことは、実はありません(_ _;
さて回答ですが、疑問のようなことはもちろんありません。
「ループ」と「配列」という技法を使えばもっと短く簡単に書くことができます。
もちろんプログラムを増やしてブロックを増やしても構いませんが、
単調な処理の繰り返しを人間様がする必要はありませんので、
機械にできることは機械にやらせましょう(^_^)
ただしこれはワンランク上のプログラミング技法なので少し難しいかも知れないな、
と思い本編では省略しました。
しかしこれを理解してしまうとプログラムの幅がグググっと広がります。
むしろ本当にプログラムを理解するには必須の項目かも知れません。
是非マスターしてください。
まずループですが、これは繰り返しのことです。
こんな風に書きます。
var i;
for ( i = 0 ; i < 3 ; i++ ) {
alert(i);
}
|
for は for(初期設定;ループ条件;ループ内最終処理){中身} として使う命令です。
初期設定 → ループ条件判定(偽なら終了) → 中身 → ループ内最終処理 → ループ条件判定(偽なら終了)…
という風に繰り返し実行されます。
でもちょっとわかりずらいですかね。
上記は慣例的な形になっていますので、これで説明しましょう。
まず最初に i=0 が実施されます。変数iに0が入ります。
次に i < 3 が実施されます。現時点では真ですので中身の処理に移り、
中身にあるalert(i)が実施されます。
画面に0と出ますね?
その後に i++ が実施されます。
i++ は i = i + 1 と(ほぼ)同じ意味ですが、for内ではこちらを使うことが多いですね。
これでiが1になります。
次に i < 3 の判定のところに戻ります。まだ真ですので中身の処理に移り実施されます。
ここまで示せばわかると思いますが、iが0,1,2の間は中身が実施されます。
本編で説明したブロック表示のhtml部分のプログラムを以下に書きます。
var i;
for ( i = 0 ; i < 8 ; i++ ) {
document.write( '\n' );
document.write( '  \n' );
document.write( ' \n' );
}
|
実践ではこのように中身の処理で巧みに i を使う必要があります。
例えば id のところは 'lyrblock' + i の形になっています。
つまりこれは、最初は lyrblock0、次のループで lyrblock1、
更に繰り返してlyrblock7 までとなります。
本編では block1~8としましたが、
ループでは慣例的に0から始めることが多いので 0~7 としています。
ちなみに「'」(シングルクォーテーション)と
「"」(ダブルクォーテーション)が使われていますが、
どちらも対応する範囲内で文字列を表します。
「'"'」は「"」という文字列を、「"'"」は「'」という文字列を意味します。
このようにdocument.writeという関数を使用してhtmlとして書き出すこともできるのですが、
こんなテクニックも必要になるので合わせて覚えておいてください。
次に配列ですが、複数の値を同列に扱うものと言ったらよいでしょうか。
とりあえずは以下を見てください。
var blockf;
blockf = new Array(8);
var i;
for ( i = 0 ; i < 8 ; i++ ) {
blockf[i] = false;
}
|
配列は、まず最初に「箱の数」を確保するためにnew Array(要素数)と書きます。
そしてそれを 変数名[インデックス] の形で参照します。
要素数が8なら、有効なインデックスは0,1,2...,7になります。
本編で出てきた blockf1 や blockf2 は、
blockf[0]やblockf[1]と置き換えることができます。
この形にすることで、例のようにループと合わせて使うことができるのです。
どうでしょう。使えそうですか?
本編を理解している人なら結構簡単に理解できてしまうかも知れません。
これが理解できれば本当にプログラムを理解したと間違いなく言えますね。
これが他のコーナーより少し難しいのは事実だと思うので、
理解するには時間が必要かも知れませんが、
今まで以上に根気良くがんばってください。
(Q)
ボールを速く(遅く)するにはどうしたらよいでしょうか。
(A)
これは7-c.速度を設定してみましょうにありますね。
ここでspeedxとspeedyの初期値を変更すれば問題なくできると思います。
ただし速度を速くする場合は少し厄介な問題が残ります。
それは当たり判定です。
speedx等を大きくすることでボールは一瞬にして別の場所へ移動することになります。
人間の目の錯覚で動いているように見えるだけなんですね。
そして今の8という速度はそれでも偶然大丈夫なようになっているのですが、
それを32とかにするとブロックを突き抜けたりします。
それは当たり判定の方式では今のボールの位置だけで判定しているので、
瞬間移動を繰り返す動き方では突き抜ける動作になってしまうのです。
ではどうすればよいかということなのですが、
解決方法は二つあります。
ひとつは前回のボールの位置と今回のボールの位置から軌跡を算出し、
数学的に当たり判定を行う方法です。
これはこれで面白いのですが、
大学レベルの数学が必要になるのでやめておきましょう。
でもう一つの解決方法ですが、処理を何回も連続で動かすという手法があります。
関数gameBodyの中は、
「タイマークリア部」→「各種処理部」→「タイマー設定部」
という構成になっていますが、
各種処理部を関数化して外に出し、
速度を2倍にしたければその関数を2回、3倍なら3回呼ぶようにします。
少しわかりづらいかも知れませんが、試してみてください!
(Q)
運の要素を入れたいのですが。
(A)
乱数というものを使うとゲームの幅が広がりますね。
rndという関数を作りましたので使ってみてください。
function rnd( n ) {
return( Math.floor( n * Math.random() ) );
}
|
これは例えばrnd(3)と書くと0,1,2のどれかをランダムに返す関数です。
rnd(5)なら0~4の整数を返します。
例えば
speedx = (rnd(2)*2-1)*8;
とすると、speedx の値が -8 か 8 のどちらかになりますので、
ボールの初期方向を開始する度に変更することができます。
関数rnd内も少し解説しましょう。
Math.random()は0以上1未満のランダムな数値を少数で返す関数です。
Math.floorが小数点以下を切り捨てて整数にする関数です。
それを組み合わせるとrndのような関数ができるわけです。
(Q)
キーボードが押されたかどうかは判定できますか?
(A)
キーボードが押されたら関数が呼ばれるようにすることができます。
本編では解説していないので以下に書きますね。
function keyCallBack(e) {
var keycode;
if ( e && e.keyCode ) {
keycode = e.keyCode;
} else if ( event && event.keyCode ) {
keycode = event.keyCode;
}
alert(keycode);
}
document.onkeydown = keyCallBack;
|
これを見て何か気付きましたか?
そうです。タイマーコールバックと同様の仕組みなのです。
すぐに気付いた人はよく理解していると言えるでしょう。
タイマーは「指定秒後に関数コールバック」、
キーボードは「キーボードが押されたら関数コールバック」です。
コールバックは他にもあります。
リンク集の【JavaScriptリファレンス】などに書いてありますので
調べて色々と試してみてください。
またキーボードの各キーには数値が割り当てられています。
上の例ではその数値がわかるようになっていますので、
まずはこれで色々と試してみてください。
その数値の取得方法がネットスケープとインターネットエクスプローラーで違うので、
上のように2通りの取得方法を並べています。
例えば A 押された場合に何かをする場合は、
上の処理を組み込んで A を押してみるとそれが 65 であるとわかるので、
のように処理を書いていけばよいでしょう。
(Q)
入力文字を取得することはできますか?
(A)
できます。
formタグとinputタグで入力欄を指定して
document.<form名>.<input名>.value
で参照することができるのですが、
本編では解説していないので例を書きます。
以下の例はJavaScriptのソースでは無くhtmlのソースなのでご注意ください。
(Q)
時間を取得することはできますか?
(A)
時間のオブジェクト(Date)を new すると、
その瞬間の時間オブジェクトを得ることができます。
本編では解説していないので以下に例を書きますね。
var d;
d = new Date();
alert(d.getDate());
alert(d.getHours());
alert(d.getTime());
|
Dateオブジェクトに対して使える関数(*)は
リンク集の【JavaScriptリファレンス】などから調べることができますので、
これをベースに色々と試してみてください。
(*)本編ではわかりやすさを優先してすべて「関数」で統一していましたが、
【JavaScriptリファレンス】では下位オブジェクトと書いてありますね。
他にもメソッドという言い方もあります。
本来は見方によって言い方も変わるのでこうなっていますが、
それだけですのであまり気にしないで下さい。
(Q)
「6-a.マウスの位置を取得してみましょう」のサンプルを入れる場所がわかりません
(A)
下記の2行
document.onmousemove=evMouseMove; //マウスを動かすとevMouseMove()を起動
if ( NN6 ) document.captureEvents(Event.MOUSEMOVE);
これらはゲームの開始時か開始前に1度呼ばれれば良いのでそういう位置に入れてください。
よくわからなければ色々な位置に入れて試してみてもらえればよいと思います。
(Q)
「4-d. 絵を動かしてみましょう」のreturn(0)は何のためでしょうか?
(A)
lyrGetLeft等の中身の話ですね。
例えば古いバージョンのWebブラウザーや、
ネットスケープでもインターネットエクスプローラーでも無い場合、
NN6 も IE5 も false になるので、両方の if文 の中は処理されずに下に来てしまいます。
そうすると、return(0) が無い場合、何が返るでしょうか?
return命令が無いわけですから、何も返らないという変な状態になるかも知れません。
これはブラウザーによって返る値も保障されないので困りモノです。
数値を返すはずの関数が何も返さないと、
この関数を利用しているプログラムがどこかでエラーになるかも知れません。
数字じゃないものに数字を加えようとすると変になったりするのです。
エラー表示は怖いと思いますから、
ページで遊んでくれた人にできるだけエラーを見せたくないので、
私の工夫として 0 を返すようにしています。
そういう理由なのでこの値は数値 100 でも -1 でも何でも構いません。
0 は私の好みですね(^o^)
(Q)
別のゲームを作りたいのですがどうすればよいでしょうか。
(A)
まず最初に、
どのようなゲームでも作るには相当時間がかかりますので、
そのつもりで取り組んでください。
技術的には「動くゲームの作り方」を理解した貴方なら、
ほとんどのゲームは既に作ることができる状態にあります。
ただしここで解説している関数は少なめに押さえているので、
関数の知識はもっと必要かもしれません。
リンク集にある各解説サイトを見たり、
Blue Fountain Factory 等のゲームサイトで使われているソースを見たりして参考にすれば、
色々と幅が広がりますので試してみてください。
ソースはWebブラウザで
「表示」→「ページソース」などで見ることができます。
(ソースを借りる場合はそのサイトの著作権規定に注意してくださいネ)。
大事なことは、すぐに答えを求めたりせずに、
自分の力で調べ、自分で作り上げてみようと努力することだと、私は思います。
そういう努力をしている人の質問なら誠意をもって回答しますので、
わからなければ遠慮なく掲示板に書き込んでください。
ただし回答はヒントだけになるかも知れません。
それは「理解」をすれば後で本当に何でも組めるようになると信じているからです。
Coffee Breakでも書きましたが、
私は数ヶ月間理解できない状態が続き、
あるとき本当に何かが弾けたように理解したのです。
なので理解する日がきっと来ますので、
根気良く頑張って下さい。
ということで、以下に書かれている説明を見る事はお勧めしません。
あまりにも結論を急ぎすぎだからです。
でもそれでもどうしてもすぐ知りたい人のために、
また色々な角度から見ることも理解の助けになるという意図から、
以下に各ゲームの作り方の具体的なヒントを書きますね。
ただし繰り返しますが
以下のQ&Aのヒントを見ることはお勧めしません
(Q)
数当てゲームを作るにはどうすればよいでしょうか。
(A)
例えば4桁だとすると、
乱数で0~9999の値を取得するようにします。
上にあるrndを使えばrnd(10000)でできますね。
それを変数にしまっておきます。
一方html側では文字列を入力させてチェックボタンを押したら関数を呼び出すようにします。
その関数ではしまっておいた変数と入力された文字列を比較するようにして、
等しければゲームクリア、
そうじゃなければ小さいとか大きいとかヒントを出すようにします。
基本はこんな感じですが、
当たりまでの回数をカウントするとゲームっぽくなるでしょう。
あとはヒットアンドブローのように各桁毎に判定する場合、
Math.floorという小数点以下を切り捨てる関数を利用できるでしょう。
これ以上はどう楽しくするかですので考えてみてください。
(Q)
育成ゲームを作りたいのですがどうすればよいでしょうか。
(A)
育成ゲームにも色々ありますが、
例えば主人公は「体力」「知性」などのパラメータを持ち、
ユーザーの指示によって勉強や運動などを行い、
ある条件が揃うとイベントが発生する、
というのを想定してみます。
まずパラメータですが、それぞれのパラメータに変数を割り当てます。
10-b.得点を付けて完成!と
同様の手法を用いて、まずは初期化を行います。
変数名はそれぞれ別々に付けて下さい。同じ名前は使えませんので。
次に指示ですが、
3-e.アンカーから入力してみましょう
に書かれている手法を用いることで簡単にできます。
すなわち「勉強」という指示をアンカーにして、
それが押されたら呼ばれる関数を定義します。
その関数内では「知性」のパラメータがアップするように処理を書きます。
「運動」についても同様です。
関数名も同じ名前を別の用途では使えませんのでそれぞれ別々に命名してください。
そして演出ですが、
まず最初に絵をすべて読み込んでおきます。
ここではXとYの2枚あり、最初はXが表示されているとしましょう。
Yは非表示にしておきます。
これらは9.ブロックに書かれている手法が使えますね。
そして上記関数内でパラメータに加算後に共通の関数を呼び出すようにします。
その共通関数の中ではif文を用いて例えば
「体力が100以上で知性も100以上」
などの判定を行い、
判定が真であれば、絵をYに差し替えます。
Xを消してYを表示します。
これも9.ブロックを理解できていれば問題ないでしょう。
これを基本として、パラメータや条件パターン、
表示される絵などを増やしていくことで、
面白くもなり、つまらなくもなるでしょう。
ここまで読めば想像できるかと思いますが、
上に書いた通り面白くするまでにはかなり大変で時間がかかります。
しかし完成したときの喜びは非常に大きいものがあります。
途中でめげずに根気よくがんばってください(^_^)
(Q)
ストップウォッチを作るにはどうすればよいでしょうか
(A)
時間オブジェクトDateとgetTimeを使用する事で実現できそうです。
まず最初のボタンが押されたら
dateA = new Date();
次のボタンが押されたら
dateB = new Date();
がそれぞれ実行されるようにしておいて、
dateB.getTime() - dateA.getTime();
を求めれば、ストップウォッチとしての機能をするはずです。
あとはゲームにどう組み込むかは貴方の工夫次第ですね。