[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
今日は、玉をキーボードで動かしてみようと思います。
キー情報は、getkey命令で取得します。getkey命令は、ある指定したキーが、押されている状態か押されていない状態かを取得する命令で、
getkey 変数, キーコード
と言う風に使います。
キーコードとは、キーボードのキー一つ一つに割り振られた番号のことで、次のようになっています。
キーコード : 実際のキー
------------------------------------------
1 : マウスの左ボタン
2 : マウスの右ボタン
3 : キャンセル([CTRL]+[BREAK])
4 : 3ボタンマウスのまん中のボタン
8 : [BACKSPACE](PC98の[BS])
9 : [TAB]
13 : [ENTER]
16 : [SHIFT]
17 : [CTRL]
18 : [ALT](PC98の[GRPH])
20 : [CAPSLOCK]
27 : [ESC]
32 : スペースキー
33 : [PAGEUP](PC98の[ROLLDOWN])
34 : [PAGEDOWN](PC98の[ROLLUP])
35 : [END](PC98の[HELP])
36 : [HOME](PC98の[HOMECLR])
37 : カーソルキー[←]
38 : カーソルキー[↑]
39 : カーソルキー[→]
40 : カーソルキー[↓]
48~57 : [0]~[9](メインキーボード)
65~90 : [A]~[Z]
96~105 : [0]~[9](テンキー)
112~121 : ファンクションキー [F1]~[F10]
(「HSP HELP Browser Ⅱ」 から引用)
この数値をgetkey命令に指定すると、押されている状態であれば変数に1が、押されていない状態であれば変数に0が代入されます。
実際に使えば分かると思います。ちょっと長いですが次のプログラムを実行してみてください。
// 初期位置
x = 100
y = 100
// 移動スピード
sp = 10
// 半径
r = 10
repeat
// キー情報取得
getkey hidari, 37
getkey ue, 38
getkey migi, 39
getkey sita, 40
// 移動
if (hidari == 1) {
x -= sp
}
if (ue == 1) {
y -= sp
}
if (migi == 1) {
x += sp
}
if (sita == 1) {
y += sp
}
// 描画始め ++++++++++++++++++
redraw 0
// 背景
color 0, 0, 0
boxf
// 玉
color 255, 255, 255
circle x - r, y - r, x + r, y + r
redraw 1
// 描画終わり ++++++++++++++++
wait 3
loop
カーソルキー(十字キー)を押すと、その方向に玉が動くと思います。
最初に
x -= sp
という書き方に触れておきますが、これは今まで使ってきた、
x = x - sp
と同じことです。つまり、xの値をspの値だけ減らす、と言う意味です。スマートに見えるので書き換えました。
今まではspの部分は定数を用いてきましたが、変数にすることで、「アイテム取得でスピードアップ!」と言うような処理が出来ます。今回はしていませんが、今後ゲームを作る際に、こういう書き方が必要になると思うので、こうしておきました。他に、spの代入する値を変更するだけで、spの部分の値を一括変更できるというメリットもあります。
キーの情報の取得はこの部分です。
getkey hidari, 37
getkey ue, 38
getkey migi, 39
getkey sita, 40
37,38,39,40と言うキーコードは、上の表で見ると、カーソルキーの左、上、右、下であることが分かると思います。
つまり、カーソルキーが押されているか押されていないかの情報が、それぞれ、hidari、ue、migi、sitaと言う変数に代入されることになります。
そして、その変数の値を利用しているところがここです。
if (hidari == 1) {
x -= sp
}
if (ue == 1) {
y -= sp
}
if (migi == 1) {
x += sp
}
if (sita == 1) {
y += sp
}
ここで、if (なんたら) { かんたら } という文が出てきました。この文をif文と言います。ifと言うのは英語で「もしも~ならば」という意味を持ちますが、プログラム上のif文もそうです。もし()内の条件が満たされていれば、{}内の処理をします。逆に()内の条件が満たされていなければ、{}内の処理を行いません。
ここで==は左辺と右辺が等しい場合、という条件を示します。つまり、それぞれ、hidari、ue、migi、sitaの値が1、つまりキーが押されている状態であれば{}内の処理を行うというものです。{}内の処理はそれぞれ、x座標、あるいはy座標を変化させる処理となっているので、カーソルキーを押すと、円が移動する、ということになります。
xを増やすか減らすかという符合の問題は、x座標の正方向が右、y座標の正方向が下、と言うことを考えれば分かると思います。
なんだかゲームっぽくなってきたと思いませんか?次はマウスでも触ってみるかもしれません。
あと、HSP HELP Browser Ⅱは、スクリプトエディタのメニューのヘルプ>HSP命令リファレンスを開く、から起動することが出来ますので、命令の詳細が知りたい時や、どんな命令や関数があるか知りたい時は開いてみてください。
これまでは、プログラムを実行する度、毎回同じ処理をしていました。
そんなプログラムにはそろそろ飽きてきたかもしれません。
ということで、とりあえず乱数を使ってみようと思います。
乱数とはランダムな数のことです。サイコロ振った目の数みたいなもんです。
ただ、パソコン内でサイコロを振っているわけではないので、
プログラムで使えるのは
計算から求められた擬似的な乱数です。
その前に、関数の説明をしておこうと思います。
(乱数と同じ”数”がついていますが全く関係ありません。)
特に難しい話ではないのですが、中学や高校の数学で、
y = f(x) とか y = g(x) とか、あるいはf(x)の中身を具体的に書いて、
y = 2x とかいう関数を見たことがあるかと思います。
プログラム上の関数もこんな感じです。
xの値を与えることで、f(x)の値が決まる、というものです。
このxのことを命令と同様にパラメータと言いますが、
このパラメータの数は1つとは限りません。
x, y, zの値を参考に、g(x, y, z)の値が決まる、というのもあるでしょう。
実際に使ってみましょう。
// 半径
r = 5
// 乱数の初期化
randomize
repeat
// ランダムに位置を決める
x = rnd(640)
y = rnd(480)
// 円の描画
circle x - r, y - r, x + r, y + r
wait 1
loop
実行したら、黒い点が次々に表示されます。
もう、大体のプログラムの流れは分かると思うので割愛します。
乱数を使う時は、使う前にrandomize命令を置いて下さい。乱数が初期化されます。
これをしないと、乱数が毎回同じ、つまり乱数でなくなってしまいます。
それをしたあとに、
x = rnd(640)
y = rnd(480)
のところで、乱数を作っています。
rnd関数が乱数を発生させる関数で、数値のパラメータを1つとります。
上のプログラムの場合、xに0から639までの数(640通り)の中のどれか、
yに0から479までの数(480通り)のどれかがランダムで代入されます。
前にも言った通り、ウィンドウのサイズはデフォルト(標準初期値)で640×480なので、
rnd関数によって決められた円の中心座標は、画面内のどこかの点です。
乱数の使い方は大体分かったでしょうか?
ゲームでも、
降り注ぐ岩の位置とか、
的の出てくる微妙なタイミングとか
煙球のランダムな色など
色々使えるとおもうので、覚えておきましょう。
次回はキーボードの情報を利用する予定です。
ここから、面白くなってくる可能性があります。
前のプログラムでチカチカしていた理由。
それは、背景を塗りつぶした瞬間が見えてしまっていた、ということです。
背景を塗りつぶした瞬間と、その後に円を描画した絵が交互に映ったため、チカチカ見えたのです。
次のようにプログラムを変えましょう。
// 変数初期化
x = 100
y = 100
r = 10
repeat
// 描画モード→0
redraw 0
// 背景塗りつぶし
color 0, 0, 0 // 黒
boxf
// 円の描画
color 255, 255, 255 // 白
circle x - r, y - r, x + r, y + r
// 描画モード→1
redraw 1
// x座標を5増やす
x = x + 5
// 50ms待つ
wait 5
loop
redraw命令が新しく加わりました。redraw命令は描画モードを変更する命令です。
描画モード0は、描画命令が実行されても、実際の画面には反映されず、仮想画面上の描画にとどまる、と言う状態です。
一方描画モード1は、描画命令が実行されたその時に、実際の画面に反映されるというモードです。
また、描画モード1にした瞬間、それまで仮想画面にあったイメージが実際の画面に反映されます。
と言うことは、いろいろ描画する前に描画モードを0にしておいて、全ての描画が終わったところでモードを1にすれば、描画の過程は画面に反映されず、結果のみが見えるということになります。これで、ちらつきが解決されます。
これから、いろいろプログラムを書いていく上で、呪文のように毎回書くことになります。大切なことなので、是非覚えておきましょう。
今日は、アニメーションをしたいと思います。
これを、プレーヤーが動かせるようになればゲーム?ですからゲームプログラマーまでもう少しです。
今までは、動かない図形や文字を描いてきました。
今日は動く図形を描くわけですが、ちょっとした工夫で簡単に出来ます。
パラパラマンガを作ったことはあるでしょうか?原理はあれと全く同じです。
1コマ1コマ少しずつ変化するコマを連続的に速く切り替えることにより、人間の目にはそれが動いているように見える、というものです。
まず、このプログラムを見てください。
x = 100
y = 100
r = 10
circle x - r, y - r, x + r, y + r
今まで言ってきませんでしたが、パラメータを指定する時に、数式で書くことも可能です。
つまり、この「circle」のパラメータは数値に直すと「90,90,110,110」ですね。
と言うことは上のプログラムで、(x, y)つまり(100, 100)を中心に、半径r=10の円が描かれることは理解できるでしょうか?パッとみて分からない人も、今までのところを振り返りながらちょっと考えれば分かるはずです。
あと補足ですが、今回のプログラムにはあちこちにスペースが入っています。これは見易さのためで、命令とパラメータの間のスペース(今回の場合、「circle」の直後のみ)以外は必要ではありません。好みで入れても入れなくてもいいです。
で、上のプログラムで(x,y)中心の円が描けると言うことは、このxとyという変数をちょっとずつ変化させながら、描画すれば、アニメーションになると言うことです。ということで、次のプログラムにしてみましょう。
// 変数初期化
x = 100
y = 100
r = 10
repeat
// 背景塗りつぶし
color 0, 0, 0 // 黒
boxf
// 円の描画
color 255, 255, 255 // 白
circle x - r, y - r, x + r, y + r
// x座標を5増やす
x = x + 5
// 50ms待つ
wait 5
loop
ちょっとプログラムが長くなってきたので、コメントを入れてみました。(←用語)
コメントとは、プログラムの節々に入れるメモみたいなものです。
//や;の後なら、好きなことが書けるので、自分で分かりやすいようなコメントを是非入れておきましょう。
この癖はつけておいたほうがいいです。
コメントを見れば、どの行がどんな役割があるか分かると思います。
ちょっと付け足すと、
・repeat命令にパラメータで繰り返し数を指定していないのは、無限に繰り返すことを意味します。
こんなループのことを無限ループと言ったりします。
・boxf命令にパラメータが1つもないのは、画面全体の塗りつぶしを意味します。
プログラム全体の流れとしては、
まず、無限ループに入る前に、変数を初期化しておきます。
そして、ループに入り、次のことを繰り返します。
①背景を塗りつぶす
これがないと、前のターンで書いたものが残ったままなので必要です。試しに消してやってみるとよく分かります。
②円を描く
その時の変数の値で(x,y)を中心に半径rの円を描きます。実質変化する変数はxのみですが・・・
③x座標を増やす
ちょっと円の中心位置をずらします。これで、動いているように見えます。
④50ms待つ
wait命令が、待ち時間を作る命令です。パラメータ×10ms待ちます。
これがないと、フリーズに近い状況になってしまうので注意しましょう。絶対必要です。
とにかく、描く→待つ→描く→待つ→・・・と繰り返すのが基本です。
ゲームでも、おおよそこんな流れなので覚えておきましょう。
この例では、xを変化させましたが、yとかrとかを変化させても面白いかもしれません。
気付いた人はいるかもしれませんが、
上のプログラムを実行すると、チカチカします。
この対策は次回します。
前回の最終的なプログラムは
x=3
mes x
x=x+3
mes x
x=x+3
mes x
x=x+3
mes x
x=x+3
mes x
x=x+3
mes x
x=x+3
mes x
x=x+3
mes x
x=x+3
mes x
でした。最初の2行以外は、同じ事の繰り返しです。
これを今回はrepeat命令とloop命令を使って簡単にします。
repeat命令とloop命令は繰り返し文を作るための命令です。
繰り返し文のことはループとも呼びます。ループの方が言いやすいので、今後は多用すると思います。
それで、使い方ですが、
repeatとloopは互いを対にして、1組で1つのループを作ります。下のようにして使います。
repeat 10
mes "なんたら"
mes "かんたら"
loop
このようにrepeatを先、loopを後に書く事によって、その間のプログラムを繰り返します。
繰り返し回数は、repeatの後にパラメータとして与えます。
今は、必ず繰り返し回数を書いてください。
繰り返し回数を書かないと、無限に繰り返すことになり、ウィンドウが固まります。
万一そうなってしまった場合は、Ctrl+Alt+Deleteでタスクマネージャーを開いて、「応答なし」のタスクを終了してください。
で、実際に上のプログラムを実行すると、「なんたら」「かんたら」「なんたら」「かんたら」・・・・と言う風に、「なんたら」「かんたら」が10回繰り返し表示されると思います。
これを利用して、3の倍数のプログラムを書き直すと、下のようになります。
x=3
mes x
repeat 8
x=x+3
mes x
loop
だいぶ簡単になりました。
簡単に動作を説明すると、1行目「x=3」でまずxの値を3に初期化します。前回は言ってませんでしたが、一番最初の代入は、その後の代入と違って、今から変数としてxを使いますよ、という宣言も含んでいます。
2行目「mes x」で、ここでのxの値、つまり3を表示します。
この次3行目で、ループに入ります。
4行目でxの値を3増やし、5行目で表示します。
そして6行目でloop命令にたどり着くと、また3行目のrepeat命令まで戻って、4行目、5行目を繰り返します。
分かったでしょうか?
今まで、1行目→2行目→3行目→4行目→5行目→・・・・・→最終行、
と言う風に上から下まで順番に実行していました。
が、今回のプログラムでは2行目を実行した後、
4行目→5行目→4行目→5行目→・・・・・・→5行目、
と言う風な繰り返しがあります。と言うことです。
もう少しプログラムを代えて、こうできるのは分かるでしょうか?
x = 0
repeat 9
x = x + 3
mes x
loop
ちょっと考えれば、これも3の倍数を表示してくれるプログラムであることが分かると思います。
このプログラムでは、xを0から始め、後は「3増やして表示」をいうのを繰り返しています。
確かに、3、6、9、・・・と繰り返しますね。
このプログラムであれば、3の倍数がいっぱい欲しければ、2行目の「9」をもっと大きな数にすればいいだけですし、4の倍数が欲しければ、3行目の「3」を「4」に書き換えるだけです。
2回にわたって、3の倍数を表示するなんて何も面白くない話でしたが、
その間に出てきた変数や、ループは非常に重要です。これからボコボコ出てきます。
ちょっと辛抱してここの辺りを理解すれば、後にゲーム作りが更に楽しくなると思います。
最後に、前回書き忘れていたことを書きます。
まず、
前回何気なく出てきた「x=x+3」の「+」。他の記号も書いておきましょう。
「-」・・・ 引き算。(例)3引く2⇒3-2
「*」・・・ 掛け算。(例)5掛け2⇒5*2
「/」・・・ 割り算。(例)8割る2⇒8/2
「%」・・・ 割り算のあまり。(例)5割る3の余り(2)⇒5%2
これらの記号のことを演算子と言います。
で、次に、変数の名前の付け方ですが、
これまでは「x」しか使ってきませんでした。
しかし、「y」や「a」とかいう記号も使えるのは当たり前で、
「okane」とか「teki」とかゆう風にアルファベットをいくつか並べたものでもOKです。
ただし、命令や他のワードとかぶらないように注意しましょう。
次は、何かが動くかも。